From 91367234d946266b73a5ace8071b0fd931f3a74b Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 20 Oct 2016 12:30:04 +0100 Subject: [PATCH 1/4] Support ErrorTag as a jump label in inline assembly --- Changelog.md | 1 + libsolidity/inlineasm/AsmCodeGen.cpp | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 4d68fc69f..d5f8cea9d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,7 @@ Features: * Do-while loops: support for a C-style do{}while(); control structure + * Inline assembly: support ``ErrorTag`` as a jump label. * Type checker: now more eagerly searches for a common type of an inline array with mixed types * Code generator: generates a runtime error when an out-of-range value is converted into an enum type. diff --git a/libsolidity/inlineasm/AsmCodeGen.cpp b/libsolidity/inlineasm/AsmCodeGen.cpp index 76c710486..1b789c5f0 100644 --- a/libsolidity/inlineasm/AsmCodeGen.cpp +++ b/libsolidity/inlineasm/AsmCodeGen.cpp @@ -81,7 +81,11 @@ struct GeneratorState class LabelOrganizer: public boost::static_visitor<> { public: - LabelOrganizer(GeneratorState& _state): m_state(_state) {} + LabelOrganizer(GeneratorState& _state): m_state(_state) + { + // Make the Solidity ErrorTag available to inline assembly + m_state.labels.insert(make_pair("ErrorTag", m_state.assembly.errorTag())); + } template void operator()(T const& /*_item*/) { } From bee926bf3f2d9f56103547d1add5463ab21c5f8e Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 20 Oct 2016 12:30:10 +0100 Subject: [PATCH 2/4] Add tests for the ErrorTag --- test/libsolidity/InlineAssembly.cpp | 5 +++++ test/libsolidity/SolidityEndToEndTest.cpp | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index a80a44a20..a26e9470f 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -177,6 +177,11 @@ BOOST_AUTO_TEST_CASE(imbalanced_stack) BOOST_CHECK(successAssemble("{ let x := 4 7 add }", false)); } +BOOST_AUTO_TEST_CASE(error_tag) +{ + BOOST_CHECK(successAssemble("{ ErrorTag }")); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 739a2efde..e50c2a85f 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7692,6 +7692,21 @@ BOOST_AUTO_TEST_CASE(packed_storage_overflow) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0x1234), u256(0), u256(0), u256(0xfffe))); } +BOOST_AUTO_TEST_CASE(inline_assembly_errortag) +{ + char const* sourceCode = R"( + contract C { + function f() { + assembly { + jump(ErrorTag) + } + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs()); +} + BOOST_AUTO_TEST_SUITE_END() } From 702ab4cb4f9344ce6d8fb1311db7c9fc94431386 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 9 Nov 2016 01:18:10 +0000 Subject: [PATCH 3/4] Document inline assembly ErrorTag --- docs/control-structures.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/control-structures.rst b/docs/control-structures.rst index bbb90e6a2..351e4c916 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -716,6 +716,10 @@ will have a wrong impression about the stack height at label ``two``: three: } +.. note:: + + ``ErrorTag`` is a pre-defined label. Jumping to this location will always + result in an invalid jump, effectively aborting execution of the code. Declaring Assembly-Local Variables ---------------------------------- From ae8403ed08cf3b2b5bec1d3f8da0c6c7425a4d5a Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 15 Nov 2016 10:12:03 +0000 Subject: [PATCH 4/4] Rename ErrorTag to invalidJumpLabel in inline assembly --- Changelog.md | 2 +- docs/control-structures.rst | 2 +- libsolidity/inlineasm/AsmCodeGen.cpp | 2 +- test/libsolidity/InlineAssembly.cpp | 2 +- test/libsolidity/SolidityEndToEndTest.cpp | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Changelog.md b/Changelog.md index d5f8cea9d..a392ec013 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,7 +2,7 @@ Features: * Do-while loops: support for a C-style do{}while(); control structure - * Inline assembly: support ``ErrorTag`` as a jump label. + * Inline assembly: support ``invalidJumpLabel`` as a jump label. * Type checker: now more eagerly searches for a common type of an inline array with mixed types * Code generator: generates a runtime error when an out-of-range value is converted into an enum type. diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 351e4c916..7e1c690d2 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -718,7 +718,7 @@ will have a wrong impression about the stack height at label ``two``: .. note:: - ``ErrorTag`` is a pre-defined label. Jumping to this location will always + ``invalidJumpLabel`` is a pre-defined label. Jumping to this location will always result in an invalid jump, effectively aborting execution of the code. Declaring Assembly-Local Variables diff --git a/libsolidity/inlineasm/AsmCodeGen.cpp b/libsolidity/inlineasm/AsmCodeGen.cpp index 1b789c5f0..771f10425 100644 --- a/libsolidity/inlineasm/AsmCodeGen.cpp +++ b/libsolidity/inlineasm/AsmCodeGen.cpp @@ -84,7 +84,7 @@ public: LabelOrganizer(GeneratorState& _state): m_state(_state) { // Make the Solidity ErrorTag available to inline assembly - m_state.labels.insert(make_pair("ErrorTag", m_state.assembly.errorTag())); + m_state.labels.insert(make_pair("invalidJumpLabel", m_state.assembly.errorTag())); } template diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index a26e9470f..185a62158 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(imbalanced_stack) BOOST_AUTO_TEST_CASE(error_tag) { - BOOST_CHECK(successAssemble("{ ErrorTag }")); + BOOST_CHECK(successAssemble("{ invalidJumpLabel }")); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index e50c2a85f..d89242500 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7692,13 +7692,13 @@ BOOST_AUTO_TEST_CASE(packed_storage_overflow) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0x1234), u256(0), u256(0), u256(0xfffe))); } -BOOST_AUTO_TEST_CASE(inline_assembly_errortag) +BOOST_AUTO_TEST_CASE(inline_assembly_invalidjumplabel) { char const* sourceCode = R"( contract C { function f() { assembly { - jump(ErrorTag) + jump(invalidJumpLabel) } } }