From 9538024c81368d866788a360ab81e527c57a38bd Mon Sep 17 00:00:00 2001 From: a3d4 Date: Thu, 23 Apr 2020 05:48:02 +0200 Subject: [PATCH] Fix #8711, #8277 --- Changelog.md | 1 + libsolidity/analysis/TypeChecker.cpp | 2 +- .../tupleAssignments/empty_tuples_lhs.sol | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/tupleAssignments/empty_tuples_lhs.sol diff --git a/Changelog.md b/Changelog.md index 50a3e4d1e..30f0e3368 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ Bugfixes: * SMTChecker: Fix internal error when fixed points are used. * 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: Perform recursiveness check on structs declared at the file level. Build System: diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 17add7a66..db88f20bf 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1289,7 +1289,7 @@ void TypeChecker::checkExpressionAssignment(Type const& _type, Expression const& if (auto const* tupleExpression = dynamic_cast(&_expression)) { auto const* tupleType = dynamic_cast(&_type); - auto const& types = tupleType && tupleExpression->components().size() > 1 ? tupleType->components() : vector { &_type }; + auto const& types = tupleType && tupleExpression->components().size() != 1 ? tupleType->components() : vector { &_type }; solAssert( tupleExpression->components().size() == types.size() || m_errorReporter.hasErrors(), diff --git a/test/libsolidity/syntaxTests/tupleAssignments/empty_tuples_lhs.sol b/test/libsolidity/syntaxTests/tupleAssignments/empty_tuples_lhs.sol new file mode 100644 index 000000000..390a3636a --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/empty_tuples_lhs.sol @@ -0,0 +1,24 @@ +contract C { + function f0() public { (()) = 2; } + + function f1() public pure { (()) = (); } + + //#8711 + function f2() internal pure returns (uint, uint) { return () = f2(); } + + //#8277 + function f3()public{return()=();} + + //#8277 + function f4 ( bytes32 hash , uint8 v , bytes32 r , bytes32 s , uint blockExpired , bytes32 salt ) public returns ( address ) { + require ( ( ( ) ) |= keccak256 ( abi . encodePacked ( blockExpired , salt ) ) ) ; + return ecrecover ( hash , v , r , s ) ; + } +} +// ---- +// TypeError: (47-48): Type int_const 2 is not implicitly convertible to expected type tuple(). +// TypeError: (178-182): Type tuple(uint256,uint256) is not implicitly convertible to expected type tuple(). +// TypeError: (166-182): Different number of arguments in return statement than in returns declaration. +// TypeError: (399-466): Compound assignment is not allowed for tuple types. +// TypeError: (410-466): Type bytes32 is not implicitly convertible to expected type tuple(). +// TypeError: (389-396): No matching declaration found after argument-dependent lookup.