Merge pull request #10004 from ethereum/fix-type-check-against-inheriting-functions-with-abiencoderv2-return-parameters

Add missing ABI compatibility check for return parameters in inherited functions
This commit is contained in:
chriseth 2020-10-12 15:40:43 +02:00 committed by GitHub
commit bc97c3e1ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 1 deletions

View File

@ -12,6 +12,7 @@ Bugfixes:
* Code generator: Fix ``ABIEncoderV2`` pragma from the current module affecting inherited functions and applied modifiers. * Code generator: Fix ``ABIEncoderV2`` pragma from the current module affecting inherited functions and applied modifiers.
* Type Checker: Fix internal compiler error caused by storage parameters with nested mappings in libraries. * Type Checker: Fix internal compiler error caused by storage parameters with nested mappings in libraries.
* Name Resolver: Fix shadowing/same-name warnings for later declarations. * Name Resolver: Fix shadowing/same-name warnings for later declarations.
* Contract Level Checker: Add missing check against inheriting functions with ABIEncoderV2 return types in ABIEncoderV1 contracts.
### 0.7.3 (2020-10-07) ### 0.7.3 (2020-10-07)

View File

@ -119,6 +119,13 @@ decoding types only supported by the new encoder. The compiler can detect this
and will issue an error. Simply enabling ``ABIEncoderV2`` for your contract is and will issue an error. Simply enabling ``ABIEncoderV2`` for your contract is
enough to make the error go away. enough to make the error go away.
.. note::
This pragma applies to all the code defined in the file where it is activated,
regardless of where that code ends up eventually. This means that a contract
without the ``ABIEncoderV2`` pragma can still contain code that uses the new encoder
by inheriting it from another contract. This is allowed if the new types are only
used internally and not in external function signatures.
.. _smt_checker: .. _smt_checker:
SMTChecker SMTChecker

View File

@ -474,7 +474,7 @@ void ContractLevelChecker::checkBaseABICompatibility(ContractDefinition const& _
auto const& currentLoc = func.second->declaration().location(); auto const& currentLoc = func.second->declaration().location();
for (TypePointer const& paramType: func.second->parameterTypes() + func.second->parameterTypes()) for (TypePointer const& paramType: func.second->parameterTypes() + func.second->returnParameterTypes())
if (!TypeChecker::typeSupportedByOldABIEncoder(*paramType, false)) if (!TypeChecker::typeSupportedByOldABIEncoder(*paramType, false))
{ {
errors.append("Type only supported by ABIEncoderV2", currentLoc); errors.append("Type only supported by ABIEncoderV2", currentLoc);

View File

@ -0,0 +1,15 @@
==== Source: A ====
pragma experimental ABIEncoderV2;
struct Item {
uint x;
}
contract C {
event Ev(Item);
}
==== Source: B ====
import "A";
contract D is C {}
// ----

View File

@ -0,0 +1,16 @@
==== Source: A ====
pragma experimental ABIEncoderV2;
contract C {
struct Item {
uint x;
}
function get(Item memory) external view {}
}
==== Source: B ====
import "A";
contract D is C {}
// ----
// TypeError 6594: (B:13-31): Contract "D" does not use ABIEncoderV2 but wants to inherit from a contract which uses types that require it. Use "pragma experimental ABIEncoderV2;" for the inheriting contract as well to enable the feature.

View File

@ -0,0 +1,16 @@
==== Source: A ====
pragma experimental ABIEncoderV2;
contract C {
struct Item {
uint x;
}
function get() external view returns(Item memory) {}
}
==== Source: B ====
import "A";
contract D is C {}
// ----
// TypeError 6594: (B:13-31): Contract "D" does not use ABIEncoderV2 but wants to inherit from a contract which uses types that require it. Use "pragma experimental ABIEncoderV2;" for the inheriting contract as well to enable the feature.