diff --git a/liblangutil/SemVerHandler.cpp b/liblangutil/SemVerHandler.cpp index 2358eec5e..fe7359736 100644 --- a/liblangutil/SemVerHandler.cpp +++ b/liblangutil/SemVerHandler.cpp @@ -208,9 +208,18 @@ void SemVerMatchExpressionParser::parseMatchExpression() range.components.push_back(parseMatchComponent()); if (currentToken() == Token::Sub) { - range.components[0].prefix = Token::GreaterThanOrEqual; nextToken(); range.components.push_back(parseMatchComponent()); + + if (TokenTraits::isPragmaOp(range.components[0].prefix) || TokenTraits::isPragmaOp(range.components[1].prefix)) + { + solThrow( + SemVerError, + "You cannot use operators (<, <=, >=, >, ^) with version ranges (-)." + ); + } + + range.components[0].prefix = Token::GreaterThanOrEqual; range.components[1].prefix = Token::LessThanOrEqual; } else diff --git a/liblangutil/Token.h b/liblangutil/Token.h index d79c7f193..b1beb15a3 100644 --- a/liblangutil/Token.h +++ b/liblangutil/Token.h @@ -299,6 +299,7 @@ namespace TokenTraits op == Token::Add || op == Token::Mul || op == Token::Equal || op == Token::NotEqual; } constexpr bool isArithmeticOp(Token op) { return Token::Add <= op && op <= Token::Exp; } constexpr bool isCompareOp(Token op) { return Token::Equal <= op && op <= Token::GreaterThanOrEqual; } + constexpr bool isPragmaOp(Token op) { return (Token::LessThan <= op && op <= Token::GreaterThanOrEqual) || op == Token::BitXor; } constexpr bool isBitOp(Token op) { return (Token::BitOr <= op && op <= Token::BitAnd) || op == Token::BitNot; } constexpr bool isBooleanOp(Token op) { return (Token::Or <= op && op <= Token::And) || op == Token::Not; } diff --git a/test/libsolidity/syntaxTests/pragma/invalid_range_operator_range_first.sol b/test/libsolidity/syntaxTests/pragma/invalid_range_operator_range_first.sol new file mode 100644 index 000000000..35bd89afa --- /dev/null +++ b/test/libsolidity/syntaxTests/pragma/invalid_range_operator_range_first.sol @@ -0,0 +1,3 @@ +pragma solidity <0.8.17 - 0.8.20; +// ---- +// ParserError 1684: (0-33): Invalid version pragma. You cannot use operators (<, <=, >=, >, ^) with version ranges (-). \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/pragma/invalid_range_operator_range_second.sol b/test/libsolidity/syntaxTests/pragma/invalid_range_operator_range_second.sol new file mode 100644 index 000000000..5bb8995c6 --- /dev/null +++ b/test/libsolidity/syntaxTests/pragma/invalid_range_operator_range_second.sol @@ -0,0 +1,3 @@ +pragma solidity 0.8.17 - >0.8.20; +// ---- +// ParserError 1684: (0-33): Invalid version pragma. You cannot use operators (<, <=, >=, >, ^) with version ranges (-). \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/pragma/invalid_range_operator_range_two_ranges.sol b/test/libsolidity/syntaxTests/pragma/invalid_range_operator_range_two_ranges.sol new file mode 100644 index 000000000..67533547f --- /dev/null +++ b/test/libsolidity/syntaxTests/pragma/invalid_range_operator_range_two_ranges.sol @@ -0,0 +1,3 @@ +pragma solidity 0.8.14 || 0.8.17 - >0.8.20; +// ---- +// ParserError 1684: (0-43): Invalid version pragma. You cannot use operators (<, <=, >=, >, ^) with version ranges (-). diff --git a/test/libsolidity/syntaxTests/pragma/valid_range_operator.sol b/test/libsolidity/syntaxTests/pragma/valid_range_operator.sol new file mode 100644 index 000000000..594d6d32b --- /dev/null +++ b/test/libsolidity/syntaxTests/pragma/valid_range_operator.sol @@ -0,0 +1,2 @@ +pragma solidity 0.8.17 - 0.8.20; +// ---- diff --git a/test/libsolidity/syntaxTests/pragma/valid_range_operator_two_ranges.sol b/test/libsolidity/syntaxTests/pragma/valid_range_operator_two_ranges.sol new file mode 100644 index 000000000..22b7fa356 --- /dev/null +++ b/test/libsolidity/syntaxTests/pragma/valid_range_operator_two_ranges.sol @@ -0,0 +1,2 @@ +pragma solidity <0.8.15 || 0.8.17 - 0.8.20; +// ----