Merge pull request #10884 from blishko/smt-refactor

[SMTChecker] Small refactoring
This commit is contained in:
Leonardo 2021-02-03 17:26:53 +01:00 committed by GitHub
commit 43ce5d3f79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 33 additions and 40 deletions

View File

@ -162,7 +162,7 @@ bool BMC::visit(FunctionDefinition const& _function)
{
reset();
initFunction(_function);
m_context.addAssertion(m_context.state().txTypeConstraints() && m_context.state().txFunctionConstraints(_function));
m_context.addAssertion(state().txTypeConstraints() && state().txFunctionConstraints(_function));
resetStateVariables();
}
@ -440,7 +440,7 @@ void BMC::endVisit(FunctionCall const& _funCall)
{
auto value = _funCall.arguments().front();
solAssert(value, "");
smtutil::Expression thisBalance = m_context.state().balance();
smtutil::Expression thisBalance = state().balance();
addVerificationTarget(
VerificationTargetType::Balance,
@ -561,8 +561,7 @@ void BMC::internalOrExternalFunctionCall(FunctionCall const& _funCall)
else
{
m_externalFunctionCallHappened = true;
resetStateVariables();
resetStorageReferences();
resetStorageVariables();
}
}
@ -624,11 +623,6 @@ pair<smtutil::Expression, smtutil::Expression> BMC::arithmeticOperation(
return values;
}
void BMC::resetStorageReferences()
{
m_context.resetVariables([&](VariableDeclaration const& _variable) { return _variable.hasReferenceOrMappingType(); });
}
void BMC::reset()
{
m_externalFunctionCallHappened = false;

View File

@ -123,7 +123,6 @@ private:
Expression const& _expression
) override;
void resetStorageReferences();
void reset();
std::pair<std::vector<smtutil::Expression>, std::vector<std::string>> modelExpressions();

View File

@ -880,8 +880,7 @@ void CHC::resetContractAnalysis()
void CHC::eraseKnowledge()
{
resetStateVariables();
m_context.resetVariables([&](VariableDeclaration const& _variable) { return _variable.hasReferenceOrMappingType(); });
resetStorageVariables();
}
void CHC::clearIndices(ContractDefinition const* _contract, FunctionDefinition const* _function)
@ -1691,11 +1690,6 @@ unsigned CHC::newErrorId()
return errorId;
}
SymbolicState& CHC::state()
{
return m_context.state();
}
SymbolicIntVariable& CHC::errorFlag()
{
return state().errorFlag();

View File

@ -258,7 +258,6 @@ private:
/// it into m_errorIds.
unsigned newErrorId();
smt::SymbolicState& state();
smt::SymbolicIntVariable& errorFlag();
//@}

View File

@ -79,7 +79,7 @@ bool SMTEncoder::analyze(SourceUnit const& _source)
if (!analysis)
return false;
m_context.state().prepareForSourceUnit(_source);
state().prepareForSourceUnit(_source);
return true;
}
@ -697,7 +697,7 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall)
visitCryptoFunction(_funCall);
break;
case FunctionType::Kind::BlockHash:
defineExpr(_funCall, m_context.state().blockhash(expr(*_funCall.arguments().at(0))));
defineExpr(_funCall, state().blockhash(expr(*_funCall.arguments().at(0))));
break;
case FunctionType::Kind::AddMod:
case FunctionType::Kind::MulMod:
@ -711,10 +711,10 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall)
auto const& value = args.front();
solAssert(value, "");
smtutil::Expression thisBalance = m_context.state().balance();
smtutil::Expression thisBalance = state().balance();
setSymbolicUnknownValue(thisBalance, TypeProvider::uint256(), m_context);
m_context.state().transfer(m_context.state().thisAddress(), expr(address), expr(*value));
state().transfer(state().thisAddress(), expr(address), expr(*value));
break;
}
case FunctionType::Kind::ArrayPush:
@ -799,8 +799,8 @@ void SMTEncoder::visitRequire(FunctionCall const& _funCall)
void SMTEncoder::visitABIFunction(FunctionCall const& _funCall)
{
auto symbFunction = m_context.state().abiFunction(&_funCall);
auto const& [name, inTypes, outTypes] = m_context.state().abiFunctionTypes(&_funCall);
auto symbFunction = state().abiFunction(&_funCall);
auto const& [name, inTypes, outTypes] = state().abiFunctionTypes(&_funCall);
auto const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);
auto kind = funType.kind();
@ -848,14 +848,14 @@ void SMTEncoder::visitCryptoFunction(FunctionCall const& _funCall)
auto arg0 = expr(*_funCall.arguments().at(0));
optional<smtutil::Expression> result;
if (kind == FunctionType::Kind::KECCAK256)
result = smtutil::Expression::select(m_context.state().cryptoFunction("keccak256"), arg0);
result = smtutil::Expression::select(state().cryptoFunction("keccak256"), arg0);
else if (kind == FunctionType::Kind::SHA256)
result = smtutil::Expression::select(m_context.state().cryptoFunction("sha256"), arg0);
result = smtutil::Expression::select(state().cryptoFunction("sha256"), arg0);
else if (kind == FunctionType::Kind::RIPEMD160)
result = smtutil::Expression::select(m_context.state().cryptoFunction("ripemd160"), arg0);
result = smtutil::Expression::select(state().cryptoFunction("ripemd160"), arg0);
else if (kind == FunctionType::Kind::ECRecover)
{
auto e = m_context.state().cryptoFunction("ecrecover");
auto e = state().cryptoFunction("ecrecover");
auto arg0 = expr(*_funCall.arguments().at(0));
auto arg1 = expr(*_funCall.arguments().at(1));
auto arg2 = expr(*_funCall.arguments().at(2));
@ -953,7 +953,7 @@ void SMTEncoder::endVisit(Identifier const& _identifier)
defineGlobalVariable(_identifier.name(), _identifier);
else if (_identifier.name() == "this")
{
defineExpr(_identifier, m_context.state().thisAddress());
defineExpr(_identifier, state().thisAddress());
m_uninterpretedTerms.insert(&_identifier);
}
// Ignore type identifiers
@ -1299,7 +1299,7 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess)
{
auto const& name = identifier->name();
solAssert(name == "block" || name == "msg" || name == "tx", "");
defineExpr(_memberAccess, m_context.state().txMember(name + "." + _memberAccess.memberName()));
defineExpr(_memberAccess, state().txMember(name + "." + _memberAccess.memberName()));
}
else if (auto magicType = dynamic_cast<MagicType const*>(exprType); magicType->kind() == MagicType::Kind::MetaType)
{
@ -1360,7 +1360,7 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess)
_memberAccess.expression().accept(*this);
if (_memberAccess.memberName() == "balance")
{
defineExpr(_memberAccess, m_context.state().balance(expr(_memberAccess.expression())));
defineExpr(_memberAccess, state().balance(expr(_memberAccess.expression())));
setSymbolicUnknownValue(*m_context.expression(_memberAccess), m_context);
m_uninterpretedTerms.insert(&_memberAccess);
return false;
@ -2571,7 +2571,7 @@ void SMTEncoder::clearIndices(ContractDefinition const* _contract, FunctionDefin
for (auto const& var: localVariablesIncludingModifiers(*_function, _contract))
m_context.variable(*var)->resetIndex();
}
m_context.state().reset();
state().reset();
}
Expression const* SMTEncoder::leftmostBase(IndexAccess const& _indexAccess)
@ -3009,3 +3009,8 @@ vector<smtutil::Expression> SMTEncoder::symbolicArguments(FunctionCall const& _f
return args;
}
smt::SymbolicState& SMTEncoder::state()
{
return m_context.state();
}

View File

@ -424,6 +424,8 @@ protected:
/// Stores the context of the encoding.
smt::EncodingContext& m_context;
smt::SymbolicState& state();
};
}

View File

@ -20,8 +20,8 @@ contract C
// ----
// Warning 2072: (224-240): Unused local variable.
// Warning 4588: (244-256): Assertion checker does not yet implement this type of function call.
// Warning 6328: (260-275): CHC: Assertion violation happens here.
// Warning 6328: (279-293): CHC: Assertion violation happens here.
// Warning 6328: (297-316): CHC: Assertion violation happens here.
// Warning 6328: (320-344): CHC: Assertion violation happens here.
// Warning 6328: (260-275): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\na = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f(0, data)
// Warning 6328: (279-293): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\na = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f(0, data)
// Warning 6328: (297-316): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\na = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f(0, data)
// Warning 6328: (320-344): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\na = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f(0, data)
// Warning 4588: (244-256): Assertion checker does not yet implement this type of function call.

View File

@ -20,8 +20,8 @@ contract C
// ----
// Warning 2072: (224-240): Unused local variable.
// Warning 4588: (244-264): Assertion checker does not yet implement this type of function call.
// Warning 6328: (268-283): CHC: Assertion violation happens here.
// Warning 6328: (287-301): CHC: Assertion violation happens here.
// Warning 6328: (305-324): CHC: Assertion violation happens here.
// Warning 6328: (328-352): CHC: Assertion violation happens here.
// Warning 6328: (268-283): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\na = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f(0, data)
// Warning 6328: (287-301): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\na = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f(0, data)
// Warning 6328: (305-324): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\na = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f(0, data)
// Warning 6328: (328-352): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\na = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f(0, data)
// Warning 4588: (244-264): Assertion checker does not yet implement this type of function call.