Merge pull request #7851 from ethereum/smt_fix_function_type

[SMTChecker] Fix ICE for arrays and mappings of functions.
This commit is contained in:
Leonardo 2019-11-30 13:15:08 +01:00 committed by GitHub
commit a7d481fb94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 48 additions and 2 deletions

View File

@ -17,6 +17,7 @@ Build System:
Bugfixes: Bugfixes:
* SMTChecker: Fix internal error when using ``abi.decode``. * SMTChecker: Fix internal error when using ``abi.decode``.
* SMTChecker: Fix internal error when using arrays or mappings of functions.

View File

@ -63,7 +63,7 @@ SortPointer smtSort(solidity::Type const& _type)
{ {
auto mapType = dynamic_cast<solidity::MappingType const*>(&_type); auto mapType = dynamic_cast<solidity::MappingType const*>(&_type);
solAssert(mapType, ""); solAssert(mapType, "");
return make_shared<ArraySort>(smtSort(*mapType->keyType()), smtSort(*mapType->valueType())); return make_shared<ArraySort>(smtSortAbstractFunction(*mapType->keyType()), smtSortAbstractFunction(*mapType->valueType()));
} }
else if (isStringLiteral(_type.category())) else if (isStringLiteral(_type.category()))
{ {
@ -77,7 +77,7 @@ SortPointer smtSort(solidity::Type const& _type)
solAssert(isArray(_type.category()), ""); solAssert(isArray(_type.category()), "");
auto arrayType = dynamic_cast<solidity::ArrayType const*>(&_type); auto arrayType = dynamic_cast<solidity::ArrayType const*>(&_type);
solAssert(arrayType, ""); solAssert(arrayType, "");
return make_shared<ArraySort>(make_shared<Sort>(Kind::Int), smtSort(*arrayType->baseType())); return make_shared<ArraySort>(make_shared<Sort>(Kind::Int), smtSortAbstractFunction(*arrayType->baseType()));
} }
} }
default: default:
@ -94,6 +94,13 @@ vector<SortPointer> smtSort(vector<solidity::TypePointer> const& _types)
return sorts; return sorts;
} }
SortPointer smtSortAbstractFunction(solidity::Type const& _type)
{
if (isFunction(_type.category()))
return make_shared<Sort>(Kind::Int);
return smtSort(_type);
}
Kind smtKind(solidity::Type::Category _category) Kind smtKind(solidity::Type::Category _category)
{ {
if (isNumber(_category)) if (isNumber(_category))

View File

@ -32,6 +32,9 @@ namespace smt
/// Returns the SMT sort that models the Solidity type _type. /// Returns the SMT sort that models the Solidity type _type.
SortPointer smtSort(solidity::Type const& _type); SortPointer smtSort(solidity::Type const& _type);
std::vector<SortPointer> smtSort(std::vector<solidity::TypePointer> const& _types); std::vector<SortPointer> smtSort(std::vector<solidity::TypePointer> const& _types);
/// If _type has type Function, abstract it to Integer.
/// Otherwise return smtSort(_type).
SortPointer smtSortAbstractFunction(solidity::Type const& _type);
/// Returns the SMT kind that models the Solidity type type category _category. /// Returns the SMT kind that models the Solidity type type category _category.
Kind smtKind(solidity::Type::Category _category); Kind smtKind(solidity::Type::Category _category);

View File

@ -0,0 +1,5 @@
pragma experimental SMTChecker;
library L {
struct Nested { uint y; }
function c(function(Nested memory) external returns (uint)[] storage) external pure {}
}

View File

@ -0,0 +1,9 @@
pragma experimental SMTChecker;
contract C {
struct Nested { uint y; }
// ensure that we consider array of function pointers as reference type
function b(function(Nested memory) external returns (uint)[] storage) internal pure {}
function c(function(Nested memory) external returns (uint)[] memory) public pure {}
function d(function(Nested memory) external returns (uint)[] calldata) external pure {}
}
// ----

View File

@ -0,0 +1,14 @@
pragma experimental SMTChecker;
contract C {
function(uint) external returns (uint)[] public x;
function(uint) internal returns (uint)[10] y;
function f() view public {
function(uint) returns (uint)[10] memory a;
function(uint) returns (uint)[10] storage b = y;
function(uint) external returns (uint)[] memory c;
c = new function(uint) external returns (uint)[](200);
a; b;
}
}
// ----
// Warning: (361-410): Assertion checker does not yet implement this type of function call.

View File

@ -0,0 +1,7 @@
pragma experimental SMTChecker;
contract test {
mapping (address => function() internal returns (uint)) a;
mapping (address => function() external) b;
mapping (address => function() external[]) c;
function() external[] d;
}