mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Fix ICE related to mapping types in abstract contract constructor
This commit is contained in:
		
							parent
							
								
									2f0df8f054
								
							
						
					
					
						commit
						138873d918
					
				| @ -16,6 +16,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