Disallow unary plus at the parsing stage

This commit is contained in:
Kamil Śliwak 2023-04-14 21:06:59 +02:00
parent ee1b50d345
commit 8a14680851
9 changed files with 27 additions and 20 deletions

View File

@ -9,6 +9,7 @@ Compiler Features:
* NatSpec: Add support for NatSpec documentation in ``enum`` definitions.
* NatSpec: Add support for NatSpec documentation in ``struct`` definitions.
* Optimizer: Re-implement simplified version of UnusedAssignEliminator and UnusedStoreEliminator. It can correctly remove some unused assignments in deeply nested loops that were ignored by the old version.
* Parser: Unary plus is no longer recognized as a unary operator in the AST and triggers an error at the parsing stage (rather than later during the analysis).
* SMTChecker: Properties that are proved safe are now reported explicitly at the end of the analysis. By default, only the number of safe properties is shown. The CLI option ``--model-checker-show-proved-safe`` and the JSON option ``settings.modelChecker.showProvedSafe`` can be enabled to show the full list of safe properties.
* SMTChecker: Group all messages about unsupported language features in a single warning. The CLI option ``--model-checker-show-unsupported`` and the JSON option ``settings.modelChecker.showUnsupported`` can be enabled to show the full list.
* Yul EVM Code Transform: If available, use ``push0`` instead of ``codesize`` to produce an arbitrary value on stack in order to create equal stack heights between branches.

View File

@ -332,9 +332,7 @@ bool SyntaxChecker::visit(Literal const& _literal)
bool SyntaxChecker::visit(UnaryOperation const& _operation)
{
if (_operation.getOperator() == Token::Add)
m_errorReporter.syntaxError(9636_error, _operation.location(), "Use of unary + is disallowed.");
solAssert(_operation.getOperator() != Token::Add);
return true;
}

View File

@ -819,16 +819,17 @@ BoolResult FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) con
TypeResult FixedPointType::unaryOperatorResult(Token _operator) const
{
solAssert(_operator != Token::Add);
switch (_operator)
{
case Token::Delete:
// "delete" is ok for all fixed types
return TypeResult{TypeProvider::emptyTuple()};
case Token::Add:
case Token::Sub:
case Token::Inc:
case Token::Dec:
// for fixed, we allow +, -, ++ and --
// for fixed, we allow -, ++ and --
return this;
default:
return nullptr;

View File

@ -511,8 +511,8 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)
m_currentLValue.reset();
break;
case Token::Add: // +
// unary add, so basically no-op
break;
// According to SyntaxChecker...
solAssert(false, "Use of unary + is disallowed.");
case Token::Sub: // -
solUnimplementedAssert(
type.category() != Type::Category::FixedPoint,

View File

@ -1863,6 +1863,10 @@ ASTPointer<Expression> Parser::parseUnaryExpression(
ASTNodeFactory nodeFactory = _partiallyParsedExpression ?
ASTNodeFactory(*this, _partiallyParsedExpression) : ASTNodeFactory(*this);
Token token = m_scanner->currentToken();
if (token == Token::Add)
fatalParserError(9636_error, "Use of unary + is disallowed.");
if (!_partiallyParsedExpression && (TokenTraits::isUnaryOp(token) || TokenTraits::isCountOp(token)))
{
// prefix expression

View File

@ -0,0 +1,9 @@
contract C
{
function f() public
{
int x = +(0, 0);
}
}
// ----
// ParserError 9636: (59-60): Use of unary + is disallowed.

View File

@ -2,19 +2,15 @@ contract C
{
function f() public
{
int x = +(0, 0);
int y = -(0, 0);
(int z) = ~(0, 0);
(int t) = !(0, 0);
}
}
// ----
// SyntaxError 9636: (59-66): Use of unary + is disallowed.
// TypeError 4907: (59-66): Built-in unary operator + cannot be applied to type tuple(int_const 0,int_const 0).
// TypeError 4907: (59-66): Built-in unary operator - cannot be applied to type tuple(int_const 0,int_const 0).
// TypeError 7364: (51-66): Different number of components on the left hand side (1) than on the right hand side (2).
// TypeError 4907: (84-91): Built-in unary operator - cannot be applied to type tuple(int_const 0,int_const 0).
// TypeError 7364: (76-91): Different number of components on the left hand side (1) than on the right hand side (2).
// TypeError 4907: (111-118): Built-in unary operator ~ cannot be applied to type tuple(int_const 0,int_const 0).
// TypeError 7364: (101-118): Different number of components on the left hand side (1) than on the right hand side (2).
// TypeError 4907: (138-145): Built-in unary operator ! cannot be applied to type tuple(int_const 0,int_const 0).
// TypeError 7364: (128-145): Different number of components on the left hand side (1) than on the right hand side (2).
// TypeError 4907: (86-93): Built-in unary operator ~ cannot be applied to type tuple(int_const 0,int_const 0).
// TypeError 7364: (76-93): Different number of components on the left hand side (1) than on the right hand side (2).
// TypeError 4907: (113-120): Built-in unary operator ! cannot be applied to type tuple(int_const 0,int_const 0).
// TypeError 7364: (103-120): Different number of components on the left hand side (1) than on the right hand side (2).

View File

@ -6,5 +6,4 @@ contract test {
}
}
// ----
// SyntaxError 9636: (70-75): Use of unary + is disallowed.
// TypeError 4907: (70-75): Built-in unary operator + cannot be applied to type rational_const 13 / 4.
// ParserError 9636: (70-71): Use of unary + is disallowed.

View File

@ -5,5 +5,4 @@ contract test {
}
}
// ----
// SyntaxError 9636: (70-72): Use of unary + is disallowed.
// TypeError 4907: (70-72): Built-in unary operator + cannot be applied to type uint256.
// ParserError 9636: (70-71): Use of unary + is disallowed.