Merge pull request #12167 from ethereum/smt_merge_query_entry_points

[SMTChecker] Merge all entry points for a target
This commit is contained in:
Leo
2021-11-03 16:43:16 +01:00
committed by GitHub
10 changed files with 24 additions and 24 deletions
+14 -13
View File
@@ -1623,28 +1623,23 @@ void CHC::checkVerificationTargets()
// Also, all possible contexts in which an external function can be called has been recorded (m_queryPlaceholders).
// Here we combine every context in which an external function can be called with all possible verification conditions
// in its call graph. Each such combination forms a unique verification target.
vector<CHCVerificationTarget> verificationTargets;
map<unsigned, vector<CHCQueryPlaceholder>> targetEntryPoints;
for (auto const& [function, placeholders]: m_queryPlaceholders)
{
auto functionTargets = transactionVerificationTargetsIds(function);
for (auto const& placeholder: placeholders)
for (unsigned id: functionTargets)
{
auto const& target = m_verificationTargets.at(id);
verificationTargets.push_back(CHCVerificationTarget{
{target.type, placeholder.fromPredicate, placeholder.constraints && placeholder.errorExpression == target.errorId},
target.errorId,
target.errorNode
});
}
targetEntryPoints[id].push_back(placeholder);
}
set<unsigned> checkedErrorIds;
for (auto const& target: verificationTargets)
for (auto const& [targetId, placeholders]: targetEntryPoints)
{
string errorType;
ErrorId errorReporterId;
auto const& target = m_verificationTargets.at(targetId);
if (target.type == VerificationTargetType::PopEmptyArray)
{
solAssert(dynamic_cast<FunctionCall const*>(target.errorNode), "");
@@ -1692,7 +1687,7 @@ void CHC::checkVerificationTargets()
else
solAssert(false, "");
checkAndReportTarget(target, errorReporterId, errorType + " happens here.", errorType + " might happen here.");
checkAndReportTarget(target, placeholders, errorReporterId, errorType + " happens here.", errorType + " might happen here.");
checkedErrorIds.insert(target.errorId);
}
@@ -1750,7 +1745,7 @@ void CHC::checkVerificationTargets()
{
set<unsigned> seenErrors;
msg += "<errorCode> = 0 -> no errors\n";
for (auto const& target: verificationTargets)
for (auto const& [id, target]: m_verificationTargets)
if (!seenErrors.count(target.errorId))
{
seenErrors.insert(target.errorId);
@@ -1785,6 +1780,7 @@ void CHC::checkVerificationTargets()
void CHC::checkAndReportTarget(
CHCVerificationTarget const& _target,
vector<CHCQueryPlaceholder> const& _placeholders,
ErrorId _errorReporterId,
string _satMsg,
string _unknownMsg
@@ -1794,7 +1790,12 @@ void CHC::checkAndReportTarget(
return;
createErrorBlock();
connectBlocks(_target.value, error(), _target.constraints);
for (auto const& placeholder: _placeholders)
connectBlocks(
placeholder.fromPredicate,
error(),
placeholder.constraints && placeholder.errorExpression == _target.errorId
);
auto const& location = _target.errorNode->location();
auto [result, invariant, model] = query(error(), location);
if (result == CheckResult::UNSATISFIABLE)
+3 -1
View File
@@ -252,11 +252,13 @@ private:
void verificationTargetEncountered(ASTNode const* const _errorNode, VerificationTargetType _type, smtutil::Expression const& _errorCondition);
void checkVerificationTargets();
// Forward declaration. Definition is below.
// Forward declarations. Definitions are below.
struct CHCVerificationTarget;
struct CHCQueryPlaceholder;
void checkAssertTarget(ASTNode const* _scope, CHCVerificationTarget const& _target);
void checkAndReportTarget(
CHCVerificationTarget const& _target,
std::vector<CHCQueryPlaceholder> const& _placeholders,
langutil::ErrorId _errorReporterId,
std::string _satMsg,
std::string _unknownMsg = ""