mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #13279 from timweri/nested-tuple-oor-fix
This commit is contained in:
commit
19ad8b115e
@ -14,6 +14,7 @@ Bugfixes:
|
|||||||
* Commandline Interface: Disallow the following options outside of the compiler mode: ``--via-ir``,``--metadata-literal``, ``--metadata-hash``, ``--model-checker-show-unproved``, ``--model-checker-div-mod-no-slacks``, ``--model-checker-engine``, ``--model-checker-invariants``, ``--model-checker-solvers``, ``--model-checker-timeout``, ``--model-checker-contracts``, ``--model-checker-targets``.
|
* Commandline Interface: Disallow the following options outside of the compiler mode: ``--via-ir``,``--metadata-literal``, ``--metadata-hash``, ``--model-checker-show-unproved``, ``--model-checker-div-mod-no-slacks``, ``--model-checker-engine``, ``--model-checker-invariants``, ``--model-checker-solvers``, ``--model-checker-timeout``, ``--model-checker-contracts``, ``--model-checker-targets``.
|
||||||
* Type Checker: Fix null dereference in `abi.encodeCall` type checking of free function.
|
* Type Checker: Fix null dereference in `abi.encodeCall` type checking of free function.
|
||||||
* Type Checker: Fix compiler crash when `abi.encodeCall` received a tuple expression instead of an inline tuple.
|
* Type Checker: Fix compiler crash when `abi.encodeCall` received a tuple expression instead of an inline tuple.
|
||||||
|
* Type Checker: Fix compiler crash on tuple assignments involving certain patterns with unary tuples on the left-hand side.
|
||||||
|
|
||||||
|
|
||||||
### 0.8.15 (2022-06-15)
|
### 0.8.15 (2022-06-15)
|
||||||
|
@ -112,8 +112,9 @@ void TypeChecker::checkDoubleStorageAssignment(Assignment const& _assignment)
|
|||||||
size_t storageByteAccesses = 0;
|
size_t storageByteAccesses = 0;
|
||||||
auto count = [&](TupleExpression const& _lhs, TupleType const& _rhs, auto _recurse) -> void {
|
auto count = [&](TupleExpression const& _lhs, TupleType const& _rhs, auto _recurse) -> void {
|
||||||
TupleType const& lhsType = dynamic_cast<TupleType const&>(*type(_lhs));
|
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())
|
if (lhsType.components().size() != _rhs.components().size() || lhsResolved->components().size() != _rhs.components().size())
|
||||||
{
|
{
|
||||||
solAssert(m_errorReporter.hasErrors(), "");
|
solAssert(m_errorReporter.hasErrors(), "");
|
||||||
return;
|
return;
|
||||||
@ -134,7 +135,7 @@ void TypeChecker::checkDoubleStorageAssignment(Assignment const& _assignment)
|
|||||||
{
|
{
|
||||||
if (bytesType && bytesType->numBytes() == 1)
|
if (bytesType && bytesType->numBytes() == 1)
|
||||||
{
|
{
|
||||||
if (FunctionCall const* lhsCall = dynamic_cast<FunctionCall const*>(resolveOuterUnaryTuples(_lhs.components().at(index).get())))
|
if (FunctionCall const* lhsCall = dynamic_cast<FunctionCall const*>(resolveOuterUnaryTuples(lhsResolved->components().at(index).get())))
|
||||||
{
|
{
|
||||||
FunctionType const& callType = dynamic_cast<FunctionType const&>(*type(lhsCall->expression()));
|
FunctionType const& callType = dynamic_cast<FunctionType const&>(*type(lhsCall->expression()));
|
||||||
if (callType.kind() == FunctionType::Kind::ArrayPush)
|
if (callType.kind() == FunctionType::Kind::ArrayPush)
|
||||||
@ -147,7 +148,7 @@ void TypeChecker::checkDoubleStorageAssignment(Assignment const& _assignment)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IndexAccess const* indexAccess = dynamic_cast<IndexAccess const*>(resolveOuterUnaryTuples(_lhs.components().at(index).get())))
|
else if (IndexAccess const* indexAccess = dynamic_cast<IndexAccess const*>(resolveOuterUnaryTuples(lhsResolved->components().at(index).get())))
|
||||||
{
|
{
|
||||||
if (ArrayType const* arrayType = dynamic_cast<ArrayType const*>(type(indexAccess->baseExpression())))
|
if (ArrayType const* arrayType = dynamic_cast<ArrayType const*>(type(indexAccess->baseExpression())))
|
||||||
if (arrayType->isByteArray() && arrayType->dataStoredIn(DataLocation::Storage))
|
if (arrayType->isByteArray() && arrayType->dataStoredIn(DataLocation::Storage))
|
||||||
@ -156,7 +157,7 @@ void TypeChecker::checkDoubleStorageAssignment(Assignment const& _assignment)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (TupleType const* tupleType = dynamic_cast<TupleType const*>(componentType))
|
else if (TupleType const* tupleType = dynamic_cast<TupleType const*>(componentType))
|
||||||
if (auto const* lhsNested = dynamic_cast<TupleExpression const*>(_lhs.components().at(index).get()))
|
if (auto const* lhsNested = dynamic_cast<TupleExpression const*>(lhsResolved->components().at(index).get()))
|
||||||
if (auto const* rhsNestedType = dynamic_cast<TupleType const*>(_rhs.components().at(index)))
|
if (auto const* rhsNestedType = dynamic_cast<TupleType const*>(_rhs.components().at(index)))
|
||||||
_recurse(
|
_recurse(
|
||||||
*lhsNested,
|
*lhsNested,
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
function f() pure {
|
||||||
|
((, ())) = (1, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
function g() pure {
|
||||||
|
((, ((, ())))) = (1, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
function t() pure returns (int, int) {
|
||||||
|
return (4, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
function h() pure {
|
||||||
|
((, ())) = t();
|
||||||
|
}
|
||||||
|
|
||||||
|
function ff() pure {
|
||||||
|
((((, ())) , )) = ((1, 2), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fg() pure {
|
||||||
|
(((, ())) , ) = ((1, 2), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// TypeError 5547: (28-30): Empty tuple on the left hand side.
|
||||||
|
// TypeError 7407: (35-41): Type tuple(int_const 1,int_const 3) is not implicitly convertible to expected type tuple(,tuple()).
|
||||||
|
// TypeError 5547: (78-80): Empty tuple on the left hand side.
|
||||||
|
// TypeError 7407: (87-93): Type tuple(int_const 1,int_const 3) is not implicitly convertible to expected type tuple(,tuple(,tuple())).
|
||||||
|
// TypeError 5547: (187-189): Empty tuple on the left hand side.
|
||||||
|
// TypeError 7407: (194-197): Type tuple(int256,int256) is not implicitly convertible to expected type tuple(,tuple()).
|
||||||
|
// TypeError 5547: (233-235): Empty tuple on the left hand side.
|
||||||
|
// TypeError 7407: (245-256): Type tuple(tuple(int_const 1,int_const 2),int_const 3) is not implicitly convertible to expected type tuple(tuple(,tuple()),).
|
||||||
|
// TypeError 5547: (291-293): Empty tuple on the left hand side.
|
||||||
|
// TypeError 7407: (302-313): Type tuple(tuple(int_const 1,int_const 2),int_const 3) is not implicitly convertible to expected type tuple(tuple(,tuple()),).
|
@ -0,0 +1,7 @@
|
|||||||
|
contract A {
|
||||||
|
function f() pure public {
|
||||||
|
bytes1 b;
|
||||||
|
bytes1 a;
|
||||||
|
(((, , b))) = (1, 2, a);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user