diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index d8e0fa4bc..f91cb91ea 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -118,12 +118,15 @@ void Parser::parsePragmaVersion(SourceLocation const& _location, vector c static SemVerVersion const currentVersion{string(VersionString)}; // FIXME: only match for major version incompatibility if (!matchExpression.matches(currentVersion)) - m_errorReporter.fatalParserError( - _location, - "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" - ); + // If m_parserErrorRecovery is true, the same message will appear from SyntaxChecker::visit(), + // so we don't need to report anything here. + if (!m_parserErrorRecovery) + m_errorReporter.fatalParserError( + _location, + "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() diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index fe1ce5eda..48ac00613 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -41,12 +41,13 @@ namespace test namespace { -ASTPointer parseText(std::string const& _source, ErrorList& _errors) +ASTPointer parseText(std::string const& _source, ErrorList& _errors, bool errorRecovery = false) { ErrorReporter errorReporter(_errors); ASTPointer sourceUnit = Parser( errorReporter, - dev::test::Options::get().evmVersion() + dev::test::Options::get().evmVersion(), + errorRecovery ).parse(std::make_shared(CharStream(_source, ""))); if (!sourceUnit) return ASTPointer(); @@ -78,12 +79,12 @@ bool successParse(std::string const& _source) return true; } -Error getError(std::string const& _source) +Error getError(std::string const& _source, bool errorRecovery = false) { ErrorList errors; try { - parseText(_source, errors); + parseText(_source, errors, errorRecovery); } catch (FatalError const& /*_exception*/) { @@ -134,6 +135,18 @@ BOOST_AUTO_TEST_CASE(unsatisfied_version_followed_by_invalid_syntax) CHECK_PARSE_ERROR(text, "Source file requires different compiler version"); } +BOOST_AUTO_TEST_CASE(unsatisfied_version_with_recovery) +{ + char const* text = R"( + pragma solidity ^99.99.0; + contract test { + uint ; + } + )"; + Error err = getError(text, true); + BOOST_CHECK(searchErrorMessage(err, "Expected identifier but got ';'")); +} + BOOST_AUTO_TEST_CASE(function_natspec_documentation) { char const* text = R"(