Add missing annotation assignments

This commit is contained in:
Mathias Baumann 2020-10-05 12:21:30 +02:00
parent 22caed1e1e
commit 6114cd8e8e
5 changed files with 25 additions and 3 deletions

View File

@ -15,6 +15,7 @@ Compiler Features:
Bugfixes: Bugfixes:
* Type Checker: Fix internal compiler error when calling `.push(<arg>)` for a storage array with a nested mapping. * Type Checker: Fix internal compiler error when calling `.push(<arg>)` for a storage array with a nested mapping.
* Type Checker: Add missing checks for calls using types incompatible with ABIEncoderV1 in modules where ABIEncoderV2 is not enabled. * Type Checker: Add missing checks for calls using types incompatible with ABIEncoderV1 in modules where ABIEncoderV2 is not enabled.
* Fixed internal compiler errors for certain contracts involving the ``new`` expression
### 0.7.2 (2020-09-28) ### 0.7.2 (2020-09-28)

View File

@ -167,7 +167,7 @@ void ImmutableValidator::analyseVariableReference(VariableDeclaration const& _va
// If this is not an ordinary assignment, we write and read at the same time. // If this is not an ordinary assignment, we write and read at the same time.
bool write = _expression.annotation().willBeWrittenTo; bool write = _expression.annotation().willBeWrittenTo;
bool read = !_expression.annotation().willBeWrittenTo || !*_expression.annotation().lValueOfOrdinaryAssignment; bool read = !_expression.annotation().willBeWrittenTo || !_expression.annotation().lValueOfOrdinaryAssignment;
if (write) if (write)
{ {
if (!m_currentConstructor) if (!m_currentConstructor)

View File

@ -1420,7 +1420,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
{ {
requireLValue( requireLValue(
*component, *component,
*_tuple.annotation().lValueOfOrdinaryAssignment _tuple.annotation().lValueOfOrdinaryAssignment
); );
types.push_back(type(*component)); types.push_back(type(*component));
} }
@ -1534,6 +1534,7 @@ bool TypeChecker::visit(UnaryOperation const& _operation)
_operation.annotation().isConstant = false; _operation.annotation().isConstant = false;
_operation.annotation().isPure = !modifying && *_operation.subExpression().annotation().isPure; _operation.annotation().isPure = !modifying && *_operation.subExpression().annotation().isPure;
_operation.annotation().isLValue = false; _operation.annotation().isLValue = false;
return false; return false;
} }
@ -2391,6 +2392,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions)
_functionCallOptions.annotation().isPure = false; _functionCallOptions.annotation().isPure = false;
_functionCallOptions.annotation().isConstant = false; _functionCallOptions.annotation().isConstant = false;
_functionCallOptions.annotation().isLValue = false;
auto expressionFunctionType = dynamic_cast<FunctionType const*>(type(_functionCallOptions.expression())); auto expressionFunctionType = dynamic_cast<FunctionType const*>(type(_functionCallOptions.expression()));
if (!expressionFunctionType) if (!expressionFunctionType)
@ -2523,6 +2525,7 @@ void TypeChecker::endVisit(NewExpression const& _newExpression)
solAssert(!!type, "Type name not resolved."); solAssert(!!type, "Type name not resolved.");
_newExpression.annotation().isConstant = false; _newExpression.annotation().isConstant = false;
_newExpression.annotation().isLValue = false;
if (auto contractName = dynamic_cast<UserDefinedTypeName const*>(&_newExpression.typeName())) if (auto contractName = dynamic_cast<UserDefinedTypeName const*>(&_newExpression.typeName()))
{ {
@ -2583,7 +2586,10 @@ void TypeChecker::endVisit(NewExpression const& _newExpression)
_newExpression.annotation().isPure = true; _newExpression.annotation().isPure = true;
} }
else else
{
_newExpression.annotation().isPure = false;
m_errorReporter.fatalTypeError(8807_error, _newExpression.location(), "Contract or array type expected."); m_errorReporter.fatalTypeError(8807_error, _newExpression.location(), "Contract or array type expected.");
}
} }
bool TypeChecker::visit(MemberAccess const& _memberAccess) bool TypeChecker::visit(MemberAccess const& _memberAccess)
@ -2766,6 +2772,8 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
) )
annotation.isPure = *_memberAccess.expression().annotation().isPure; annotation.isPure = *_memberAccess.expression().annotation().isPure;
} }
else
annotation.isLValue = false;
} }
else if (exprType->category() == Type::Category::Module) else if (exprType->category() == Type::Category::Module)
{ {
@ -3061,6 +3069,7 @@ vector<Declaration const*> TypeChecker::cleanOverloadedDeclarations(
bool TypeChecker::visit(Identifier const& _identifier) bool TypeChecker::visit(Identifier const& _identifier)
{ {
IdentifierAnnotation& annotation = _identifier.annotation(); IdentifierAnnotation& annotation = _identifier.annotation();
if (!annotation.referencedDeclaration) if (!annotation.referencedDeclaration)
{ {
annotation.overloadedDeclarations = cleanOverloadedDeclarations(_identifier, annotation.candidateDeclarations); annotation.overloadedDeclarations = cleanOverloadedDeclarations(_identifier, annotation.candidateDeclarations);

View File

@ -253,7 +253,8 @@ struct ExpressionAnnotation: ASTAnnotation
bool willBeWrittenTo = false; bool willBeWrittenTo = false;
/// Whether the expression is an lvalue that is only assigned. /// Whether the expression is an lvalue that is only assigned.
/// Would be false for --, ++, delete, +=, -=, .... /// Would be false for --, ++, delete, +=, -=, ....
SetOnce<bool> lValueOfOrdinaryAssignment; /// Only relevant if isLvalue == true
bool lValueOfOrdinaryAssignment;
/// Types and - if given - names of arguments if the expr. is a function /// Types and - if given - names of arguments if the expr. is a function
/// that is called, used for overload resolution /// that is called, used for overload resolution

View File

@ -0,0 +1,11 @@
contract C {
function foo(uint x) public
{
// Used to cause an ICE
uint p = new uint[] = x;
}
}
// ----
// TypeError 4247: (100-110): Expression has to be an lvalue.
// TypeError 7407: (113-114): Type uint256 is not implicitly convertible to expected type function (uint256) pure returns (uint256[] memory).
// TypeError 9574: (91-114): Type function (uint256) pure returns (uint256[] memory) is not implicitly convertible to expected type uint256.