diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 7d275e6f8..48daf3fa1 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -2576,7 +2576,30 @@ string YulUtilFunctions::updateStorageValueFunction( auto const* toReferenceType = dynamic_cast(&_toType); auto const* fromReferenceType = dynamic_cast(&_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(*toReferenceType); + solAssert(toArrayType.isByteArray(), ""); + + return Whiskers(R"( + function (slot, offset) { + if offset { () } + let value := () + (slot, value) + } + )") + ("functionName", functionName) + ("dynamicOffset", !_offset.has_value()) + ("panic", panicFunction(PanicCode::Generic)) + ("copyLiteralToMemory", copyLiteralToMemoryFunction(dynamic_cast(_fromType).value())) + ("copyToStorage", copyArrayToStorageFunction(*TypeProvider::bytesMemory(), toArrayType)) + .render(); + } + solAssert(*toReferenceType->copyForLocation( fromReferenceType->location(), fromReferenceType->isPointer() diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 300a6ed85..e0ec5e28a 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -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; diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol index c0dd812ad..7ce90c5f2 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol @@ -9,5 +9,7 @@ contract C { return m; } } +// ==== +// compileViaYul: also // ---- // f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000 diff --git a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol new file mode 100644 index 000000000..cee98fe63 --- /dev/null +++ b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol @@ -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() -> \ No newline at end of file