A pragma version mismatch is not fatal if ...

error recovery is desired.

Fixes #7085
This commit is contained in:
rocky 2019-07-17 15:29:56 -04:00
parent 15cba9163e
commit f9b631f410
2 changed files with 26 additions and 10 deletions

View File

@ -118,12 +118,15 @@ void Parser::parsePragmaVersion(SourceLocation const& _location, vector<Token> c
static SemVerVersion const currentVersion{string(VersionString)}; static SemVerVersion const currentVersion{string(VersionString)};
// FIXME: only match for major version incompatibility // FIXME: only match for major version incompatibility
if (!matchExpression.matches(currentVersion)) if (!matchExpression.matches(currentVersion))
m_errorReporter.fatalParserError( // If m_parserErrorRecovery is true, the same message will appear from SyntaxChecker::visit(),
_location, // so we don't need to report anything here.
"Source file requires different compiler version (current compiler is " + if (!m_parserErrorRecovery)
string(VersionString) + " - note that nightly builds are considered to be " m_errorReporter.fatalParserError(
"strictly less than the released version" _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<PragmaDirective> Parser::parsePragmaDirective() ASTPointer<PragmaDirective> Parser::parsePragmaDirective()

View File

@ -41,12 +41,13 @@ namespace test
namespace namespace
{ {
ASTPointer<ContractDefinition> parseText(std::string const& _source, ErrorList& _errors) ASTPointer<ContractDefinition> parseText(std::string const& _source, ErrorList& _errors, bool errorRecovery = false)
{ {
ErrorReporter errorReporter(_errors); ErrorReporter errorReporter(_errors);
ASTPointer<SourceUnit> sourceUnit = Parser( ASTPointer<SourceUnit> sourceUnit = Parser(
errorReporter, errorReporter,
dev::test::Options::get().evmVersion() dev::test::Options::get().evmVersion(),
errorRecovery
).parse(std::make_shared<Scanner>(CharStream(_source, ""))); ).parse(std::make_shared<Scanner>(CharStream(_source, "")));
if (!sourceUnit) if (!sourceUnit)
return ASTPointer<ContractDefinition>(); return ASTPointer<ContractDefinition>();
@ -78,12 +79,12 @@ bool successParse(std::string const& _source)
return true; return true;
} }
Error getError(std::string const& _source) Error getError(std::string const& _source, bool errorRecovery = false)
{ {
ErrorList errors; ErrorList errors;
try try
{ {
parseText(_source, errors); parseText(_source, errors, errorRecovery);
} }
catch (FatalError const& /*_exception*/) 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"); 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) BOOST_AUTO_TEST_CASE(function_natspec_documentation)
{ {
char const* text = R"( char const* text = R"(