Merge pull request #8752 from a3d4/fix-8711-typechecker-compiler-error

Type Checker: Fix internal error when assigning to empty tuples
This commit is contained in:
chriseth 2020-04-23 12:01:00 +02:00 committed by GitHub
commit 18ee96ac91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 1 deletions

View File

@ -11,6 +11,7 @@ Bugfixes:
* SMTChecker: Fix internal error when using array slices. * SMTChecker: Fix internal error when using array slices.
* Type Checker: Disallow ``virtual`` and ``override`` for constructors. * 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 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. * Type Checker: Perform recursiveness check on structs declared at the file level.
Build System: Build System:

View File

@ -1288,8 +1288,11 @@ void TypeChecker::checkExpressionAssignment(Type const& _type, Expression const&
{ {
if (auto const* tupleExpression = dynamic_cast<TupleExpression const*>(&_expression)) if (auto const* tupleExpression = dynamic_cast<TupleExpression const*>(&_expression))
{ {
if (tupleExpression->components().empty())
m_errorReporter.typeError(_expression.location(), "Empty tuple on the left hand side.");
auto const* tupleType = dynamic_cast<TupleType const*>(&_type); auto const* tupleType = dynamic_cast<TupleType const*>(&_type);
auto const& types = tupleType && tupleExpression->components().size() > 1 ? tupleType->components() : vector<TypePointer> { &_type }; auto const& types = tupleType && tupleExpression->components().size() != 1 ? tupleType->components() : vector<TypePointer> { &_type };
solAssert( solAssert(
tupleExpression->components().size() == types.size() || m_errorReporter.hasErrors(), tupleExpression->components().size() == types.size() || m_errorReporter.hasErrors(),

View File

@ -0,0 +1,29 @@
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: (41-43): Empty tuple on the left hand side.
// TypeError: (47-48): Type int_const 2 is not implicitly convertible to expected type tuple().
// TypeError: (86-88): Empty tuple on the left hand side.
// TypeError: (173-175): Empty tuple on the left hand side.
// 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: (229-231): Empty tuple on the left hand side.
// TypeError: (401-404): Empty tuple on the left hand side.
// 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.