Merge pull request #9849 from ethereum/fixIce9817

Fixing ICE on returning struct with mapping from library
This commit is contained in:
chriseth 2020-10-14 00:05:19 +02:00 committed by GitHub
commit 8d241fece9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 5 deletions

View File

@ -11,6 +11,7 @@ Compiler Features:
Bugfixes:
* Code generator: Fix internal error on returning structs containing mappings from library function.
* Code generator: Fix internal compiler error when referencing members via module name but not using the reference.
* Code generator: Fix ``ABIEncoderV2`` pragma from the current module affecting inherited functions and applied modifiers.
* Type Checker: Fix internal compiler error caused by storage parameters with nested mappings in libraries.

View File

@ -3001,8 +3001,11 @@ TypePointers FunctionType::returnParameterTypesWithoutDynamicTypes() const
m_kind == Kind::BareStaticCall
)
for (auto& param: returnParameterTypes)
if (param->isDynamicallyEncoded() && !param->dataStoredIn(DataLocation::Storage))
{
solAssert(param->decodingType(), "");
if (param->decodingType()->isDynamicallyEncoded())
param = TypeProvider::inaccessibleDynamic();
}
return returnParameterTypes;
}

View File

@ -41,16 +41,17 @@ ReturnInfo::ReturnInfo(EVMVersion const& _evmVersion, FunctionType const& _funct
returnTypes = _functionType.returnParameterTypesWithoutDynamicTypes();
for (auto const& retType: returnTypes)
if (retType->isDynamicallyEncoded())
{
solAssert(retType->decodingType(), "");
if (retType->decodingType()->isDynamicallyEncoded())
{
solAssert(haveReturndatacopy, "");
dynamicReturnSize = true;
estimatedReturnSize = 0;
break;
}
else if (retType->decodingType())
estimatedReturnSize += retType->decodingType()->calldataEncodedSize();
else
estimatedReturnSize += retType->calldataEncodedSize();
estimatedReturnSize += retType->decodingType()->calldataEncodedSize();
}
}
}

View File

@ -0,0 +1,21 @@
pragma experimental ABIEncoderV2;
library Lib {
struct Items {
mapping (uint => uint) a;
}
function get() public returns (Items storage x) {
assembly { x.slot := 123 }
}
}
contract C {
function f() public returns(uint256 slot) {
Lib.Items storage ptr = Lib.get();
assembly { slot := ptr.slot }
}
}
// ----
// library: Lib
// f() -> 123