From c2ec6d71b4707dab9b7727347077904b7a90eaf2 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 12 Dec 2018 15:45:17 +0000 Subject: [PATCH 1/3] Add version pragma parsing to Parser --- libsolidity/analysis/SyntaxChecker.cpp | 2 +- libsolidity/parsing/Parser.cpp | 25 +++++++++++++++++++++++++ libsolidity/parsing/Parser.h | 1 + test/libsolidity/SolidityParser.cpp | 9 +++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index 12e148641..066b5004f 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -114,7 +114,7 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma) vector literals(_pragma.literals().begin() + 1, _pragma.literals().end()); SemVerMatchExpressionParser parser(tokens, literals); auto matchExpression = parser.parse(); - SemVerVersion currentVersion{string(VersionString)}; + static SemVerVersion const currentVersion{string(VersionString)}; if (!matchExpression.matches(currentVersion)) m_errorReporter.syntaxError( _pragma.location(), diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 9de2146e3..bcb28988f 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -22,6 +22,8 @@ #include +#include +#include #include #include #include @@ -106,6 +108,20 @@ ASTPointer Parser::parse(shared_ptr const& _scanner) } } +void Parser::parsePragmaVersion(vector const& tokens, vector const& literals) +{ + SemVerMatchExpressionParser parser(tokens, literals); + auto matchExpression = parser.parse(); + static SemVerVersion const currentVersion{string(VersionString)}; + // FIXME: only match for major version incompatibility + if (!matchExpression.matches(currentVersion)) + fatalParserError( + "Source file requires different compiler version (current compiler is " + + string(VersionString) + " - note that nightly builds are considered to be " + "strictly less than the released version" + ); +} + ASTPointer Parser::parsePragmaDirective() { RecursionGuard recursionGuard(*this); @@ -134,6 +150,15 @@ ASTPointer Parser::parsePragmaDirective() while (m_scanner->currentToken() != Token::Semicolon && m_scanner->currentToken() != Token::EOS); nodeFactory.markEndPosition(); expectToken(Token::Semicolon); + + if (literals.size() >= 2 && literals[0] == "solidity") + { + parsePragmaVersion( + vector(tokens.begin() + 1, tokens.end()), + vector(literals.begin() + 1, literals.end()) + ); + } + return nodeFactory.createNode(tokens, literals); } diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 15852096a..bf02c626c 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -70,6 +70,7 @@ private: ///@{ ///@name Parsing functions for the AST nodes + void parsePragmaVersion(std::vector const& tokens, std::vector const& literals); ASTPointer parsePragmaDirective(); ASTPointer parseImportDirective(); ContractDefinition::ContractKind parseContractKind(); diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index d86d3d397..619d6a48c 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -113,6 +113,15 @@ while(0) BOOST_AUTO_TEST_SUITE(SolidityParser) +BOOST_AUTO_TEST_CASE(unsatisfied_version_followed_by_invalid_syntax) +{ + char const* text = R"( + pragma solidity ^99.99.0; + this is surely invalid + )"; + CHECK_PARSE_ERROR(text, "Source file requires different compiler version"); +} + BOOST_AUTO_TEST_CASE(function_natspec_documentation) { char const* text = R"( From ba15bc0a2325c50578247c3ee477a3d49a6f8cf1 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 18 Dec 2018 11:08:11 +0000 Subject: [PATCH 2/3] Fail if parsing failed in AnalysisFramework Otherwise Compilerstack::analyze will throw an exception. --- test/libsolidity/AnalysisFramework.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsolidity/AnalysisFramework.cpp b/test/libsolidity/AnalysisFramework.cpp index 8a72f996e..abeecd327 100644 --- a/test/libsolidity/AnalysisFramework.cpp +++ b/test/libsolidity/AnalysisFramework.cpp @@ -52,7 +52,7 @@ AnalysisFramework::parseAnalyseAndReturnError( m_compiler.setEVMVersion(dev::test::Options::get().evmVersion()); if (!m_compiler.parse()) { - BOOST_ERROR("Parsing contract failed in analysis test suite:" + formatErrors()); + BOOST_FAIL("Parsing contract failed in analysis test suite:" + formatErrors()); } m_compiler.analyze(); From bd2f2ecbbd20f8d861d7a068954ea2e27d7f02be Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 18 Dec 2018 11:17:52 +0000 Subject: [PATCH 3/3] Move unsatisfied_version test from SolidityNameAndTypeResolution to SolidityParser --- test/libsolidity/SolidityNameAndTypeResolution.cpp | 12 ------------ test/libsolidity/SolidityParser.cpp | 8 ++++++++ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 757260279..774f67fe8 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -376,18 +376,6 @@ BOOST_AUTO_TEST_CASE(warn_nonpresent_pragma) BOOST_CHECK(searchErrorMessage(*sourceAndError.second.front(), "Source file does not specify required compiler version!")); } -BOOST_AUTO_TEST_CASE(unsatisfied_version) -{ - char const* text = R"( - pragma solidity ^99.99.0; - )"; - auto sourceAndError = parseAnalyseAndReturnError(text, false, false, false); - BOOST_REQUIRE(!sourceAndError.second.empty()); - BOOST_REQUIRE(!!sourceAndError.first); - BOOST_CHECK(sourceAndError.second.front()->type() == Error::Type::SyntaxError); - BOOST_CHECK(searchErrorMessage(*sourceAndError.second.front(), "Source file requires different compiler version")); -} - BOOST_AUTO_TEST_CASE(returndatasize_as_variable) { char const* text = R"( diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index 619d6a48c..a33c6134d 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -113,6 +113,14 @@ while(0) BOOST_AUTO_TEST_SUITE(SolidityParser) +BOOST_AUTO_TEST_CASE(unsatisfied_version) +{ + char const* text = R"( + pragma solidity ^99.99.0; + )"; + CHECK_PARSE_ERROR(text, "Source file requires different compiler version"); +} + BOOST_AUTO_TEST_CASE(unsatisfied_version_followed_by_invalid_syntax) { char const* text = R"(