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. * 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: 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 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: Allow assignments to local variables of mapping types.
* Type Checker: Consider fixed size arrays when checking for recursive structs. * 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. * 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); encodingType = encodingType->interfaceType(_inLibraryCall);
if (encodingType) if (encodingType)
encodingType = encodingType->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,
// Structs are fine in the following circumstances: // - storage struct for a library
// - ABIv2 without packed encoding or, if (_inLibraryCall && encodingType->dataStoredIn(DataLocation::Storage))
// - storage struct for a library return encodingType;
if (!( TypePointer baseType = encodingType;
(_encoderV2 && !_packed) || while (auto const* arrayType = dynamic_cast<ArrayType const*>(baseType.get()))
(structType->location() == DataLocation::Storage && _inLibraryCall) baseType = arrayType->baseType();
)) if (dynamic_cast<StructType const*>(baseType.get()))
if (!_encoderV2 || _packed)
return TypePointer(); return TypePointer();
}
return encodingType; 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.