From c1dc8df9c97b9bdd87b1fed72db4132989793dbd Mon Sep 17 00:00:00 2001 From: wechman Date: Tue, 26 Jul 2022 15:32:16 +0200 Subject: [PATCH] Adjust code to review findings --- libsolidity/analysis/ControlFlowBuilder.cpp | 6 +++--- libsolidity/analysis/TypeChecker.cpp | 2 +- libsolidity/ast/Types.cpp | 15 +++++++++------ .../ternary_assignment_fine.sol | 4 +--- .../userDefinedTypeOperators/binary_operator.sol | 1 - .../203_struct_reference_compare_operators.sol | 2 +- .../operators/custom/operator_bound_to_enum.sol | 2 +- .../custom/operator_consecutive_calls.sol | 14 ++++++++++++++ .../custom/two_functions_bound_to_operator.sol | 2 +- 9 files changed, 31 insertions(+), 17 deletions(-) create mode 100644 test/libsolidity/syntaxTests/operators/custom/operator_consecutive_calls.sol diff --git a/libsolidity/analysis/ControlFlowBuilder.cpp b/libsolidity/analysis/ControlFlowBuilder.cpp index 88dcab803..7797df958 100644 --- a/libsolidity/analysis/ControlFlowBuilder.cpp +++ b/libsolidity/analysis/ControlFlowBuilder.cpp @@ -61,8 +61,6 @@ bool ControlFlowBuilder::visit(BinaryOperation const& _operation) switch (_operation.getOperator()) { - case Token::Conditional: - return true; case Token::Or: case Token::And: { @@ -89,10 +87,12 @@ bool ControlFlowBuilder::visit(BinaryOperation const& _operation) connect(m_currentNode, nextNode); m_currentNode = nextNode; + return false; } - return false; + } } + return ASTConstVisitor::visit(_operation); } bool ControlFlowBuilder::visit(UnaryOperation const& _operation) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 4ede00e79..6520a5260 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -3853,7 +3853,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor) m_errorReporter.typeError( 9921_error, _usingFor.location(), - "The \"using\" directive cannot be used to attach functions to the enum type." + "The \"using\" directive cannot be used to attach functions to enum types." ); Type const* normalizedType = TypeProvider::withLocationIfReference( diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 3e26cedbd..df408853e 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -403,20 +403,23 @@ FunctionDefinitionResult Type::userDefinedOperator(Token _token, ASTNode const& ); solAssert(functionType && !functionType->parameterTypes().empty()); solAssert(isImplicitlyConvertibleTo(*functionType->parameterTypes().front())); - if ((_unaryOperation && function.parameterList().parameters().size() == 1) || - (!_unaryOperation && function.parameterList().parameters().size() == 2)) + if ( + (_unaryOperation && function.parameterList().parameters().size() == 1) || + (!_unaryOperation && function.parameterList().parameters().size() == 2) + ) seenFunctions.insert(&function); } if (seenFunctions.size() == 1) return *seenFunctions.begin(); - else if (seenFunctions.size() == 0) - return FunctionDefinitionResult::err("A user-defined operator not found."); + else if (!!typeDefinition() && seenFunctions.size() == 0) + return FunctionDefinitionResult::err("Operator has not been user-defined."); + else if (!!typeDefinition()) + return FunctionDefinitionResult::err("Multiple user-defined functions provided for this operator."); else - return FunctionDefinitionResult::err("A user-defined operator not unique."); + return nullptr; } - MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _scope) { MemberList::MemberMap members; diff --git a/test/libsolidity/syntaxTests/controlFlow/localStorageVariables/ternary_assignment_fine.sol b/test/libsolidity/syntaxTests/controlFlow/localStorageVariables/ternary_assignment_fine.sol index a2b12279c..435a01613 100644 --- a/test/libsolidity/syntaxTests/controlFlow/localStorageVariables/ternary_assignment_fine.sol +++ b/test/libsolidity/syntaxTests/controlFlow/localStorageVariables/ternary_assignment_fine.sol @@ -6,7 +6,5 @@ contract C { y; } } -// --- + // ---- -// TypeError 3464: (137-138): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour. -// TypeError 3464: (141-142): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour. diff --git a/test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/binary_operator.sol b/test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/binary_operator.sol index 0e3692946..0bbd8bc43 100644 --- a/test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/binary_operator.sol +++ b/test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/binary_operator.sol @@ -17,7 +17,6 @@ contract C { S storage s; get() + s; } - } // ---- diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/203_struct_reference_compare_operators.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/203_struct_reference_compare_operators.sol index 7467211c7..caf55376d 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/203_struct_reference_compare_operators.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/203_struct_reference_compare_operators.sol @@ -7,4 +7,4 @@ contract test { } } // ---- -// TypeError 2271: (79-85): Operator == not compatible with types struct test.s storage ref and struct test.s storage ref. A user-defined operator not found. +// TypeError 2271: (79-85): Operator == not compatible with types struct test.s storage ref and struct test.s storage ref. Operator has not been user-defined. diff --git a/test/libsolidity/syntaxTests/operators/custom/operator_bound_to_enum.sol b/test/libsolidity/syntaxTests/operators/custom/operator_bound_to_enum.sol index 4a09bf1a4..045922c38 100644 --- a/test/libsolidity/syntaxTests/operators/custom/operator_bound_to_enum.sol +++ b/test/libsolidity/syntaxTests/operators/custom/operator_bound_to_enum.sol @@ -10,4 +10,4 @@ function add(E, E) pure returns (E) { } // ---- -// TypeError 9921: (0-23): The "using" directive cannot be used to attach functions to the enum type. +// TypeError 9921: (0-23): The "using" directive cannot be used to attach functions to enum types. diff --git a/test/libsolidity/syntaxTests/operators/custom/operator_consecutive_calls.sol b/test/libsolidity/syntaxTests/operators/custom/operator_consecutive_calls.sol new file mode 100644 index 000000000..30957a457 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/custom/operator_consecutive_calls.sol @@ -0,0 +1,14 @@ +struct S { uint v; } + +using {add as +} for S; + +function add(S memory _a, S memory) pure returns (S memory) { + return _a; +} + +function g() pure returns (S memory) { + S memory a = S(0); + S memory b = S(1); + S memory c = S(2); + return a + b + c; +} diff --git a/test/libsolidity/syntaxTests/operators/custom/two_functions_bound_to_operator.sol b/test/libsolidity/syntaxTests/operators/custom/two_functions_bound_to_operator.sol index 959347435..9eb017447 100644 --- a/test/libsolidity/syntaxTests/operators/custom/two_functions_bound_to_operator.sol +++ b/test/libsolidity/syntaxTests/operators/custom/two_functions_bound_to_operator.sol @@ -14,4 +14,4 @@ function test() { Int.wrap(0) + Int.wrap(1); } // ---- -// TypeError 2271: (213-238): Operator + not compatible with types Int and Int. A user-defined operator not unique. +// TypeError 2271: (213-238): Operator + not compatible with types Int and Int. Multiple user-defined functions provided for this operator.