mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #7707 from ethereum/smt_ice_implicit_conversion
[SMTChecker] Fix ICE in string literal to fixed bytes conversion
This commit is contained in:
commit
8d46f39643
@ -18,6 +18,7 @@ Bugfixes:
|
||||
* Code Generator: Fixed a faulty assert that would wrongly trigger for array sizes exceeding unsigned integer.
|
||||
* SMTChecker: Fix internal error when accessing indices of fixed bytes.
|
||||
* SMTChecker: Fix internal error when using function pointers as arguments.
|
||||
* SMTChecker: Fix internal error when implicitly converting string literals to fixed bytes.
|
||||
* Type Checker: Disallow constructor of the same class to be used as modifier.
|
||||
* Type Checker: Treat magic variables as unknown identifiers in inline assembly.
|
||||
|
||||
|
@ -428,15 +428,20 @@ void BMC::inlineFunctionCall(FunctionCall const& _funCall)
|
||||
auto const& funType = dynamic_cast<FunctionType const*>(calledExpr->annotation().type);
|
||||
solAssert(funType, "");
|
||||
|
||||
auto const& functionParams = funDef->parameters();
|
||||
auto const& arguments = _funCall.arguments();
|
||||
unsigned firstParam = 0;
|
||||
if (funType->bound())
|
||||
{
|
||||
auto const& boundFunction = dynamic_cast<MemberAccess const*>(calledExpr);
|
||||
solAssert(boundFunction, "");
|
||||
funArgs.push_back(expr(boundFunction->expression()));
|
||||
funArgs.push_back(expr(boundFunction->expression(), functionParams.front()->type()));
|
||||
firstParam = 1;
|
||||
}
|
||||
|
||||
for (auto arg: _funCall.arguments())
|
||||
funArgs.push_back(expr(*arg));
|
||||
solAssert((arguments.size() + firstParam) == functionParams.size(), "");
|
||||
for (unsigned i = 0; i < arguments.size(); ++i)
|
||||
funArgs.push_back(expr(*arguments.at(i), functionParams.at(i + firstParam)->type()));
|
||||
initializeFunctionCallParameters(*funDef, funArgs);
|
||||
|
||||
// The reason why we need to pushCallStack here instead of visit(FunctionDefinition)
|
||||
|
@ -135,9 +135,13 @@ void SMTEncoder::visitFunctionOrModifier()
|
||||
*modifierInvocation->name()->annotation().referencedDeclaration
|
||||
);
|
||||
vector<smt::Expression> modifierArgsExpr;
|
||||
if (modifierInvocation->arguments())
|
||||
for (auto arg: *modifierInvocation->arguments())
|
||||
modifierArgsExpr.push_back(expr(*arg));
|
||||
if (auto const* arguments = modifierInvocation->arguments())
|
||||
{
|
||||
auto const& modifierParams = modifierDef.parameters();
|
||||
solAssert(modifierParams.size() == arguments->size(), "");
|
||||
for (unsigned i = 0; i < arguments->size(); ++i)
|
||||
modifierArgsExpr.push_back(expr(*arguments->at(i), modifierParams.at(i)->type()));
|
||||
}
|
||||
initializeFunctionCallParameters(modifierDef, modifierArgsExpr);
|
||||
pushCallStack({&modifierDef, modifierInvocation.get()});
|
||||
modifierDef.body().accept(*this);
|
||||
@ -698,7 +702,7 @@ void SMTEncoder::endVisit(Return const& _return)
|
||||
}
|
||||
}
|
||||
else if (returnParams.size() == 1)
|
||||
m_context.addAssertion(expr(*_return.expression()) == m_context.newValue(*returnParams.front()));
|
||||
m_context.addAssertion(expr(*_return.expression(), returnParams.front()->type()) == m_context.newValue(*returnParams.front()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,14 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract B {
|
||||
function f() pure public {
|
||||
g("0123456");
|
||||
}
|
||||
function g(bytes7 a) pure public {
|
||||
assert(a == "0123456");
|
||||
assert(a == "1234567");
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (162-184): Assertion violation happens here
|
||||
// Warning: (136-158): Assertion violation happens here
|
||||
// Warning: (162-184): Assertion violation happens here
|
@ -0,0 +1,11 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract B {
|
||||
function f() mod2("0123456") pure public { }
|
||||
modifier mod2(bytes7 a) {
|
||||
assert(a == "0123456");
|
||||
assert(a == "1234567");
|
||||
_;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (152-174): Assertion violation happens here
|
@ -0,0 +1,12 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract C {
|
||||
function g() public pure returns (bytes32 val) { return "abc"; }
|
||||
function f1() public pure returns (bytes32 val) { return g(); }
|
||||
|
||||
function a() public pure {
|
||||
assert(f1() == "abc");
|
||||
assert(f1() == "cde");
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (238-259): Assertion violation happens here
|
@ -0,0 +1,15 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract C {
|
||||
function h() public pure returns (bytes32 val, bytes3 val2) { return ("abc", "def"); }
|
||||
function g() public pure returns (bytes32 val) { return "abc"; }
|
||||
function f1() public pure returns (bytes32 val) { return g(); }
|
||||
function f2() public pure returns (bytes32 val, bytes3 val2) { return h(); }
|
||||
|
||||
function a() public pure {
|
||||
(bytes32 v1, bytes3 v2) = f2();
|
||||
assert(v1 == "abc");
|
||||
assert(v2 == "cde");
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (442-461): Assertion violation happens here
|
Loading…
Reference in New Issue
Block a user