mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #13299 from ethereum/fix-bad-cast-tuple-returned-from-function-abi-encodeCall
Fix bad_cast when abi.encodeCall() receives a tuple expression
This commit is contained in:
commit
c9f772eba8
@ -13,6 +13,7 @@ Compiler Features:
|
||||
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``.
|
||||
* 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.
|
||||
|
||||
|
||||
### 0.8.15 (2022-06-15)
|
||||
|
@ -2248,8 +2248,17 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
|
||||
auto const* tupleType = dynamic_cast<TupleType const*>(type(*arguments[1]));
|
||||
if (tupleType)
|
||||
{
|
||||
auto const& argumentTuple = dynamic_cast<TupleExpression const&>(*arguments[1].get());
|
||||
callArguments = decltype(callArguments){argumentTuple.components().begin(), argumentTuple.components().end()};
|
||||
if (TupleExpression const* argumentTuple = dynamic_cast<TupleExpression const*>(arguments[1].get()))
|
||||
callArguments = decltype(callArguments){argumentTuple->components().begin(), argumentTuple->components().end()};
|
||||
else
|
||||
{
|
||||
m_errorReporter.typeError(
|
||||
9062_error,
|
||||
arguments[1]->location(),
|
||||
"Expected an inline tuple, not an expression of a tuple type."
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
callArguments.push_back(arguments[1]);
|
||||
|
@ -0,0 +1,24 @@
|
||||
contract C {
|
||||
function g0() internal pure {}
|
||||
function g2() internal pure returns (uint, uint) { return (2, 3); }
|
||||
|
||||
function f0() public {}
|
||||
function f2(uint, uint) public {}
|
||||
|
||||
function h() public view {
|
||||
uint a;
|
||||
uint b;
|
||||
|
||||
abi.encodeCall(this.f0, () = g0());
|
||||
abi.encodeCall(this.f0, () = ());
|
||||
abi.encodeCall(this.f2, (a, b) = g2());
|
||||
abi.encodeCall(this.f2, (a, b) = (2, 3));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 5547: (284-286): Empty tuple on the left hand side.
|
||||
// TypeError 9062: (284-293): Expected an inline tuple, not an expression of a tuple type.
|
||||
// TypeError 5547: (328-330): Empty tuple on the left hand side.
|
||||
// TypeError 9062: (328-335): Expected an inline tuple, not an expression of a tuple type.
|
||||
// TypeError 9062: (370-383): Expected an inline tuple, not an expression of a tuple type.
|
||||
// TypeError 9062: (418-433): Expected an inline tuple, not an expression of a tuple type.
|
@ -0,0 +1,17 @@
|
||||
contract C {
|
||||
function g0() internal pure {}
|
||||
function g2() internal pure returns (uint, uint) { return (2, 3); }
|
||||
|
||||
function f0() public {}
|
||||
function f2(uint, uint) public {}
|
||||
|
||||
function h() public view {
|
||||
abi.encodeCall(this.f0, true ? g0() : g0());
|
||||
abi.encodeCall(this.f2, true ? g2() : g2());
|
||||
abi.encodeCall(this.f2, true ? (1, 2) : (3, 4));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9062: (251-269): Expected an inline tuple, not an expression of a tuple type.
|
||||
// TypeError 9062: (304-322): Expected an inline tuple, not an expression of a tuple type.
|
||||
// TypeError 9062: (357-379): Expected an inline tuple, not an expression of a tuple type.
|
@ -0,0 +1,16 @@
|
||||
contract C {
|
||||
event Ev();
|
||||
error Er();
|
||||
|
||||
function f0() public {}
|
||||
|
||||
function h() public view {
|
||||
abi.encodeCall(this.f0, Ev());
|
||||
abi.encodeCall(this.f0, Er());
|
||||
abi.encodeCall(this.f0, revert());
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9062: (138-142): Expected an inline tuple, not an expression of a tuple type.
|
||||
// TypeError 9062: (177-181): Expected an inline tuple, not an expression of a tuple type.
|
||||
// TypeError 9062: (216-224): Expected an inline tuple, not an expression of a tuple type.
|
@ -0,0 +1,23 @@
|
||||
contract C {
|
||||
event Ev();
|
||||
error Er();
|
||||
|
||||
function g0() internal pure {}
|
||||
function g2() internal pure returns (uint, uint) { return (2, 3); }
|
||||
|
||||
function f0() public {}
|
||||
function f2(uint, uint) public {}
|
||||
|
||||
function h() public view {
|
||||
abi.encodeCall(this.f2, (1, 1) + (2, 2));
|
||||
abi.encodeCall(this.f0, Ev() / Er());
|
||||
abi.encodeCall(this.f0, !());
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2271: (284-299): Operator + not compatible with types tuple(int_const 1,int_const 1) and tuple(int_const 2,int_const 2)
|
||||
// TypeError 9062: (284-299): Expected an inline tuple, not an expression of a tuple type.
|
||||
// TypeError 2271: (334-345): Operator / not compatible with types tuple() and tuple()
|
||||
// TypeError 9062: (334-345): Expected an inline tuple, not an expression of a tuple type.
|
||||
// TypeError 4907: (380-383): Unary operator ! cannot be applied to type tuple()
|
||||
// TypeError 9062: (380-383): Expected an inline tuple, not an expression of a tuple type.
|
@ -0,0 +1,22 @@
|
||||
contract C {
|
||||
function g0() internal pure {}
|
||||
function g2() internal pure returns (uint, uint) { return (2, 3); }
|
||||
|
||||
function f0() public {}
|
||||
function f2(uint, uint) public {}
|
||||
|
||||
function h() public view {
|
||||
abi.encodeCall(this.f0, g0());
|
||||
abi.encodeCall(this.f2, g2());
|
||||
|
||||
abi.encodeCall(this.f0, (g0()));
|
||||
abi.encodeCall(this.f2, (g2()));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9062: (251-255): Expected an inline tuple, not an expression of a tuple type.
|
||||
// TypeError 9062: (290-294): Expected an inline tuple, not an expression of a tuple type.
|
||||
// TypeError 6473: (331-335): Tuple component cannot be empty.
|
||||
// TypeError 7788: (306-337): Expected 0 instead of 1 components for the tuple parameter.
|
||||
// TypeError 7788: (347-378): Expected 2 instead of 1 components for the tuple parameter.
|
||||
// TypeError 5407: (372-376): Cannot implicitly convert component at position 0 from "tuple(uint256,uint256)" to "uint256".
|
@ -0,0 +1,13 @@
|
||||
contract C {
|
||||
function g1() internal pure returns (uint) { return (1); }
|
||||
|
||||
function f1(uint) public {}
|
||||
|
||||
function h() public view {
|
||||
uint a;
|
||||
|
||||
abi.encodeCall(this.f1, (a) = g1());
|
||||
abi.encodeCall(this.f1, (a) = (1));
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function g1() internal pure returns (uint) { return (1); }
|
||||
|
||||
function f1(uint) public {}
|
||||
|
||||
function h() public view {
|
||||
abi.encodeCall(this.f1, true ? (1) : (2));
|
||||
abi.encodeCall(this.f1, true ? g1() : g1());
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,14 @@
|
||||
contract C {
|
||||
function g1() internal pure returns (uint) { return (1); }
|
||||
function g2() internal pure returns (uint, uint) { return (2, 3); }
|
||||
|
||||
function f1(uint) public {}
|
||||
function f2(uint, uint) public {}
|
||||
|
||||
function h() public view {
|
||||
abi.encodeCall(this.f1, g1());
|
||||
abi.encodeCall(this.f1, (g1()));
|
||||
abi.encodeCall(this.f2, (g1(), g1()));
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,15 @@
|
||||
contract C {
|
||||
function g0() internal pure {}
|
||||
function g1() internal pure returns (uint) { return (1); }
|
||||
function g2() internal pure returns (uint, uint) { return (2, 3); }
|
||||
|
||||
function h() public pure {
|
||||
abi.encodePacked(g0());
|
||||
abi.encodePacked(g2());
|
||||
abi.encodePacked((g1(), g1()));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2056: (240-244): This type cannot be encoded.
|
||||
// TypeError 2056: (272-276): This type cannot be encoded.
|
||||
// TypeError 2056: (304-316): This type cannot be encoded.
|
@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
function g1() internal pure returns (uint) { return (1); }
|
||||
|
||||
function h() public pure {
|
||||
abi.encodePacked(g1());
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,19 @@
|
||||
contract C {
|
||||
function g0() internal pure {}
|
||||
function g1() internal pure returns (uint) { return (1); }
|
||||
function g2() internal pure returns (uint, uint) { return (2, 3); }
|
||||
|
||||
function f0() public {}
|
||||
function f1(uint) public {}
|
||||
function f2(uint, uint) public {}
|
||||
|
||||
function h() public pure {
|
||||
abi.encodeWithSelector(this.f0.selector, g0());
|
||||
abi.encodeWithSelector(this.f0.selector, g2());
|
||||
abi.encodeWithSelector(this.f0.selector, (g1(), g1()));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2056: (363-367): This type cannot be encoded.
|
||||
// TypeError 2056: (419-423): This type cannot be encoded.
|
||||
// TypeError 2056: (475-487): This type cannot be encoded.
|
@ -0,0 +1,10 @@
|
||||
contract C {
|
||||
function g1() internal pure returns (uint) { return (1); }
|
||||
|
||||
function f0() public {}
|
||||
|
||||
function h() public pure {
|
||||
abi.encodeWithSelector(this.f0.selector, g1());
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,15 @@
|
||||
contract C {
|
||||
function g0() internal pure {}
|
||||
function g1() internal pure returns (uint) { return (1); }
|
||||
function g2() internal pure returns (uint, uint) { return (2, 3); }
|
||||
|
||||
function h() public pure {
|
||||
abi.encodeWithSignature("f0()", g0());
|
||||
abi.encodeWithSignature("f()", g2());
|
||||
abi.encodeWithSignature("f()", (g1(), g1()));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2056: (255-259): This type cannot be encoded.
|
||||
// TypeError 2056: (301-305): This type cannot be encoded.
|
||||
// TypeError 2056: (347-359): This type cannot be encoded.
|
@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
function g1() internal pure returns (uint) { return (1); }
|
||||
|
||||
function h() public pure {
|
||||
abi.encodeWithSignature("f()", g1());
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,15 @@
|
||||
contract C {
|
||||
function g0() internal pure {}
|
||||
function g1() internal pure returns (uint) { return (1); }
|
||||
function g2() internal pure returns (uint, uint) { return (2, 3); }
|
||||
|
||||
function h() public pure {
|
||||
abi.encode(g0());
|
||||
abi.encode(g2());
|
||||
abi.encode((g1(), g1()));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2056: (234-238): This type cannot be encoded.
|
||||
// TypeError 2056: (260-264): This type cannot be encoded.
|
||||
// TypeError 2056: (286-298): This type cannot be encoded.
|
@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
function g1() internal pure returns (uint) { return (1); }
|
||||
|
||||
function h() public pure {
|
||||
abi.encode(g1());
|
||||
}
|
||||
}
|
||||
// ----
|
Loading…
Reference in New Issue
Block a user