diff --git a/Changelog.md b/Changelog.md index ec45f9da7..a901e8606 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,6 +14,7 @@ Bugfixes: * Type Checker: Disallow ``virtual`` and ``override`` for constructors. * Type Checker: Fix several internal errors by performing size and recursiveness checks of types before the full type checking. * Type Checker: Fix internal error when assigning to empty tuples. + * Type Checker: Fix internal error when applying unary operators to tuples with empty components. * Type Checker: Perform recursiveness check on structs declared at the file level. * Standard Json Input: Fix error when using prefix ``file://`` in the field ``urls``. diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index a0155c9ce..b4030c0c4 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1478,13 +1478,13 @@ bool TypeChecker::visit(UnaryOperation const& _operation) TypePointer t = type(_operation.subExpression())->unaryOperatorResult(op); if (!t) { - m_errorReporter.typeError( - _operation.location(), - "Unary operator " + - string(TokenTraits::toString(op)) + - " cannot be applied to type " + - subExprType->toString() - ); + string description = "Unary operator " + string(TokenTraits::toString(op)) + " cannot be applied to type " + subExprType->toString(); + if (modifying) + // Cannot just report the error, ignore the unary operator, and continue, + // because the sub-expression was already processed with requireLValue() + m_errorReporter.fatalTypeError(_operation.location(), description); + else + m_errorReporter.typeError(_operation.location(), description); t = subExprType; } _operation.annotation().type = t; diff --git a/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_bitnot_tuple.sol b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_bitnot_tuple.sol new file mode 100644 index 000000000..56877ecdc --- /dev/null +++ b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_bitnot_tuple.sol @@ -0,0 +1,9 @@ +contract C +{ + function f() public + { + int x = ~(0,); + } +} +// ---- +// TypeError: (60-64): Tuple component cannot be empty. diff --git a/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_dec_tuple.sol b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_dec_tuple.sol new file mode 100644 index 000000000..161200642 --- /dev/null +++ b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_dec_tuple.sol @@ -0,0 +1,9 @@ +contract C +{ + function f() public + { + int x = --(,); + } +} +// ---- +// TypeError: (59-64): Unary operator -- cannot be applied to type tuple(,) diff --git a/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_delete_tuple.sol b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_delete_tuple.sol new file mode 100644 index 000000000..0cdcee5cc --- /dev/null +++ b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_delete_tuple.sol @@ -0,0 +1,10 @@ +contract C +{ + function f() public + { + int x = delete (,0); + } +} +// ---- +// TypeError: (68-69): Expression has to be an lvalue. +// TypeError: (59-70): Unary operator delete cannot be applied to type tuple(,int_const 0) diff --git a/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_inc_tuple.sol b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_inc_tuple.sol new file mode 100644 index 000000000..fe5d5e5ce --- /dev/null +++ b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_inc_tuple.sol @@ -0,0 +1,9 @@ +contract C +{ + function f() public + { + (int x) = ++(,); + } +} +// ---- +// TypeError: (61-66): Unary operator ++ cannot be applied to type tuple(,) diff --git a/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_unary_tuple.sol b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_unary_tuple.sol new file mode 100644 index 000000000..6f40f1ed1 --- /dev/null +++ b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_unary_tuple.sol @@ -0,0 +1,20 @@ +contract C +{ + function f() public + { + int x = +(0, 0); + int y = -(0, 0); + (int z) = ~(0, 0); + (int t) = !(0, 0); + } +} +// ---- +// SyntaxError: (59-66): Use of unary + is disallowed. +// TypeError: (59-66): Unary operator + cannot be applied to type tuple(int_const 0,int_const 0) +// TypeError: (51-66): Different number of components on the left hand side (1) than on the right hand side (2). +// TypeError: (84-91): Unary operator - cannot be applied to type tuple(int_const 0,int_const 0) +// TypeError: (76-91): Different number of components on the left hand side (1) than on the right hand side (2). +// TypeError: (111-118): Unary operator ~ cannot be applied to type tuple(int_const 0,int_const 0) +// TypeError: (101-118): Different number of components on the left hand side (1) than on the right hand side (2). +// TypeError: (138-145): Unary operator ! cannot be applied to type tuple(int_const 0,int_const 0) +// TypeError: (128-145): Different number of components on the left hand side (1) than on the right hand side (2).