From 7b0fb5d06b735ec7b45120a67298caec70441379 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 5 Oct 2016 19:49:47 +0100 Subject: [PATCH 1/3] Support variable references within modifiers for inline assembly --- libsolidity/ast/AST.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 8fd1584df..7ed4ddce8 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -623,7 +623,7 @@ public: virtual bool isLValue() const override; virtual bool isPartOfExternalInterface() const override { return isPublic(); } - bool isLocalVariable() const { return !!dynamic_cast(scope()); } + bool isLocalVariable() const { return !!dynamic_cast(scope()); } /// @returns true if this variable is a parameter or return parameter of a function. bool isCallableParameter() const; /// @returns true if this variable is a parameter (not return parameter) of an external function. From d50204d8086ce34d11439394152d9fc5556b1cbf Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 20 Oct 2016 23:29:27 +0100 Subject: [PATCH 2/3] Add changelog entry --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 39e030146..a6503c32b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,7 @@ Bugfixes: * Inline assembly: fix parsing of assignment after a label. * Inline assembly: external variables of unsupported type (such as ``this``, ``super``, etc.) are properly detected as unusable. + * Inline assembly: support variables within modifiers. ### 0.4.2 (2016-09-17) From 13b2101ea7b55bc310682935bea4f4e5b07947c6 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 20 Oct 2016 23:36:05 +0100 Subject: [PATCH 3/3] Add tests for inline assembly in modifiers --- test/libsolidity/SolidityEndToEndTest.cpp | 22 ++++++++ .../SolidityNameAndTypeResolution.cpp | 51 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 088fe4d1e..0a028a45f 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7304,6 +7304,28 @@ BOOST_AUTO_TEST_CASE(shift_negative_constant_right) BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(-0x42))); } +BOOST_AUTO_TEST_CASE(inline_assembly_in_modifiers) +{ + char const* sourceCode = R"( + contract C { + modifier m { + uint a = 1; + assembly { + a := 2 + } + if (a != 2) + throw; + _; + } + function f() m returns (bool) { + return true; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(true)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 834723695..2c69f6637 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -4107,6 +4107,57 @@ BOOST_AUTO_TEST_CASE(inline_assembly_unbalanced_negative_stack) BOOST_CHECK(expectError(text, true) == Error::Type::Warning); } +BOOST_AUTO_TEST_CASE(inline_assembly_in_modifier) +{ + char const* text = R"( + contract test { + modifier m { + uint a = 1; + assembly { + a := 2 + } + _; + } + function f() m { + } + } + )"; + BOOST_CHECK(success(text)); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_storage) +{ + char const* text = R"( + contract test { + uint x = 1; + function f() { + assembly { + x := 2 + } + } + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::DeclarationError); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_storage_in_modifiers) +{ + char const* text = R"( + contract test { + uint x = 1; + modifier m { + assembly { + x := 2 + } + _; + } + function f() m { + } + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::DeclarationError); +} + BOOST_AUTO_TEST_SUITE_END() }