aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--docs/control-structures.rst4
-rw-r--r--libsolidity/inlineasm/AsmCodeGen.cpp6
-rw-r--r--test/libsolidity/InlineAssembly.cpp5
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp15
5 files changed, 30 insertions, 1 deletions
diff --git a/Changelog.md b/Changelog.md
index 4d68fc69..a392ec01 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,6 +2,7 @@
Features:
* Do-while loops: support for a C-style do{<block>}while(<expr>); control structure
+ * 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 bbb90e6a..7e1c690d 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::
+
+ ``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 76c71048..771f1042 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("invalidJumpLabel", m_state.assembly.errorTag()));
+ }
template <class T>
void operator()(T const& /*_item*/) { }
diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp
index a80a44a2..185a6215 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("{ invalidJumpLabel }"));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 739a2efd..d8924250 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_invalidjumplabel)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() {
+ assembly {
+ jump(invalidJumpLabel)
+ }
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs());
+}
+
BOOST_AUTO_TEST_SUITE_END()
}