Skip to content

Commit 45668fd

Browse files
authored
Merge pull request #9953 from ethereum/issue-9952
Add missing lValue assignment
2 parents 22caed1 + 6114cd8 commit 45668fd

File tree

5 files changed

+25
-3
lines changed

5 files changed

+25
-3
lines changed

Diff for: Changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Compiler Features:
1515
Bugfixes:
1616
* Type Checker: Fix internal compiler error when calling `.push(<arg>)` for a storage array with a nested mapping.
1717
* Type Checker: Add missing checks for calls using types incompatible with ABIEncoderV1 in modules where ABIEncoderV2 is not enabled.
18+
* Fixed internal compiler errors for certain contracts involving the ``new`` expression
1819

1920

2021
### 0.7.2 (2020-09-28)

Diff for: libsolidity/analysis/ImmutableValidator.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ void ImmutableValidator::analyseVariableReference(VariableDeclaration const& _va
167167

168168
// If this is not an ordinary assignment, we write and read at the same time.
169169
bool write = _expression.annotation().willBeWrittenTo;
170-
bool read = !_expression.annotation().willBeWrittenTo || !*_expression.annotation().lValueOfOrdinaryAssignment;
170+
bool read = !_expression.annotation().willBeWrittenTo || !_expression.annotation().lValueOfOrdinaryAssignment;
171171
if (write)
172172
{
173173
if (!m_currentConstructor)

Diff for: libsolidity/analysis/TypeChecker.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -1420,7 +1420,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
14201420
{
14211421
requireLValue(
14221422
*component,
1423-
*_tuple.annotation().lValueOfOrdinaryAssignment
1423+
_tuple.annotation().lValueOfOrdinaryAssignment
14241424
);
14251425
types.push_back(type(*component));
14261426
}
@@ -1534,6 +1534,7 @@ bool TypeChecker::visit(UnaryOperation const& _operation)
15341534
_operation.annotation().isConstant = false;
15351535
_operation.annotation().isPure = !modifying && *_operation.subExpression().annotation().isPure;
15361536
_operation.annotation().isLValue = false;
1537+
15371538
return false;
15381539
}
15391540

@@ -2391,6 +2392,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions)
23912392

23922393
_functionCallOptions.annotation().isPure = false;
23932394
_functionCallOptions.annotation().isConstant = false;
2395+
_functionCallOptions.annotation().isLValue = false;
23942396

23952397
auto expressionFunctionType = dynamic_cast<FunctionType const*>(type(_functionCallOptions.expression()));
23962398
if (!expressionFunctionType)
@@ -2523,6 +2525,7 @@ void TypeChecker::endVisit(NewExpression const& _newExpression)
25232525
solAssert(!!type, "Type name not resolved.");
25242526

25252527
_newExpression.annotation().isConstant = false;
2528+
_newExpression.annotation().isLValue = false;
25262529

25272530
if (auto contractName = dynamic_cast<UserDefinedTypeName const*>(&_newExpression.typeName()))
25282531
{
@@ -2583,7 +2586,10 @@ void TypeChecker::endVisit(NewExpression const& _newExpression)
25832586
_newExpression.annotation().isPure = true;
25842587
}
25852588
else
2589+
{
2590+
_newExpression.annotation().isPure = false;
25862591
m_errorReporter.fatalTypeError(8807_error, _newExpression.location(), "Contract or array type expected.");
2592+
}
25872593
}
25882594

25892595
bool TypeChecker::visit(MemberAccess const& _memberAccess)
@@ -2766,6 +2772,8 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
27662772
)
27672773
annotation.isPure = *_memberAccess.expression().annotation().isPure;
27682774
}
2775+
else
2776+
annotation.isLValue = false;
27692777
}
27702778
else if (exprType->category() == Type::Category::Module)
27712779
{
@@ -3061,6 +3069,7 @@ vector<Declaration const*> TypeChecker::cleanOverloadedDeclarations(
30613069
bool TypeChecker::visit(Identifier const& _identifier)
30623070
{
30633071
IdentifierAnnotation& annotation = _identifier.annotation();
3072+
30643073
if (!annotation.referencedDeclaration)
30653074
{
30663075
annotation.overloadedDeclarations = cleanOverloadedDeclarations(_identifier, annotation.candidateDeclarations);

Diff for: libsolidity/ast/ASTAnnotations.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@ struct ExpressionAnnotation: ASTAnnotation
253253
bool willBeWrittenTo = false;
254254
/// Whether the expression is an lvalue that is only assigned.
255255
/// Would be false for --, ++, delete, +=, -=, ....
256-
SetOnce<bool> lValueOfOrdinaryAssignment;
256+
/// Only relevant if isLvalue == true
257+
bool lValueOfOrdinaryAssignment;
257258

258259
/// Types and - if given - names of arguments if the expr. is a function
259260
/// that is called, used for overload resolution
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
contract C {
2+
function foo(uint x) public
3+
{
4+
// Used to cause an ICE
5+
uint p = new uint[] = x;
6+
}
7+
}
8+
// ----
9+
// TypeError 4247: (100-110): Expression has to be an lvalue.
10+
// TypeError 7407: (113-114): Type uint256 is not implicitly convertible to expected type function (uint256) pure returns (uint256[] memory).
11+
// TypeError 9574: (91-114): Type function (uint256) pure returns (uint256[] memory) is not implicitly convertible to expected type uint256.

0 commit comments

Comments
 (0)