aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsolidity/codegen/ABIFunctions.cpp7
-rw-r--r--test/libsolidity/ABIEncoderTests.cpp59
2 files changed, 61 insertions, 5 deletions
diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp
index 22b620e1..202a747f 100644
--- a/libsolidity/codegen/ABIFunctions.cpp
+++ b/libsolidity/codegen/ABIFunctions.cpp
@@ -538,7 +538,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
mstore(pos, sub(tail, headStart))
tail := <encodeToMemoryFun>(<arrayElementAccess>, tail)
srcPtr := <nextArrayElement>(srcPtr)
- pos := add(pos, <elementEncodedSize>)
+ pos := add(pos, 0x20)
}
pos := tail
<assignEnd>
@@ -832,7 +832,7 @@ string ABIFunctions::abiEncodingFunctionStruct(
}
memberTempl("encodingOffset", toCompactHexWithPrefix(encodingOffset));
encodingOffset += dynamicMember ? 0x20 : memberTypeTo->calldataEncodedSize();
- memberTempl("abiEncode", abiEncodingFunction(*memberTypeFrom, *memberTypeTo, _encodeAsLibraryTypes, false));
+ memberTempl("abiEncode", abiEncodingFunction(*memberTypeFrom, *memberTypeTo, _encodeAsLibraryTypes, true));
members.push_back({});
members.back()["encode"] = memberTempl.render();
@@ -1190,10 +1190,7 @@ size_t ABIFunctions::headSize(TypePointers const& _targetTypes)
if (t->isDynamicallyEncoded())
headSize += 0x20;
else
- {
- solAssert(t->calldataEncodedSize() > 0, "");
headSize += t->calldataEncodedSize();
- }
}
return headSize;
diff --git a/test/libsolidity/ABIEncoderTests.cpp b/test/libsolidity/ABIEncoderTests.cpp
index 05158601..9836eb77 100644
--- a/test/libsolidity/ABIEncoderTests.cpp
+++ b/test/libsolidity/ABIEncoderTests.cpp
@@ -462,6 +462,65 @@ BOOST_AUTO_TEST_CASE(structs)
)
}
+BOOST_AUTO_TEST_CASE(structs2)
+{
+ string sourceCode = R"(
+ contract C {
+ enum E {A, B, C}
+ struct T { uint x; E e; uint8 y; }
+ struct S { C c; T[] t;}
+ function f() public returns (uint a, S[2] s1, S[] s2, uint b) {
+ a = 7;
+ b = 8;
+ s1[0].c = this;
+ s1[0].t = new T[](1);
+ s1[0].t[0].x = 0x11;
+ s1[0].t[0].e = E.B;
+ s1[0].t[0].y = 0x12;
+ s2 = new S[](2);
+ s2[1].c = C(0x1234);
+ s2[1].t = new T[](3);
+ s2[1].t[1].x = 0x21;
+ s2[1].t[1].e = E.C;
+ s2[1].t[1].y = 0x22;
+ }
+ }
+ )";
+
+ NEW_ENCODER(
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(
+ 7, 0x80, 0x1e0, 8,
+ // S[2] s1
+ 0x40,
+ 0x100,
+ // S s1[0]
+ u256(u160(m_contractAddress)),
+ 0x40,
+ // T s1[0].t
+ 1, // length
+ // s1[0].t[0]
+ 0x11, 1, 0x12,
+ // S s1[1]
+ 0, 0x40,
+ // T s1[1].t
+ 0,
+ // S[] s2 (0x1e0)
+ 2, // length
+ 0x40, 0xa0,
+ // S s2[0]
+ 0, 0x40, 0,
+ // S s2[1]
+ 0x1234, 0x40,
+ // s2[1].t
+ 3, // length
+ 0, 0, 0,
+ 0x21, 2, 0x22,
+ 0, 0, 0
+ ));
+ )
+}
+
BOOST_AUTO_TEST_SUITE_END()
}