mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[SMTChecker] Inline external function calls to this.
This commit is contained in:
@@ -666,8 +666,6 @@ void SMTChecker::endVisit(FunctionCall const& _funCall)
|
||||
visitGasLeft(_funCall);
|
||||
break;
|
||||
case FunctionType::Kind::Internal:
|
||||
inlineFunctionCall(_funCall);
|
||||
break;
|
||||
case FunctionType::Kind::External:
|
||||
case FunctionType::Kind::DelegateCall:
|
||||
case FunctionType::Kind::BareCall:
|
||||
@@ -675,9 +673,7 @@ void SMTChecker::endVisit(FunctionCall const& _funCall)
|
||||
case FunctionType::Kind::BareDelegateCall:
|
||||
case FunctionType::Kind::BareStaticCall:
|
||||
case FunctionType::Kind::Creation:
|
||||
m_externalFunctionCallHappened = true;
|
||||
resetStateVariables();
|
||||
resetStorageReferences();
|
||||
internalOrExternalFunctionCall(_funCall);
|
||||
break;
|
||||
case FunctionType::Kind::KECCAK256:
|
||||
case FunctionType::Kind::ECRecover:
|
||||
@@ -805,6 +801,25 @@ void SMTChecker::inlineFunctionCall(FunctionCall const& _funCall)
|
||||
}
|
||||
}
|
||||
|
||||
void SMTChecker::internalOrExternalFunctionCall(FunctionCall const& _funCall)
|
||||
{
|
||||
auto funDef = inlinedFunctionCallToDefinition(_funCall);
|
||||
auto const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);
|
||||
if (funDef)
|
||||
inlineFunctionCall(_funCall);
|
||||
else if (funType.kind() == FunctionType::Kind::Internal)
|
||||
m_errorReporter.warning(
|
||||
_funCall.location(),
|
||||
"Assertion checker does not yet implement this type of function call."
|
||||
);
|
||||
else
|
||||
{
|
||||
m_externalFunctionCallHappened = true;
|
||||
resetStateVariables();
|
||||
resetStorageReferences();
|
||||
}
|
||||
}
|
||||
|
||||
void SMTChecker::abstractFunctionCall(FunctionCall const& _funCall)
|
||||
{
|
||||
vector<smt::Expression> smtArguments;
|
||||
@@ -1931,7 +1946,21 @@ FunctionDefinition const* SMTChecker::inlinedFunctionCallToDefinition(FunctionCa
|
||||
return nullptr;
|
||||
|
||||
FunctionType const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);
|
||||
if (funType.kind() != FunctionType::Kind::Internal)
|
||||
if (funType.kind() == FunctionType::Kind::External)
|
||||
{
|
||||
auto memberAccess = dynamic_cast<MemberAccess const*>(&_funCall.expression());
|
||||
auto identifier = memberAccess ?
|
||||
dynamic_cast<Identifier const*>(&memberAccess->expression()) :
|
||||
nullptr;
|
||||
if (!(
|
||||
identifier &&
|
||||
identifier->name() == "this" &&
|
||||
identifier->annotation().referencedDeclaration &&
|
||||
dynamic_cast<MagicVariableDeclaration const*>(identifier->annotation().referencedDeclaration)
|
||||
))
|
||||
return nullptr;
|
||||
}
|
||||
else if (funType.kind() != FunctionType::Kind::Internal)
|
||||
return nullptr;
|
||||
|
||||
FunctionDefinition const* funDef = nullptr;
|
||||
|
||||
@@ -115,6 +115,9 @@ private:
|
||||
void inlineFunctionCall(FunctionCall const& _funCall);
|
||||
/// Creates an uninterpreted function call.
|
||||
void abstractFunctionCall(FunctionCall const& _funCall);
|
||||
/// Inlines if the function call is internal or external to `this`.
|
||||
/// Erases knowledge about state variables if external.
|
||||
void internalOrExternalFunctionCall(FunctionCall const& _funCall);
|
||||
void visitFunctionIdentifier(Identifier const& _identifier);
|
||||
|
||||
/// Encodes a modifier or function body according to the modifier
|
||||
|
||||
Reference in New Issue
Block a user