Exclude internal functions in library ABIs

This commit is contained in:
Mathias Baumann 2019-03-05 14:55:04 +01:00
parent 189983a1b8
commit fbbd03dbd7
3 changed files with 31 additions and 28 deletions

View File

@ -15,6 +15,7 @@ Compiler Features:
Bugfixes:
* JSON ABI: Json description of library ABIs no longer contain functions with internal types like storage structs.
* SMTChecker: Fix internal compiler error when contract contains too large rational number.
* Type system: Detect if a contract's base uses types that require the experimental abi encoder while the contract still uses the old encoder
* Yul Optimizer: Fix visitation order bug for the structural simplifier.
@ -24,7 +25,6 @@ Build System:
* Soltest: Add support for arrays in function signatures.
* Soltest: Add support for struct arrays in function signatures.
### 0.5.5 (2019-03-05)
Language Features:

View File

@ -26,12 +26,31 @@ using namespace std;
using namespace dev;
using namespace dev::solidity;
namespace
{
bool anyDataStoredInStorage(TypePointers const& _pointers)
{
for (TypePointer const& pointer: _pointers)
if (pointer->dataStoredIn(DataLocation::Storage))
return true;
return false;
}
}
Json::Value ABI::generate(ContractDefinition const& _contractDef)
{
Json::Value abi(Json::arrayValue);
for (auto it: _contractDef.interfaceFunctions())
{
if (
_contractDef.isLibrary() &&
(it.second->stateMutability() > StateMutability::View ||
anyDataStoredInStorage(it.second->parameterTypes() + it.second->returnParameterTypes()))
)
continue;
auto externalFunctionType = it.second->interfaceFunctionType();
solAssert(!!externalFunctionType, "");
Json::Value method;

View File

@ -755,24 +755,23 @@ BOOST_AUTO_TEST_CASE(library_function)
library test {
struct StructType { uint a; }
function f(StructType storage b, uint[] storage c, test d) public returns (uint[] memory e, StructType storage f) { f = f; }
function f1(uint[] memory c, test d) public pure returns (uint[] memory e) { }
}
)";
char const* interface = R"(
[
{
"constant" : false,
"constant" : true,
"payable" : false,
"stateMutability": "nonpayable",
"name": "f",
"stateMutability": "pure",
"name": "f1",
"inputs": [
{ "name": "b", "type": "test.StructType storage" },
{ "name": "c", "type": "uint256[] storage" },
{ "name": "c", "type": "uint256[]" },
{ "name": "d", "type": "test" }
],
"outputs": [
{ "name": "e", "type": "uint256[]" },
{ "name": "f", "type": "test.StructType storage" }
{ "name": "e", "type": "uint256[]" }
],
"type" : "function"
}
@ -1040,13 +1039,13 @@ BOOST_AUTO_TEST_CASE(structs_in_libraries)
library L {
struct S { uint a; T[] sub; bytes b; }
struct T { uint[2] x; }
function f(L.S storage s) public {}
function g(L.S memory s) public {}
function f(L.S storage s) public view {}
function g(L.S memory s) public view {}
}
)";
char const* interface = R"(
[{
"constant": false,
"constant": true,
"inputs": [
{
"components": [
@ -1076,24 +1075,9 @@ BOOST_AUTO_TEST_CASE(structs_in_libraries)
"name": "g",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "s",
"type": "L.S storage"
}
],
"name": "f",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}]
)";
}])";
checkInterface(sourceCode, "L", interface);
}