From 59c8ec0e65d77ea57df5a89e5c805dd3aff61098 Mon Sep 17 00:00:00 2001 From: wechman Date: Wed, 31 Aug 2022 12:03:52 +0200 Subject: [PATCH] Operators SHL, SAR, Exp and Not can be bound as a user type operators --- docs/grammar/SolidityParser.g4 | 2 +- libsolidity/parsing/Parser.cpp | 3 +-- .../operators/custom/all_operators.sol | 23 ++++++++++++++++++- .../operator_not_user_implementable.sol | 22 +++++++----------- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/docs/grammar/SolidityParser.g4 b/docs/grammar/SolidityParser.g4 index 3629a742d..f384d571b 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -314,7 +314,7 @@ errorDefinition: /** * User type operators. */ -userOp: Add | Sub | Mul | Div | Mod | BitAnd | BitOr | BitXor | BitNot | Equal | NotEqual | LessThan | GreaterThan | LessThanOrEqual | GreaterThanOrEqual; +userOp: Add | Sub | Mul | Div | Mod | BitAnd | BitOr | BitXor | BitNot | Equal | NotEqual | LessThan | GreaterThan | LessThanOrEqual | GreaterThanOrEqual | Shl | Sar | Exp | Not; /** * Using directive to bind library functions and free functions to types. diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 43d3fbca2..a57e582e9 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -981,12 +981,11 @@ ASTPointer Parser::parseUsingDirective() advance(); Token operator_ = m_scanner->currentToken(); vector static const overridableOperators = { - // Potential future additions: <<, >>, **, ! 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::BitNot, Token::SHL, Token::SAR, Token::Exp, Token::Not }; if (!util::contains(overridableOperators, operator_)) { diff --git a/test/libsolidity/semanticTests/operators/custom/all_operators.sol b/test/libsolidity/semanticTests/operators/custom/all_operators.sol index b16f67b87..e870f4268 100644 --- a/test/libsolidity/semanticTests/operators/custom/all_operators.sol +++ b/test/libsolidity/semanticTests/operators/custom/all_operators.sol @@ -2,7 +2,8 @@ type Int is int128; using { bitor as |, bitand as &, bitxor as ^, bitnot as ~, add as +, sub as -, unsub as -, mul as *, div as /, mod as %, - eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >= + eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=, + shl as <<, sar as >>, exp as **, not as ! } for Int; function uw(Int x) pure returns (int128) { @@ -59,6 +60,18 @@ function leq(Int x, Int) pure returns (bool) { function geq(Int x, Int) pure returns (bool) { return uw(x) >= 10; } +function shl(Int, Int) pure returns (Int) { + return w(20); +} +function sar(Int, Int) pure returns (Int) { + return w(21); +} +function exp(Int, Int) pure returns (Int) { + return w(22); +} +function not(Int) pure returns (Int) { + return w(23); +} contract C { function test_bitor() public pure returns (Int) { return w(1) | w(2); } @@ -77,6 +90,10 @@ contract C { function test_gt(int128 x) public pure returns (bool) { return w(x) > w(2); } function test_leq(int128 x) public pure returns (bool) { return w(x) <= w(2); } function test_geq(int128 x) public pure returns (bool) { return w(x) >= w(2); } + function test_shl() public pure returns (Int) { return w(1) << w(2); } + function test_sar() public pure returns (Int) { return w(1) >> w(2); } + function test_exp() public pure returns (Int) { return w(1) ** w(2); } + function test_not() public pure returns (Int) { return !w(1); } } // ---- @@ -103,3 +120,7 @@ contract C { // test_leq(int128): 11 -> false // test_geq(int128): 10 -> true // test_geq(int128): 9 -> false +// test_shl() -> 20 +// test_sar() -> 21 +// test_exp() -> 22 +// test_not() -> 23 diff --git a/test/libsolidity/syntaxTests/operators/custom/operator_not_user_implementable.sol b/test/libsolidity/syntaxTests/operators/custom/operator_not_user_implementable.sol index d84ee8692..f9bce4273 100644 --- a/test/libsolidity/syntaxTests/operators/custom/operator_not_user_implementable.sol +++ b/test/libsolidity/syntaxTests/operators/custom/operator_not_user_implementable.sol @@ -1,9 +1,6 @@ using { - f as <<, - f as >>, - f as **, f as ++, - f as !, + f as --, f as x, f as delete, f as new, @@ -11,13 +8,10 @@ using { } for int256; // ---- -// ParserError 4403: (17-19): The operator << cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~ -// ParserError 4403: (30-32): The operator >> cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~ -// ParserError 4403: (43-45): The operator ** cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~ -// ParserError 4403: (56-58): The operator ++ cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~ -// ParserError 4403: (69-70): The operator ! cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~ -// ParserError 4403: (81-82): The operator cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~ -// ParserError 4403: (93-99): The operator delete cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~ -// ParserError 4403: (110-113): The operator new cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~ -// ParserError 4403: (124-125): The operator ( cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~ -// ParserError 2314: (125-126): Expected '}' but got ')' +// ParserError 4403: (17-19): The operator ++ cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~, <<, >>, **, ! +// ParserError 4403: (30-32): The operator -- cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~, <<, >>, **, ! +// ParserError 4403: (43-44): The operator cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~, <<, >>, **, ! +// ParserError 4403: (55-61): The operator delete cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~, <<, >>, **, ! +// ParserError 4403: (72-75): The operator new cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~, <<, >>, **, ! +// ParserError 4403: (86-87): The operator ( cannot be user-implemented. This is only possible for the following operators: |, &, ^, +, -, *, /, %, ==, !=, <, >, <=, >=, ~, <<, >>, **, ! +// ParserError 2314: (87-88): Expected '}' but got ')'