diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 6b0fb9ec1..600ad2a5e 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -851,7 +851,6 @@ std::string YulUtilFunctions::resizeDynamicArrayFunction(ArrayType const& _type) solAssert(_type.isDynamicallySized(), ""); solUnimplementedAssert(!_type.isByteArray(), "Byte Arrays not yet implemented!"); solUnimplementedAssert(_type.baseType()->storageBytes() <= 32, "..."); - solUnimplementedAssert(_type.baseType()->storageSize() == 1, ""); string functionName = "resize_array_" + _type.identifier(); return m_functionCollector.createFunction(functionName, [&]() { @@ -2317,27 +2316,32 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) auto const& toStructType = dynamic_cast(_to); solAssert(fromStructType.structDefinition() == toStructType.structDefinition(), ""); - solUnimplementedAssert(!fromStructType.isDynamicallyEncoded(), ""); - solUnimplementedAssert(toStructType.location() == DataLocation::Memory, ""); - solUnimplementedAssert(fromStructType.location() != DataLocation::Memory, ""); - - if (fromStructType.location() == DataLocation::CallData) - { - body = Whiskers(R"( - converted := (value, calldatasize()) - )")("abiDecode", ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector).tupleDecoder( - {&toStructType} - )).render(); - } + if (fromStructType.location() == toStructType.location() && toStructType.isPointer()) + body = "converted := value"; else { - solAssert(fromStructType.location() == DataLocation::Storage, ""); + solUnimplementedAssert(toStructType.location() == DataLocation::Memory, ""); + solUnimplementedAssert(fromStructType.location() != DataLocation::Memory, ""); - body = Whiskers(R"( - converted := (value) - )") - ("readFromStorage", readFromStorage(toStructType, 0, true)) - .render(); + if (fromStructType.location() == DataLocation::CallData) + { + solUnimplementedAssert(!fromStructType.isDynamicallyEncoded(), ""); + body = Whiskers(R"( + converted := (value, calldatasize()) + )")("abiDecode", ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector).tupleDecoder( + {&toStructType} + )).render(); + } + else + { + solAssert(fromStructType.location() == DataLocation::Storage, ""); + + body = Whiskers(R"( + converted := (value) + )") + ("readFromStorage", readFromStorage(toStructType, 0, true)) + .render(); + } } break; @@ -2780,22 +2784,24 @@ string YulUtilFunctions::storageSetToZeroFunction(Type const& _type) else if (_type.category() == Type::Category::Array) return Whiskers(R"( function (slot, offset) { - if iszero(eq(offset, 0)) { panic() } + if iszero(eq(offset, 0)) { () } (slot) } )") ("functionName", functionName) ("clearArray", clearStorageArrayFunction(dynamic_cast(_type))) + ("panic", panicFunction()) .render(); else if (_type.category() == Type::Category::Struct) return Whiskers(R"( function (slot, offset) { - if iszero(eq(offset, 0)) { panic() } + if iszero(eq(offset, 0)) { () } (slot) } )") ("functionName", functionName) ("clearStruct", clearStorageStructFunction(dynamic_cast(_type))) + ("panic", panicFunction()) .render(); else solUnimplemented("setToZero for type " + _type.identifier() + " not yet implemented!"); diff --git a/test/libsolidity/semanticTests/array/delete_on_array_of_structs.sol b/test/libsolidity/semanticTests/array/delete_on_array_of_structs.sol index 316b8d9ef..b415ac7f6 100644 --- a/test/libsolidity/semanticTests/array/delete_on_array_of_structs.sol +++ b/test/libsolidity/semanticTests/array/delete_on_array_of_structs.sol @@ -16,5 +16,7 @@ contract C { } } +// ==== +// compileViaYul: also // ---- // f() -> true # This code interprets x as an array length and thus will go out of gas. neither of the two should throw due to out-of-bounds access # diff --git a/test/libsolidity/semanticTests/array/push_no_args_struct.sol b/test/libsolidity/semanticTests/array/push_no_args_struct.sol index 6f626d9c3..89df694c6 100644 --- a/test/libsolidity/semanticTests/array/push_no_args_struct.sol +++ b/test/libsolidity/semanticTests/array/push_no_args_struct.sol @@ -31,6 +31,8 @@ contract C { } } +// ==== +// compileViaYul: also // ---- // l() -> 0 // f(uint256): 42 -> diff --git a/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_storage_access_via_pointer.sol b/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_storage_access_via_pointer.sol index 183709835..c7f4cb240 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_storage_access_via_pointer.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_storage_access_via_pointer.sol @@ -18,6 +18,8 @@ contract C { } } +// ==== +// compileViaYul: also // ---- // f() -> true // a() -> 7 diff --git a/test/libsolidity/semanticTests/libraries/using_for_storage_structs.sol b/test/libsolidity/semanticTests/libraries/using_for_storage_structs.sol index cd45726b6..2749fb444 100644 --- a/test/libsolidity/semanticTests/libraries/using_for_storage_structs.sol +++ b/test/libsolidity/semanticTests/libraries/using_for_storage_structs.sol @@ -21,5 +21,7 @@ contract C { return (s.f(), h(s)); } } +// ==== +// compileViaYul: also // ---- // g() -> 7, 7 diff --git a/test/libsolidity/semanticTests/structs/recursive_struct_2.sol b/test/libsolidity/semanticTests/structs/recursive_struct_2.sol index 65cfcf209..5214b1a48 100644 --- a/test/libsolidity/semanticTests/structs/recursive_struct_2.sol +++ b/test/libsolidity/semanticTests/structs/recursive_struct_2.sol @@ -20,5 +20,7 @@ contract C { assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) } } } +// ==== +// compileViaYul: also // ---- // f() -> 0, 0, 0, 0 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_member.sol b/test/libsolidity/semanticTests/structs/struct_delete_member.sol index 2b3f41402..a4bfe948b 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_member.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_member.sol @@ -16,5 +16,7 @@ contract test { } } +// ==== +// compileViaYul: also // ---- // deleteMember() -> 0 diff --git a/test/libsolidity/semanticTests/structs/struct_reference.sol b/test/libsolidity/semanticTests/structs/struct_reference.sol index 79eeccbe7..c836d3f1d 100644 --- a/test/libsolidity/semanticTests/structs/struct_reference.sol +++ b/test/libsolidity/semanticTests/structs/struct_reference.sol @@ -18,6 +18,8 @@ contract test { inner.recursive[0].z = inner.recursive[1].z + 1; } } +// ==== +// compileViaYul: also // ---- // check() -> false // set() -> diff --git a/test/libsolidity/semanticTests/various/typed_multi_variable_declaration.sol b/test/libsolidity/semanticTests/various/typed_multi_variable_declaration.sol index 1ab8586fc..de3c813a3 100644 --- a/test/libsolidity/semanticTests/various/typed_multi_variable_declaration.sol +++ b/test/libsolidity/semanticTests/various/typed_multi_variable_declaration.sol @@ -22,5 +22,7 @@ contract C { } } +// ==== +// compileViaYul: also // ---- // f() -> true