From efc8d79d5354af260671ea8439f5a680ca04739f Mon Sep 17 00:00:00 2001 From: Mathias Baumann Date: Mon, 15 Apr 2019 14:50:00 +0200 Subject: [PATCH] Fix wrong location for inline asm blocks --- libsolidity/parsing/Parser.cpp | 8 ++-- test/libsolidity/SolidityParser.cpp | 37 +++++++++++++++++++ .../smtCheckerTests/inline_assembly/empty.sol | 2 +- .../inline_assembly/local_var.sol | 2 +- .../uninitializedAccess/assembly.sol | 2 +- 5 files changed, 45 insertions(+), 6 deletions(-) diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index ba02c048c..d2e993cd7 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1036,7 +1036,8 @@ ASTPointer Parser::parseStatement() ASTPointer Parser::parseInlineAssembly(ASTPointer const& _docString) { RecursionGuard recursionGuard(*this); - ASTNodeFactory nodeFactory(*this); + SourceLocation location{position(), -1, source()}; + expectToken(Token::Assembly); if (m_scanner->currentToken() == Token::StringLiteral) { @@ -1050,8 +1051,9 @@ ASTPointer Parser::parseInlineAssembly(ASTPointer con shared_ptr block = asmParser.parse(m_scanner, true); if (block == nullptr) BOOST_THROW_EXCEPTION(FatalError()); - nodeFactory.markEndPosition(); - return nodeFactory.createNode(_docString, block); + + location.end = block->location.end; + return make_shared(location, _docString, block); } ASTPointer Parser::parseIfStatement(ASTPointer const& _docString) diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index 44624c962..763fda9ca 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -27,6 +27,7 @@ #include #include #include +#include using namespace std; using namespace langutil; @@ -631,6 +632,42 @@ BOOST_AUTO_TEST_CASE(recursion_depth4) CHECK_PARSE_ERROR(text, "Maximum recursion depth reached during parsing"); } +BOOST_AUTO_TEST_CASE(inline_asm_end_location) +{ + auto sourceCode = std::string(R"( + contract C { + function f() public pure returns (uint y) { + uint a; + assembly { a := 0x12345678 } + uint z = a; + y = z; + } + } + )"); + ErrorList errors; + auto contract = parseText(sourceCode, errors); + + class CheckInlineAsmLocation: public ASTConstVisitor + { + public: + bool visited = false; + virtual bool visit(InlineAssembly const& _inlineAsm) + { + auto loc = _inlineAsm.location(); + auto asmStr = loc.source->source().substr(loc.start, loc.end - loc.start); + BOOST_CHECK_EQUAL(asmStr, "assembly { a := 0x12345678 }"); + visited = true; + + return false; + } + }; + + CheckInlineAsmLocation visitor; + contract->accept(visitor); + + BOOST_CHECK_MESSAGE(visitor.visited, "No inline asm block found?!"); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/smtCheckerTests/inline_assembly/empty.sol b/test/libsolidity/smtCheckerTests/inline_assembly/empty.sol index a0a07d85e..bb221e58b 100644 --- a/test/libsolidity/smtCheckerTests/inline_assembly/empty.sol +++ b/test/libsolidity/smtCheckerTests/inline_assembly/empty.sol @@ -8,4 +8,4 @@ contract C } } // ---- -// Warning: (76-93): Assertion checker does not support inline assembly. +// Warning: (76-90): Assertion checker does not support inline assembly. diff --git a/test/libsolidity/smtCheckerTests/inline_assembly/local_var.sol b/test/libsolidity/smtCheckerTests/inline_assembly/local_var.sol index 964f357f8..888f7ef16 100644 --- a/test/libsolidity/smtCheckerTests/inline_assembly/local_var.sol +++ b/test/libsolidity/smtCheckerTests/inline_assembly/local_var.sol @@ -10,4 +10,4 @@ contract C } } // ---- -// Warning: (97-130): Assertion checker does not support inline assembly. +// Warning: (97-121): Assertion checker does not support inline assembly. diff --git a/test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/assembly.sol b/test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/assembly.sol index bfcbbef51..9ffba6fa2 100644 --- a/test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/assembly.sol +++ b/test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/assembly.sol @@ -6,4 +6,4 @@ contract C { } } // ---- -// TypeError: (92-126): This variable is of storage pointer type and can be accessed without prior assignment. +// TypeError: (92-116): This variable is of storage pointer type and can be accessed without prior assignment.