Skip to content

Commit

Permalink
Fix segmentation fault when assigning to a parenthesized non-tuple ex…
Browse files Browse the repository at this point in the history
…pression of a tuple type

Co-authored-by: Kamil Śliwak <kamil.sliwak@codepoets.it>
  • Loading branch information
r0qs and cameel committed May 14, 2024
1 parent d116a34 commit 3b4d9bb
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 1 deletion.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Bugfixes:
* SMTChecker: Fix internal error when using bitwise operators with an array element as argument.
* Standard JSON Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``optimizerSteps`` sequence.
* StaticAnalyzer: Only raise a compile time error for division and modulo by zero when it's between literals.
* TypeChecker: Fix compiler crash when the left-hand side of an assignment was a parenthesized non-tuple expression of a tuple type.
* Yul Optimizer: Fix the order of assignments generated by ``SSATransform`` being dependent on AST IDs, sometimes resulting in different (but equivalent) bytecode when unrelated files were added to the compilation pipeline.


Expand Down
3 changes: 2 additions & 1 deletion libsolidity/analysis/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ void TypeChecker::checkDoubleStorageAssignment(Assignment const& _assignment)
TupleType const& lhsType = dynamic_cast<TupleType const&>(*type(_lhs));
TupleExpression const* lhsResolved = dynamic_cast<TupleExpression const*>(resolveOuterUnaryTuples(&_lhs));

if (lhsType.components().size() != _rhs.components().size() || lhsResolved->components().size() != _rhs.components().size())
solAssert(!lhsResolved || lhsResolved->components().size() == lhsType.components().size());
if (lhsType.components().size() != _rhs.components().size())
{
solAssert(m_errorReporter.hasErrors(), "");
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
contract C {
uint[] public array;

function f() public {
// (f()) is not a tuple expression, but its value is a tuple.
(f()) = ();
}

function g() public {
// (revert()) is not a tuple expression, but its value is a tuple.
(revert()) = ();
}

function h() internal returns (uint, uint) {}

function i() public {
// (h()) is not a tuple expression, but its value is a tuple (uint, uint).
(h()) = (1, 1);
}

function j() public returns (uint, uint) {
// (j()) is not a tuple expression, but its value is a tuple (uint, uint).
(j()) = (1, 1);
}

function m() public {
// (uint x, uint y) is a tuple expression, and its value is a tuple (uint, uint).
(uint x, uint y) = (1, 1);
}

function n() public {
// ((array.push(), array.push())) is a tuple expression of a tuple expression, and its value is a tuple (pointer uint, pointer uint).
((array.push(), array.push())) = (1, 1);
}
}
// ----
// TypeError 4247: (126-129): Expression has to be an lvalue.
// TypeError 4247: (236-244): Expression has to be an lvalue.
// TypeError 4247: (407-410): Expression has to be an lvalue.
// TypeError 4247: (550-553): Expression has to be an lvalue.

0 comments on commit 3b4d9bb

Please sign in to comment.