mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add missing checks for parameter compatibilty with ABIEncoderV1 in calls
This commit is contained in:
parent
25d408058b
commit
33ff79bf82
@ -11,6 +11,7 @@ Compiler Features:
|
||||
|
||||
Bugfixes:
|
||||
* 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.
|
||||
|
||||
|
||||
### 0.7.2 (2020-09-28)
|
||||
|
@ -2178,6 +2178,52 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
|
||||
m_errorReporter.typeError(errorId, paramArgMap[i]->location(), description);
|
||||
}
|
||||
}
|
||||
|
||||
TypePointers const& returnParameterTypes = _functionType->returnParameterTypes();
|
||||
bool isLibraryCall = (_functionType->kind() == FunctionType::Kind::DelegateCall);
|
||||
bool callRequiresABIEncoding =
|
||||
// ABIEncode/ABIDecode calls not included because they should have been already validated
|
||||
// at this point and they have variadic arguments so they need special handling.
|
||||
_functionType->kind() == FunctionType::Kind::DelegateCall ||
|
||||
_functionType->kind() == FunctionType::Kind::External ||
|
||||
_functionType->kind() == FunctionType::Kind::Creation ||
|
||||
_functionType->kind() == FunctionType::Kind::Event;
|
||||
|
||||
if (callRequiresABIEncoding && !experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2))
|
||||
{
|
||||
solAssert(!isVariadic, "");
|
||||
solAssert(parameterTypes.size() == arguments.size(), "");
|
||||
solAssert(!_functionType->isBareCall(), "");
|
||||
solAssert(*_functionCall.annotation().kind == FunctionCallKind::FunctionCall, "");
|
||||
|
||||
for (size_t i = 0; i < parameterTypes.size(); ++i)
|
||||
{
|
||||
solAssert(parameterTypes[i], "");
|
||||
|
||||
if (!typeSupportedByOldABIEncoder(*parameterTypes[i], isLibraryCall))
|
||||
m_errorReporter.typeError(
|
||||
2443_error,
|
||||
paramArgMap[i]->location(),
|
||||
"The type of this parameter, " + parameterTypes[i]->toString(true) + ", "
|
||||
"is only supported in ABIEncoderV2. "
|
||||
"Use \"pragma experimental ABIEncoderV2;\" to enable the feature."
|
||||
);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < returnParameterTypes.size(); ++i)
|
||||
{
|
||||
solAssert(returnParameterTypes[i], "");
|
||||
|
||||
if (!typeSupportedByOldABIEncoder(*returnParameterTypes[i], isLibraryCall))
|
||||
m_errorReporter.typeError(
|
||||
2428_error,
|
||||
_functionCall.location(),
|
||||
"The type of return parameter " + toString(i + 1) + ", " + returnParameterTypes[i]->toString(true) + ", "
|
||||
"is only supported in ABIEncoderV2. "
|
||||
"Use \"pragma experimental ABIEncoderV2;\" to enable the feature."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TypeChecker::visit(FunctionCall const& _functionCall)
|
||||
|
@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function set(Item storage _item) external view {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
L.Item item;
|
||||
|
||||
function foo() public view {
|
||||
L.set(item);
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
constructor(Item memory _item) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
new C(C.Item(5));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2443: (B:71-80): The type of this parameter, struct C.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function set(uint _x, string memory _y, Item memory _item, bool _z) external view {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
C(0x00).set({_item: C.Item(50), _z: false, _y: "abc", _x: 30});
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2443: (B:90-100): The type of this parameter, struct C.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
@ -0,0 +1,22 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get(Item memory _item) external {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
C c = new C();
|
||||
function(C.Item memory) external ptr = c.get;
|
||||
ptr(C.Item(5));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2443: (B:146-155): The type of this parameter, struct C.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
@ -0,0 +1,16 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f() external view returns (string[] memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract D {
|
||||
function g() public view {
|
||||
C(0x00).f();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:65-76): The type of return parameter 1, string[], is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
C(0x00).get();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:70-83): The type of return parameter 1, struct C.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint[] y;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
C(0x00).get();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:70-83): The type of return parameter 1, struct C.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
@ -0,0 +1,19 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
event E(Item _value);
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
emit L.E(L.Item(42));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2443: (B:74-84): The type of this parameter, struct L.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get(Item storage _item) external view {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
L.Item item;
|
||||
|
||||
function foo() public view {
|
||||
L.get(item);
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
L.get();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:70-77): The type of return parameter 1, struct L.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
@ -0,0 +1,13 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function get() public view returns (uint[][] memory) {}
|
||||
|
||||
function test() public view returns (bool) {
|
||||
uint[][] memory x = this.get();
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// ----
|
||||
// Warning 2072: (166-183): Unused local variable.
|
@ -0,0 +1,13 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function get() public view returns (uint[][] memory) {}
|
||||
|
||||
function test() public view returns (bool) {
|
||||
uint[][] memory x = this.get();
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: <byzantium
|
||||
// ----
|
||||
// TypeError 9574: (166-196): Type inaccessible dynamic type is not implicitly convertible to expected type uint256[] memory[] memory.
|
@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
constructor(Item memory _item) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
new C(C.Item(5));
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,23 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get(Item memory _item) external {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
C c = new C();
|
||||
function(C.Item memory) external ptr = c.get;
|
||||
ptr(C.Item(5));
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,17 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f() external view returns (string[] memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract D {
|
||||
function g() public view {
|
||||
C(0x00).f();
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
C(0x00).get();
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint[] y;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
C(0x00).get();
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
event E(Item _value);
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
emit L.E(L.Item(42));
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,25 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get(Item memory _item) external {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
// NOTE: This test checks a case that is currently not possible (pointer to an external
|
||||
// library function) but it might become possible in the future.
|
||||
function(L.Item memory) external ptr = L.get;
|
||||
ptr(L.Item(5));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9574: (B:269-313): Type function (struct L.Item memory) is not implicitly convertible to expected type function (struct L.Item memory) external.
|
@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
L.get();
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,30 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
struct Data {
|
||||
bool flag;
|
||||
}
|
||||
|
||||
contract A {
|
||||
function get() public view returns (Data memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract B {
|
||||
modifier validate() {
|
||||
A(0x00).get();
|
||||
_;
|
||||
}
|
||||
}
|
||||
==== Source: C ====
|
||||
import "B";
|
||||
|
||||
contract C is B {
|
||||
function foo()
|
||||
public
|
||||
validate()
|
||||
{}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:60-73): The type of return parameter 1, struct Data, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
@ -0,0 +1,32 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
struct Data {
|
||||
bool flag;
|
||||
}
|
||||
|
||||
contract A {
|
||||
function get() public view returns (Data memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract B {
|
||||
modifier validate() {
|
||||
A(0x00).get();
|
||||
_;
|
||||
}
|
||||
}
|
||||
==== Source: C ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "B";
|
||||
|
||||
contract C is B {
|
||||
function foo()
|
||||
public
|
||||
validate()
|
||||
{}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:60-73): The type of return parameter 1, struct Data, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
Loading…
Reference in New Issue
Block a user