Report meaningful error if parsing a version pragma failed

This commit is contained in:
Alex Beregszaszi 2020-12-16 22:33:40 +00:00
parent 8c455a1a99
commit b14a6a10cc
14 changed files with 45 additions and 8 deletions

View File

@ -1,12 +1,12 @@
### 0.8.1 (unreleased) ### 0.8.1 (unreleased)
Compiler Features: Compiler Features:
* Parser: Report meaningful error if parsing a version pragma failed.
* SMTChecker: Support ABI functions as uninterpreted functions. * SMTChecker: Support ABI functions as uninterpreted functions.
Bugfixes: Bugfixes:
* SMTChecker: Fix false negatives in overriding modifiers. * SMTChecker: Fix false negatives in overriding modifiers.
### 0.8.0 (2020-12-16) ### 0.8.0 (2020-12-16)
Breaking Changes: Breaking Changes:

View File

@ -147,7 +147,7 @@ bool SemVerMatchExpression::matches(SemVerVersion const& _version) const
return false; return false;
} }
SemVerMatchExpression SemVerMatchExpressionParser::parse() optional<SemVerMatchExpression> SemVerMatchExpressionParser::parse()
{ {
reset(); reset();
@ -166,6 +166,7 @@ SemVerMatchExpression SemVerMatchExpressionParser::parse()
catch (SemVerError const&) catch (SemVerError const&)
{ {
reset(); reset();
return nullopt;
} }
return m_expression; return m_expression;

View File

@ -26,6 +26,7 @@
#include <liblangutil/Token.h> #include <liblangutil/Token.h>
#include <string> #include <string>
#include <optional>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -86,7 +87,9 @@ public:
SemVerMatchExpressionParser(std::vector<Token> _tokens, std::vector<std::string> _literals): SemVerMatchExpressionParser(std::vector<Token> _tokens, std::vector<std::string> _literals):
m_tokens(std::move(_tokens)), m_literals(std::move(_literals)) m_tokens(std::move(_tokens)), m_literals(std::move(_literals))
{} {}
SemVerMatchExpression parse();
/// Returns an expression if it was parseable, or nothing otherwise.
std::optional<SemVerMatchExpression> parse();
private: private:
void reset(); void reset();

View File

@ -160,8 +160,10 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
vector<string> literals(_pragma.literals().begin() + 1, _pragma.literals().end()); vector<string> literals(_pragma.literals().begin() + 1, _pragma.literals().end());
SemVerMatchExpressionParser parser(tokens, literals); SemVerMatchExpressionParser parser(tokens, literals);
auto matchExpression = parser.parse(); auto matchExpression = parser.parse();
// An unparsable version pragma is an unrecoverable fatal error in the parser.
solAssert(matchExpression.has_value(), "");
static SemVerVersion const currentVersion{string(VersionString)}; static SemVerVersion const currentVersion{string(VersionString)};
if (!matchExpression.matches(currentVersion)) if (!matchExpression->matches(currentVersion))
m_errorReporter.syntaxError( m_errorReporter.syntaxError(
3997_error, 3997_error,
_pragma.location(), _pragma.location(),

View File

@ -140,9 +140,16 @@ void Parser::parsePragmaVersion(SourceLocation const& _location, vector<Token> c
{ {
SemVerMatchExpressionParser parser(_tokens, _literals); SemVerMatchExpressionParser parser(_tokens, _literals);
auto matchExpression = parser.parse(); auto matchExpression = parser.parse();
if (!matchExpression.has_value())
m_errorReporter.fatalParserError(
1684_error,
_location,
"Found version pragma, but failed to parse it. "
"Please ensure there is a trailing semicolon."
);
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))
// If m_parserErrorRecovery is true, the same message will appear from SyntaxChecker::visit(), // If m_parserErrorRecovery is true, the same message will appear from SyntaxChecker::visit(),
// so we don't need to report anything here. // so we don't need to report anything here.
if (!m_parserErrorRecovery) if (!m_parserErrorRecovery)

View File

@ -114,7 +114,7 @@ do
SOL_FILES+=("$line") SOL_FILES+=("$line")
done < <( done < <(
grep -riL -E \ grep -riL -E \
"^\/\/ (Syntax|Type|Declaration)Error|^\/\/ ParserError (2837|3716|3997|5333|6275|6281|6933|7319)|^==== Source:" \ "^\/\/ (Syntax|Type|Declaration)Error|^\/\/ ParserError (1684|2837|3716|3997|5333|6275|6281|6933|7319)|^==== Source:" \
"${ROOT_DIR}/test/libsolidity/syntaxTests" \ "${ROOT_DIR}/test/libsolidity/syntaxTests" \
"${ROOT_DIR}/test/libsolidity/semanticTests" | "${ROOT_DIR}/test/libsolidity/semanticTests" |
grep -v -E 'comments/.*_direction_override.*.sol' | grep -v -E 'comments/.*_direction_override.*.sol' |

View File

@ -58,11 +58,12 @@ SemVerMatchExpression parseExpression(string const& _input)
} }
auto expression = SemVerMatchExpressionParser(tokens, literals).parse(); auto expression = SemVerMatchExpressionParser(tokens, literals).parse();
BOOST_REQUIRE(expression.has_value());
BOOST_CHECK_MESSAGE( BOOST_CHECK_MESSAGE(
expression.isValid(), expression->isValid(),
"Expression \"" + _input + "\" did not parse properly." "Expression \"" + _input + "\" did not parse properly."
); );
return expression; return *expression;
} }
} }

View File

@ -0,0 +1,3 @@
pragma solidity ^0^1;
// ----
// ParserError 5333: (0-21): Source file requires different compiler version (current compiler is ....

View File

@ -0,0 +1,3 @@
pragma solidity pragma;
// ----
// ParserError 1684: (0-23): Found version pragma, but failed to parse it. Please ensure there is a trailing semicolon.

View File

@ -0,0 +1,4 @@
pragma solidity #8.0.0;
// ----
// ParserError 6281: (16-17): Token incompatible with Solidity parser as part of pragma directive.
// ParserError 5333: (0-23): Source file requires different compiler version (current compiler is ....

View File

@ -0,0 +1,3 @@
pragma solidity (8.0.0);
// ----
// ParserError 1684: (0-24): Found version pragma, but failed to parse it. Please ensure there is a trailing semicolon.

View File

@ -0,0 +1,3 @@
pragma solidity 88_;
// ----
// ParserError 1684: (0-20): Found version pragma, but failed to parse it. Please ensure there is a trailing semicolon.

View File

@ -0,0 +1,3 @@
pragma solidity 0.4.3
// ----
// ParserError 2314: (22-22): Expected ';' but got end of source

View File

@ -0,0 +1,4 @@
pragma solidity 0.4.3
pragma abicoder v2;
// ----
// ParserError 1684: (0-41): Found version pragma, but failed to parse it. Please ensure there is a trailing semicolon.