diff --git a/Changelog.md b/Changelog.md index bb20bd813..597a6a70a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -13,6 +13,7 @@ Bugfixes: * Antlr Grammar: Allow builtin names in ``yulPath`` to support ``.address`` in function pointers. * Control Flow Graph: Perform proper virtual lookup for modifiers for uninitialized variable and unreachable code analysis. * Immutables: Fix wrong error when the constructor of a base contract uses ``return`` and the parent contract contains immutable variables. + * IR Generator: Fix IR syntax error when copying storage arrays of structs containing functions. * Natspec: Fix ICE when overriding a struct getter with a Natspec-documented return value and the name in the struct is different. * TypeChecker: Fix ICE when a constant variable declaration forward references a struct. diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 106ad260f..2327250b2 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -3608,7 +3608,7 @@ string YulUtilFunctions::copyStructToStorageFunction(StructType const& _from, St auto const& [srcSlotOffset, srcOffset] = _from.storageOffsetsOfMember(structMembers[i].name); t("memberOffset", formatNumber(srcSlotOffset)); if (memberType.isValueType()) - t("read", readFromStorageValueType(memberType, srcOffset, false)); + t("read", readFromStorageValueType(memberType, srcOffset, true)); else solAssert(srcOffset == 0, ""); diff --git a/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol b/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol new file mode 100644 index 000000000..70e3a34d4 --- /dev/null +++ b/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol @@ -0,0 +1,28 @@ +contract C { + struct Struct { + function () external el; + } + Struct[] array; + int externalCalled = 0; + + function ext() external { + externalCalled++; + } + + function f() public { + array.push(Struct(this.ext)); + array.push(array[0]); + + array[0].el(); + array[1].el(); + + assert(externalCalled == 2); + } +} +// ==== +// compileViaYul: also +// ---- +// f() -> +// gas irOptimized: 113142 +// gas legacy: 112937 +// gas legacyOptimized: 112608