Merge pull request #10759 from ethereum/nestedBytesArraySol2Yul

[Sol->Yul] Fixing nested bytes array push.
This commit is contained in:
chriseth 2021-01-14 11:33:06 +01:00 committed by GitHub
commit 8905af28c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 3 deletions

View File

@ -2576,7 +2576,30 @@ string YulUtilFunctions::updateStorageValueFunction(
auto const* toReferenceType = dynamic_cast<ReferenceType const*>(&_toType);
auto const* fromReferenceType = dynamic_cast<ReferenceType const*>(&_fromType);
solAssert(fromReferenceType && toReferenceType, "");
solAssert(toReferenceType, "");
if (!fromReferenceType)
{
solAssert(_fromType.category() == Type::Category::StringLiteral, "");
solAssert(toReferenceType->category() == Type::Category::Array, "");
auto const& toArrayType = dynamic_cast<ArrayType const&>(*toReferenceType);
solAssert(toArrayType.isByteArray(), "");
return Whiskers(R"(
function <functionName>(slot<?dynamicOffset>, offset</dynamicOffset>) {
<?dynamicOffset>if offset { <panic>() }</dynamicOffset>
let value := <copyLiteralToMemory>()
<copyToStorage>(slot, value)
}
)")
("functionName", functionName)
("dynamicOffset", !_offset.has_value())
("panic", panicFunction(PanicCode::Generic))
("copyLiteralToMemory", copyLiteralToMemoryFunction(dynamic_cast<StringLiteralType const&>(_fromType).value()))
("copyToStorage", copyArrayToStorageFunction(*TypeProvider::bytesMemory(), toArrayType))
.render();
}
solAssert(*toReferenceType->copyForLocation(
fromReferenceType->location(),
fromReferenceType->isPointer()

View File

@ -1325,8 +1325,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
m_utils.storageArrayPushFunction(arrayType, &argument.type()) <<
"(" <<
IRVariable(_functionCall.expression()).commaSeparatedList() <<
", " <<
argument.commaSeparatedList() <<
(argument.stackSlots().empty() ? "" : (", " + argument.commaSeparatedList())) <<
")\n";
}
break;

View File

@ -9,5 +9,7 @@ contract C {
return m;
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000

View File

@ -0,0 +1,15 @@
pragma abicoder v2;
contract C {
bytes[] a;
function f() public {
a.push("abc");
a.push("def");
assert(a[0][0] == "a");
assert(a[1][0] == "d");
}
}
// ====
// compileViaYul: also
// ----
// f() ->