Merge pull request #5309 from ethereum/smt_bound_functions

[SMTChecker] Support bound function calls
This commit is contained in:
Alex Beregszaszi 2018-11-19 14:53:26 +00:00 committed by GitHub
commit d3f66ca0fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 91 additions and 0 deletions

View File

@ -8,6 +8,7 @@ Compiler Features:
* Code generator: Do not perform redundant double cleanup on unsigned integers when loading from calldata.
* SMTChecker: Support ``msg``, ``tx`` and ``block`` member variables.
* SMTChecker: Support ``gasleft()`` and ``blockhash()`` functions.
* SMTChecker: Support internal bound function calls.
Bugfixes:

View File

@ -457,6 +457,14 @@ void SMTChecker::inlineFunctionCall(FunctionCall const& _funCall)
else if (_funDef && _funDef->isImplemented())
{
vector<smt::Expression> funArgs;
auto const& funType = dynamic_cast<FunctionType const*>(_calledExpr->annotation().type.get());
solAssert(funType, "");
if (funType->bound())
{
auto const& boundFunction = dynamic_cast<MemberAccess const*>(_calledExpr);
solAssert(boundFunction, "");
funArgs.push_back(expr(boundFunction->expression()));
}
for (auto arg: _funCall.arguments())
funArgs.push_back(expr(*arg));
initializeFunctionCallParameters(*_funDef, funArgs);
@ -548,6 +556,10 @@ void SMTChecker::endVisit(Return const& _return)
bool SMTChecker::visit(MemberAccess const& _memberAccess)
{
auto const& accessType = _memberAccess.annotation().type;
if (accessType->category() == Type::Category::Function)
return true;
auto const& exprType = _memberAccess.expression().annotation().type;
solAssert(exprType, "");
if (exprType->category() == Type::Category::Magic)

View File

@ -0,0 +1,19 @@
pragma experimental SMTChecker;
library L
{
function add(uint x, uint y) internal pure returns (uint) {
require(x < 1000);
require(y < 1000);
return x + y;
}
}
contract C
{
using L for uint;
function f(uint x) public pure {
uint y = x.add(999);
assert(y < 10000);
}
}

View File

@ -0,0 +1,21 @@
pragma experimental SMTChecker;
library L
{
function add(uint x, uint y) internal pure returns (uint) {
require(x < 1000);
require(y < 1000);
return x + y;
}
}
contract C
{
using L for uint;
function f(uint x) public pure {
uint y = x.add(999);
assert(y < 1000);
}
}
// ----
// Warning: (261-277): Assertion violation happens here

View File

@ -0,0 +1,18 @@
pragma experimental SMTChecker;
library L
{
function add(uint x, uint y) internal pure returns (uint) {
require(x < 1000);
require(y < 1000);
return x + y;
}
}
contract C
{
function f(uint x) public pure {
uint y = L.add(x, 999);
assert(y < 10000);
}
}

View File

@ -0,0 +1,20 @@
pragma experimental SMTChecker;
library L
{
function add(uint x, uint y) internal pure returns (uint) {
require(x < 1000);
require(y < 1000);
return x + y;
}
}
contract C
{
function f(uint x) public pure {
uint y = L.add(x, 999);
assert(y < 1000);
}
}
// ----
// Warning: (245-261): Assertion violation happens here