diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 68e58e1c9..6242ee609 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -63,6 +63,7 @@ set(sources ast/CallGraph.cpp ast/CallGraph.h ast/ExperimentalFeatures.h + ast/OverridableOperators.h ast/Types.cpp ast/Types.h ast/TypeProvider.cpp diff --git a/libsolidity/ast/OverridableOperators.h b/libsolidity/ast/OverridableOperators.h new file mode 100644 index 000000000..38a375ecb --- /dev/null +++ b/libsolidity/ast/OverridableOperators.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +#include + +namespace solidity::frontend +{ + +std::vector const overridableOperators = { + langutil::Token::BitOr, + langutil::Token::BitAnd, + langutil::Token::BitXor, + langutil::Token::Add, + langutil::Token::Sub, + langutil::Token::Mul, + langutil::Token::Div, + langutil::Token::Mod, + langutil::Token::Equal, + langutil::Token::NotEqual, + langutil::Token::LessThan, + langutil::Token::GreaterThan, + langutil::Token::LessThanOrEqual, + langutil::Token::GreaterThanOrEqual, + langutil::Token::BitNot, + langutil::Token::SHL, + langutil::Token::SAR, + langutil::Token::Exp, + langutil::Token::Not +}; + +} diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index cc6f30198..f39b5b8b6 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -25,6 +25,7 @@ #include #include +#include #include @@ -387,7 +388,7 @@ vector usingForDirectivesForType(Type const& _type, AS Result Type::userDefinedOperator(Token _token, ASTNode const& _scope, bool _unaryOperation) const { - if (!typeDefinition()) + if (!typeDefinition() || !util::contains(overridableOperators, _token)) return nullptr; set matchingDefinitions; diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index a57e582e9..32b795a9b 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -23,6 +23,7 @@ #include +#include #include #include #include @@ -980,13 +981,6 @@ ASTPointer Parser::parseUsingDirective() { advance(); Token operator_ = m_scanner->currentToken(); - vector static const overridableOperators = { - Token::BitOr, Token::BitAnd, Token::BitXor, - Token::Add, Token::Sub, Token::Mul, Token::Div, Token::Mod, - Token::Equal, Token::NotEqual, - Token::LessThan, Token::GreaterThan, Token::LessThanOrEqual, Token::GreaterThanOrEqual, - Token::BitNot, Token::SHL, Token::SAR, Token::Exp, Token::Not - }; if (!util::contains(overridableOperators, operator_)) { parserError( diff --git a/test/libsolidity/syntaxTests/operators/custom/binary_operator_cannot_be_applied.sol b/test/libsolidity/syntaxTests/operators/custom/binary_operator_cannot_be_applied.sol new file mode 100644 index 000000000..76258a1a4 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/custom/binary_operator_cannot_be_applied.sol @@ -0,0 +1,11 @@ +type Int is int256; + +function f() pure { + Int a = Int.wrap(0); + a + a; + a >>> a; +} + +// ---- +// TypeError 2271: (70-75): Binary operator + not compatible with types Int and Int. No matching user-defined operator found. +// TypeError 2271: (81-88): Binary operator >>> not compatible with types Int and Int. diff --git a/test/libsolidity/syntaxTests/operators/custom/unary_operator_cannot_be_applied.sol b/test/libsolidity/syntaxTests/operators/custom/unary_operator_cannot_be_applied.sol new file mode 100644 index 000000000..3b95318e8 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/custom/unary_operator_cannot_be_applied.sol @@ -0,0 +1,11 @@ +type Int is int256; + +function f() pure { + Int a = Int.wrap(0); + -a; + a++; +} + +// ---- +// TypeError 4907: (70-72): Unary operator - cannot be applied to type Int. No matching user-defined operator found. +// TypeError 9767: (78-81): Unary operator ++ cannot be applied to type Int.