mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11456 from ethereum/ice-abstract-contract-mapping-constructor
Fix ICE related to mapping types in abstract contract constructor
This commit is contained in:
commit
3dfa68a574
@ -18,6 +18,7 @@ Bugfixes:
|
||||
* AST: Do not output value of Yul literal if it is not a valid UTF-8 string.
|
||||
* SMTChecker: Fix internal error on struct constructor with fixed bytes member initialized with string literal.
|
||||
* Standard JSON: Properly allow the ``inliner`` setting under ``settings.optimizer.details``.
|
||||
* Type Checker: Fix internal compiler error related to having mapping types in constructor parameter for abstract contracts.
|
||||
|
||||
|
||||
AST Changes:
|
||||
|
@ -588,7 +588,12 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
|
||||
if (result)
|
||||
{
|
||||
bool isLibraryStorageParameter = (_variable.isLibraryFunctionParameter() && referenceType->location() == DataLocation::Storage);
|
||||
bool callDataCheckRequired = ((_variable.isConstructorParameter() || _variable.isPublicCallableParameter()) && !isLibraryStorageParameter);
|
||||
// We skip the calldata check for abstract contract constructors.
|
||||
bool isAbstractConstructorParam = _variable.isConstructorParameter() && m_currentContract && m_currentContract->abstract();
|
||||
bool callDataCheckRequired =
|
||||
!isAbstractConstructorParam &&
|
||||
(_variable.isConstructorParameter() || _variable.isPublicCallableParameter()) &&
|
||||
!isLibraryStorageParameter;
|
||||
if (callDataCheckRequired)
|
||||
{
|
||||
if (!referenceType->interfaceType(false))
|
||||
|
@ -0,0 +1,19 @@
|
||||
abstract contract A {
|
||||
constructor (mapping (uint => uint) [] storage m) {
|
||||
m.push();
|
||||
m[0][1] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
contract C is A {
|
||||
mapping(uint => mapping (uint => uint) []) public m;
|
||||
|
||||
constructor() A(m[1]) {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE
|
||||
// m(uint256,uint256,uint256): 1, 0, 1 -> 2
|
||||
// m(uint256,uint256,uint256): 1, 0, 5 -> 0
|
@ -0,0 +1,17 @@
|
||||
abstract contract A {
|
||||
constructor (mapping (uint => uint) storage m) {
|
||||
m[5] = 20;
|
||||
}
|
||||
}
|
||||
|
||||
contract C is A {
|
||||
mapping (uint => uint) public m;
|
||||
|
||||
constructor() A(m) {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// m(uint256): 1 -> 0
|
||||
// m(uint256): 5 -> 20
|
@ -0,0 +1,26 @@
|
||||
struct S {
|
||||
mapping (uint => uint) m;
|
||||
}
|
||||
|
||||
abstract contract A {
|
||||
constructor (S storage s) {
|
||||
s.m[5] = 16;
|
||||
}
|
||||
}
|
||||
|
||||
contract C is A {
|
||||
mapping(uint => S) m;
|
||||
|
||||
constructor() A(m[1]) {
|
||||
}
|
||||
|
||||
function getM(uint a, uint b) external returns (uint) {
|
||||
return m[a].m[b];
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// getM(uint256,uint256): 0, 0 -> 0
|
||||
// getM(uint256,uint256): 1, 5 -> 0x10
|
||||
// getM(uint256,uint256): 1, 0 -> 0
|
@ -0,0 +1,4 @@
|
||||
abstract contract A {
|
||||
constructor (mapping (uint => uint) [] storage) { }
|
||||
}
|
||||
// ----
|
@ -0,0 +1,5 @@
|
||||
contract A {
|
||||
constructor (mapping (uint => uint) [] storage) { }
|
||||
}
|
||||
// ----
|
||||
// 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.
|
Loading…
Reference in New Issue
Block a user