Merge pull request #4782 from ethereum/encodePackedArrayOfStructs

Encode packed array of structs
This commit is contained in:
chriseth 2018-08-14 16:32:57 +02:00 committed by GitHub
commit ec7ccbdf86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 10 deletions

View File

@ -98,6 +98,7 @@ Bugfixes:
* References Resolver: Report error instead of assertion fail when FunctionType has an undeclared type as parameter.
* Type Checker: Default data location for type conversions (e.g. from literals) is memory and not storage.
* Type Checker: Disallow assignments to mappings within tuple assignments as well.
* Type Checker: Disallow packed encoding of arrays of structs.
* Type Checker: Allow assignments to local variables of mapping types.
* Type Checker: Consider fixed size arrays when checking for recursive structs.
* Type Checker: Fix crashes in erroneous tuple assignments in which the type of the right hand side cannot be determined.

View File

@ -394,17 +394,17 @@ TypePointer Type::fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool _p
encodingType = encodingType->interfaceType(_inLibraryCall);
if (encodingType)
encodingType = encodingType->encodingType();
if (auto structType = dynamic_cast<StructType const*>(encodingType.get()))
{
// Structs are fine in the following circumstances:
// - ABIv2 without packed encoding or,
// - storage struct for a library
if (!(
(_encoderV2 && !_packed) ||
(structType->location() == DataLocation::Storage && _inLibraryCall)
))
// Structs are fine in the following circumstances:
// - ABIv2 without packed encoding or,
// - storage struct for a library
if (_inLibraryCall && encodingType->dataStoredIn(DataLocation::Storage))
return encodingType;
TypePointer baseType = encodingType;
while (auto const* arrayType = dynamic_cast<ArrayType const*>(baseType.get()))
baseType = arrayType->baseType();
if (dynamic_cast<StructType const*>(baseType.get()))
if (!_encoderV2 || _packed)
return TypePointer();
}
return encodingType;
}

View File

@ -0,0 +1,9 @@
contract C {
struct S { uint x; }
function f() public pure {
S[] memory s;
abi.encodePacked(s);
}
}
// ----
// TypeError: (116-117): This type cannot be encoded.

View File

@ -0,0 +1,10 @@
pragma experimental ABIEncoderV2;
contract C {
struct S { uint x; }
function f() public pure {
S[] memory s;
abi.encode(s);
}
}
// ----
// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.