Skip to content

Commit 3dfa68a

Browse files
authored
Merge pull request #11456 from ethereum/ice-abstract-contract-mapping-constructor
Fix ICE related to mapping types in abstract contract constructor
2 parents c09dc61 + 138873d commit 3dfa68a

7 files changed

Lines changed: 78 additions & 1 deletion

File tree

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Bugfixes:
1818
* AST: Do not output value of Yul literal if it is not a valid UTF-8 string.
1919
* SMTChecker: Fix internal error on struct constructor with fixed bytes member initialized with string literal.
2020
* Standard JSON: Properly allow the ``inliner`` setting under ``settings.optimizer.details``.
21+
* Type Checker: Fix internal compiler error related to having mapping types in constructor parameter for abstract contracts.
2122

2223

2324
AST Changes:

libsolidity/analysis/TypeChecker.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,12 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
588588
if (result)
589589
{
590590
bool isLibraryStorageParameter = (_variable.isLibraryFunctionParameter() && referenceType->location() == DataLocation::Storage);
591-
bool callDataCheckRequired = ((_variable.isConstructorParameter() || _variable.isPublicCallableParameter()) && !isLibraryStorageParameter);
591+
// We skip the calldata check for abstract contract constructors.
592+
bool isAbstractConstructorParam = _variable.isConstructorParameter() && m_currentContract && m_currentContract->abstract();
593+
bool callDataCheckRequired =
594+
!isAbstractConstructorParam &&
595+
(_variable.isConstructorParameter() || _variable.isPublicCallableParameter()) &&
596+
!isLibraryStorageParameter;
592597
if (callDataCheckRequired)
593598
{
594599
if (!referenceType->interfaceType(false))
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
abstract contract A {
2+
constructor (mapping (uint => uint) [] storage m) {
3+
m.push();
4+
m[0][1] = 2;
5+
}
6+
}
7+
8+
contract C is A {
9+
mapping(uint => mapping (uint => uint) []) public m;
10+
11+
constructor() A(m[1]) {
12+
}
13+
}
14+
// ====
15+
// compileViaYul: also
16+
// ----
17+
// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE
18+
// m(uint256,uint256,uint256): 1, 0, 1 -> 2
19+
// m(uint256,uint256,uint256): 1, 0, 5 -> 0
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
abstract contract A {
2+
constructor (mapping (uint => uint) storage m) {
3+
m[5] = 20;
4+
}
5+
}
6+
7+
contract C is A {
8+
mapping (uint => uint) public m;
9+
10+
constructor() A(m) {
11+
}
12+
}
13+
// ====
14+
// compileViaYul: also
15+
// ----
16+
// m(uint256): 1 -> 0
17+
// m(uint256): 5 -> 20
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
struct S {
2+
mapping (uint => uint) m;
3+
}
4+
5+
abstract contract A {
6+
constructor (S storage s) {
7+
s.m[5] = 16;
8+
}
9+
}
10+
11+
contract C is A {
12+
mapping(uint => S) m;
13+
14+
constructor() A(m[1]) {
15+
}
16+
17+
function getM(uint a, uint b) external returns (uint) {
18+
return m[a].m[b];
19+
}
20+
}
21+
// ====
22+
// compileViaYul: also
23+
// ----
24+
// getM(uint256,uint256): 0, 0 -> 0
25+
// getM(uint256,uint256): 1, 5 -> 0x10
26+
// getM(uint256,uint256): 1, 0 -> 0
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
abstract contract A {
2+
constructor (mapping (uint => uint) [] storage) { }
3+
}
4+
// ----
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
contract A {
2+
constructor (mapping (uint => uint) [] storage) { }
3+
}
4+
// ----
5+
// TypeError 3644: (30-63): This parameter has a type that can only be used internally. You can make the contract abstract to avoid this problem.

0 commit comments

Comments
 (0)