argotorg / argotorg/solidity

[BUG] Assertion failed /solidity/libsolidity/ast/Types.h(246)

Open
#15,731 0 comments 0 reactions 0 assignees View on GitHub
bug :bug:
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

Open the contributing guide

Research direction

Start by reproducing the failure with the provided poc.sol and `solc --bin -o poc poc.sol`. Then inspect the assertion location in /solidity/libsolidity/ast/Types.h(246) and the StructType::isDynamicallyEncoded() path reported at Types.cpp(2284). Done means the minimal input no longer triggers the internal compiler assertion and the relevant compiler tests pass.

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.