[SMTChecker] Fix virtual modifier called statically

This commit is contained in:
Martin Blicha
2020-12-21 13:52:28 +01:00
parent 67712d50ba
commit 87ef0e16f5
4 changed files with 55 additions and 13 deletions
+20 -13
View File
@@ -207,12 +207,8 @@ void SMTEncoder::visitFunctionOrModifier()
auto refDecl = modifierInvocation->name().annotation().referencedDeclaration;
if (dynamic_cast<ContractDefinition const*>(refDecl))
visitFunctionOrModifier();
else if (auto modifierDef = dynamic_cast<ModifierDefinition const*>(refDecl))
{
solAssert(*modifierInvocation->name().annotation().requiredLookup == VirtualLookup::Virtual, "");
ModifierDefinition const& modifier = modifierDef->resolveVirtual(*m_currentContract);
inlineModifierInvocation(modifierInvocation.get(), &modifier);
}
else if (auto modifier = resolveModifierInvocation(*modifierInvocation, m_currentContract))
inlineModifierInvocation(modifierInvocation.get(), modifier);
else
solAssert(false, "");
}
@@ -2681,23 +2677,34 @@ vector<VariableDeclaration const*> SMTEncoder::modifiersVariables(FunctionDefini
{
if (!invok)
continue;
auto decl = invok->name().annotation().referencedDeclaration;
auto const* modifier = dynamic_cast<ModifierDefinition const*>(decl);
auto const* modifier = resolveModifierInvocation(*invok, _contract);
if (!modifier || visited.count(modifier))
continue;
visited.insert(modifier);
solAssert(_contract, "No contract context provided for modifier analysis!");
auto const& actualModifier = modifier->resolveVirtual(*_contract);
if (actualModifier.isImplemented())
if (modifier->isImplemented())
{
vars += applyMap(actualModifier.parameters(), [](auto _var) { return _var.get(); });
vars += BlockVars(actualModifier.body()).vars;
vars += applyMap(modifier->parameters(), [](auto _var) { return _var.get(); });
vars += BlockVars(modifier->body()).vars;
}
}
return vars;
}
ModifierDefinition const* SMTEncoder::resolveModifierInvocation(ModifierInvocation const& _invocation, ContractDefinition const* _contract)
{
auto const* modifier = dynamic_cast<ModifierDefinition const*>(_invocation.name().annotation().referencedDeclaration);
if (modifier)
{
VirtualLookup lookup = *_invocation.name().annotation().requiredLookup;
solAssert(lookup == VirtualLookup::Virtual || lookup == VirtualLookup::Static, "");
solAssert(_contract || lookup == VirtualLookup::Static, "No contract context provided for modifier lookup resolution!");
if (lookup == VirtualLookup::Virtual)
modifier = &modifier->resolveVirtual(*_contract);
}
return modifier;
}
SourceUnit const* SMTEncoder::sourceUnitContaining(Scopable const& _scopable)
{
for (auto const* s = &_scopable; s; s = dynamic_cast<Scopable const*>(s->scope()))