aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsolidity/ast/Types.cpp7
-rw-r--r--libsolidity/ast/Types.h1
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp19
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp45
4 files changed, 71 insertions, 1 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 8cc125fe..395faf55 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -1897,6 +1897,13 @@ bool FunctionType::operator==(Type const& _other) const
return true;
}
+TypePointer FunctionType::unaryOperatorResult(Token::Value _operator) const
+{
+ if (_operator == Token::Value::Delete)
+ return make_shared<TupleType>();
+ return TypePointer();
+}
+
string FunctionType::toString(bool _short) const
{
string name = "function (";
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 691ddf29..9831bc42 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -892,6 +892,7 @@ public:
TypePointer selfType() const;
virtual bool operator==(Type const& _other) const override;
+ virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
virtual std::string toString(bool _short) const override;
virtual unsigned calldataEncodedSize(bool _padded) const override;
virtual bool canBeStored() const override { return m_location == Location::Internal || m_location == Location::External; }
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index c665b050..a1236803 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -7960,7 +7960,7 @@ BOOST_AUTO_TEST_CASE(function_memory_array)
BOOST_CHECK(callContractFunction("test(uint256,uint256)", u256(10), u256(5)) == encodeArgs());
}
-BOOST_AUTO_TEST_CASE(function_delete)
+BOOST_AUTO_TEST_CASE(function_delete_storage)
{
char const* sourceCode = R"(
contract C {
@@ -7987,6 +7987,23 @@ BOOST_AUTO_TEST_CASE(function_delete)
BOOST_CHECK(callContractFunction("ca()") == encodeArgs());
}
+BOOST_AUTO_TEST_CASE(function_delete_stack)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function a() returns (uint) { return 7; }
+ function test() returns (uint) {
+ y = a;
+ delete y;
+ y();
+ }
+ }
+ )";
+
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("test()") == encodeArgs());
+}
+
BOOST_AUTO_TEST_CASE(copy_function_storage_array)
{
char const* sourceCode = R"(
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index e85d0fe6..62fb55f7 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -4256,6 +4256,51 @@ BOOST_AUTO_TEST_CASE(function_type_arrays)
BOOST_CHECK(success(text));
}
+BOOST_AUTO_TEST_CASE(delete_function_type)
+{
+ char const* text = R"(
+ contract C {
+ function(uint) external returns (uint) x;
+ function(uint) internal returns (uint) y;
+ function f() {
+ delete x;
+ var a = y;
+ delete a;
+ delete y;
+ var c = f;
+ delete c;
+ function(uint) internal returns (uint) g;
+ delete g;
+ }
+ }
+ )";
+ BOOST_CHECK(success(text));
+}
+
+BOOST_AUTO_TEST_CASE(delete_function_type_invalid)
+{
+ char const* text = R"(
+ contract C {
+ function f() {
+ delete f;
+ }
+ }
+ )";
+ BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(delete_external_function_type_invalid)
+{
+ char const* text = R"(
+ contract C {
+ function f() {
+ delete this.f;
+ }
+ }
+ )";
+ BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+}
+
BOOST_AUTO_TEST_CASE(invalid_fixed_point_literal)
{
char const* text = R"(