mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Simplify internal function calls
This commit is contained in:
parent
3519b38055
commit
fa7c9a0dc6
@ -532,6 +532,10 @@ void CHC::internalFunctionCall(FunctionCall const& _funCall)
|
|||||||
|
|
||||||
void CHC::externalFunctionCall(FunctionCall const& _funCall)
|
void CHC::externalFunctionCall(FunctionCall const& _funCall)
|
||||||
{
|
{
|
||||||
|
/// In external function calls we do not add a "predicate call"
|
||||||
|
/// because we do not trust their function body anyway,
|
||||||
|
/// so we just add the nondet_interface predicate.
|
||||||
|
|
||||||
solAssert(m_currentContract, "");
|
solAssert(m_currentContract, "");
|
||||||
|
|
||||||
FunctionType const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);
|
FunctionType const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);
|
||||||
@ -978,24 +982,35 @@ smtutil::Expression CHC::predicate(Predicate const& _block)
|
|||||||
|
|
||||||
smtutil::Expression CHC::predicate(FunctionCall const& _funCall)
|
smtutil::Expression CHC::predicate(FunctionCall const& _funCall)
|
||||||
{
|
{
|
||||||
|
/// Used only for internal calls.
|
||||||
|
|
||||||
auto const* function = functionCallToDefinition(_funCall);
|
auto const* function = functionCallToDefinition(_funCall);
|
||||||
if (!function)
|
if (!function)
|
||||||
return smtutil::Expression(true);
|
return smtutil::Expression(true);
|
||||||
|
|
||||||
errorFlag().increaseIndex();
|
errorFlag().increaseIndex();
|
||||||
vector<smtutil::Expression> args{errorFlag().currentValue()};
|
vector<smtutil::Expression> args{errorFlag().currentValue()};
|
||||||
auto const* contract = function->annotation().contract;
|
|
||||||
FunctionType const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);
|
|
||||||
bool otherContract = contract->isLibrary() ||
|
|
||||||
funType.kind() == FunctionType::Kind::External ||
|
|
||||||
funType.kind() == FunctionType::Kind::BareStaticCall;
|
|
||||||
|
|
||||||
args += otherContract ? stateVariablesAtIndex(0, *contract) : currentStateVariables();
|
FunctionType const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);
|
||||||
|
solAssert(funType.kind() == FunctionType::Kind::Internal, "");
|
||||||
|
|
||||||
|
/// Internal calls can be made to the contract itself or a library.
|
||||||
|
auto const* contract = function->annotation().contract;
|
||||||
|
auto const& hierarchy = m_currentContract->annotation().linearizedBaseContracts;
|
||||||
|
solAssert(contract->isLibrary() || find(hierarchy.begin(), hierarchy.end(), contract) != hierarchy.end(), "");
|
||||||
|
|
||||||
|
/// If the call is to a library, we use that library as the called contract.
|
||||||
|
/// If it is not, we use the current contract even if it is a call to a contract
|
||||||
|
/// up in the inheritance hierarchy, since the interfaces/predicates are different.
|
||||||
|
auto const* calledContract = contract->isLibrary() ? contract : m_currentContract;
|
||||||
|
solAssert(calledContract, "");
|
||||||
|
|
||||||
|
args += currentStateVariables(*calledContract);
|
||||||
args += symbolicArguments(_funCall);
|
args += symbolicArguments(_funCall);
|
||||||
if (!otherContract)
|
if (!calledContract->isLibrary())
|
||||||
for (auto const& var: m_stateVariables)
|
for (auto const& var: m_stateVariables)
|
||||||
m_context.variable(*var)->increaseIndex();
|
m_context.variable(*var)->increaseIndex();
|
||||||
args += otherContract ? stateVariablesAtIndex(1, *contract) : currentStateVariables();
|
args += currentStateVariables(*calledContract);
|
||||||
|
|
||||||
for (auto var: function->parameters() + function->returnParameters())
|
for (auto var: function->parameters() + function->returnParameters())
|
||||||
{
|
{
|
||||||
@ -1006,11 +1021,7 @@ smtutil::Expression CHC::predicate(FunctionCall const& _funCall)
|
|||||||
args.push_back(currentValue(*var));
|
args.push_back(currentValue(*var));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (otherContract)
|
return (*m_summaries.at(calledContract).at(function))(args);
|
||||||
return (*m_summaries.at(contract).at(function))(args);
|
|
||||||
|
|
||||||
solAssert(m_currentContract, "");
|
|
||||||
return (*m_summaries.at(m_currentContract).at(function))(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHC::addRule(smtutil::Expression const& _rule, string const& _ruleName)
|
void CHC::addRule(smtutil::Expression const& _rule, string const& _ruleName)
|
||||||
|
@ -14,13 +14,11 @@ contract LoopFor2 {
|
|||||||
c[i] = b[i];
|
c[i] = b[i];
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
// Fails as false positive.
|
|
||||||
assert(b[0] == c[0]);
|
assert(b[0] == c[0]);
|
||||||
assert(a[0] == 900);
|
assert(a[0] == 900);
|
||||||
assert(b[0] == 900);
|
assert(b[0] == 900);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Warning 6328: (320-339): CHC: Assertion violation happens here.
|
// Warning 6328: (290-309): CHC: Assertion violation happens here.
|
||||||
// Warning 6328: (343-362): CHC: Assertion violation happens here.
|
// Warning 6328: (313-332): CHC: Assertion violation happens here.
|
||||||
// Warning 4661: (296-316): BMC: Assertion violation happens here.
|
|
||||||
|
Loading…
Reference in New Issue
Block a user