From 2c2c7a4473f8348766760febbba5cb401abfc990 Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Wed, 24 Feb 2021 11:48:55 +0100 Subject: [PATCH] Fix IR bug on deleting storage variables of function type. Calling the zeroing function assumed that the stack slots needed for the type was always 1. This is false for function types. --- libsolidity/codegen/YulUtilFunctions.cpp | 4 +- .../function_external_delete_storage.sol | 39 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 56800d8fe..8abc2385f 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -3888,11 +3888,13 @@ string YulUtilFunctions::storageSetToZeroFunction(Type const& _type) if (_type.isValueType()) return Whiskers(R"( function (slot, offset) { - (slot, offset, ()) + let := () + (slot, offset, ) } )") ("functionName", functionName) ("store", updateStorageValueFunction(_type, _type)) + ("values", suffixedVariableNameList("zero_", 0, _type.sizeOnStack())) ("zeroValue", zeroValueFunction(_type)) .render(); else if (_type.category() == Type::Category::Array) diff --git a/test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol b/test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol new file mode 100644 index 000000000..a7604872b --- /dev/null +++ b/test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol @@ -0,0 +1,39 @@ +contract C { + function() external public x; + uint public y = 0; + + function increment() public { + ++y; + } + + function set() external { + x = this.increment; + } + + function incrementIndirectly() public { + x(); + } + + function deleteFunction() public { + // used to lead to an ICE during IR + delete x; + } +} +// ==== +// compileViaYul: also +// ---- +// x() -> 0 +// y() -> 0 +// increment() -> +// y() -> 1 +// set() -> +// x() -> 0xfdd67305928fcac8d213d1e47bfa6165cd0b87bd09de08a0000000000000000 +// increment() -> +// y() -> 2 +// incrementIndirectly() -> +// y() -> 3 +// deleteFunction() -> +// increment() -> +// y() -> 4 +// incrementIndirectly() -> FAILURE +// y() -> 4