[BUG] Assertion failed. solidity/libsolidity/ast/Types.cpp(2284)
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 21
Description
## Description
Error:
```
Internal compiler error:
/solidity/libsolidity/ast/Types.cpp(2284): Throw in function virtual bool solidity::frontend::StructType::isDynamicallyEncoded() const
Dynamic exception type: boost::wrapexcept
std::exception::what: Solidity assertion failed
[solidity::util::tag_comment*] = Solidity assertion failed
```
## Environment
- Compiler version: Version: 0.8.28-develop.2025.1.19+commit.7893614a.mod.Linux.g++
- Compilation pipeline (legacy, IR, EOF):
- Target EVM version (as per compiler settings):
- Framework/IDE (e.g. Foundry, Hardhat, Remix):
- EVM execution environment / backend / blockchain client:
- Operating system: Ubuntu 22.04
## Steps to Reproduce
poc.sol (fuzzer-generated):
```solidity
contract I {
function f() internal returns (uint256[] calldata) {}
}
contract J {
struct S {
uint128 p1;
uint256[][2] a;
uint32 p2;
}
struct S1 {
uint128 u;
S s;
}
struct S2 {
S[2] array;
}
function f(uint x) public pure {
for (x = 0; x < 10; ++x)
break;
assert(x == 0);
}
function f(uint8 a) public pure returns (function() external returns (uint)) {
bytes memory b = hex"00010203040506070809000102030405060708090001020304050607080900010203040506070809";
}
function f() internal returns (uint[5] memory) {
}
function exp_2(uint y) public returns (uint) {
}
}
contract IJ is I, J {
modifier f() virtual override (I, B) { _; }
}
contract A is IJ
{
function f(uint256 a, uint256 b) internal pure returns (fixed40x40) {
return a >> b;
}
function t() public pure {
assert(f(0x4266, 0) == 0x4266);
// Fails because the above is true.
assert(f(0x4266, 0) == 0x426);
assert(f(0x4266, 0x8) == 0x42);
// Fails because the above is true.
assert(f(0x4266, 0x8) == 0x420);
assert(f(0x4266, 0x11) == 0);
// Fails because the above is true.
assert(f(0x4266, 0x11) == 1);
assert(f(57896044618658097711785492504343953926634992332820282019728792003956564819968, 5) == 1809251394333065553493296640760748560207343510400633813116524750123642650624);
// Fails because the above is true.
assert(f(57896044618658097711785492504343953926634992332820282019728792003956564819968, 5) == 0);
}
}
contract B is IJ
{
}
contract C is A, B {
struct D {
uint32 a;
uint128 b;
uint256 c;
function() internal returns (uint32) f;
}
struct S { uint x; }
function f(bytes calldata) internal {
return f();
}
function g(S[2] calldata a) public returns (bytes memory) {
return abi.encode(a);
}
function h(D[][] calldata a) private returns (bytes memory) {}
function i(D[2][] calldata a) internal returns (uint x) {
return abi.encode(a);
}
function f() public pure {
uint x;
while (x < 3) {
if (x > 1) {
x = 3;
break;
}
if (x >= 0) {
x = 0;
continue;
}
}
assert(x == 3);
}
function k(bool) public returns (bytes memory) {
int a;
}
function f() public { }
}
```
To reproduce:
`solc --bin -o poc poc.sol`
Contributor guide
Research direction
Start at solidity/libsolidity/ast/Types.cpp:2284 and compile the supplied poc.sol with `solc --bin -o poc poc.sol` to reproduce the InternalCompilerError. Trace why StructType::isDynamicallyEncoded() asserts for this fuzzer-generated input; done means the reproducer no longer triggers the assertion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, solidity
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100