aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
authorDan Liew <daniel.liew@imperial.ac.uk>2017-05-24 18:37:50 +0100
committerDan Liew <delcypher@gmail.com>2017-06-01 11:36:09 +0100
commit2e12c5326edde78b1344cc9df1a51db902e41bd5 (patch)
treee770264dda477ee91c354290c8a7e244e745155d /lib
parent2f7878e424dd17b931e56fe179f08a9289211c36 (diff)
downloadklee-2e12c5326edde78b1344cc9df1a51db902e41bd5.tar.gz
[Z3] In `getConstraintLog()` use a separate builder from that of the
solver. This is to avoid tampering with the cache of the builder the solver is using.
Diffstat (limited to 'lib')
-rw-r--r--lib/Solver/Z3Solver.cpp21
1 files changed, 18 insertions, 3 deletions
diff --git a/lib/Solver/Z3Solver.cpp b/lib/Solver/Z3Solver.cpp
index 2b2e63b8..f32860f7 100644
--- a/lib/Solver/Z3Solver.cpp
+++ b/lib/Solver/Z3Solver.cpp
@@ -132,10 +132,18 @@ void Z3Solver::setCoreSolverTimeout(double timeout) {
char *Z3SolverImpl::getConstraintLog(const Query &query) {
std::vector<Z3ASTHandle> assumptions;
+ // We use a different builder here because we don't want to interfere
+ // with the solver's builder because it may change the solver builder's
+ // cache.
+ // NOTE: The builder does not set `z3LogInteractionFile` to avoid conflicting
+ // with whatever the solver's builder is set to do.
+ Z3Builder temp_builder(/*autoClearConstructCache=*/false,
+ /*z3LogInteractionFile=*/NULL);
+
for (std::vector<ref<Expr> >::const_iterator it = query.constraints.begin(),
ie = query.constraints.end();
it != ie; ++it) {
- assumptions.push_back(builder->construct(*it));
+ assumptions.push_back(temp_builder.construct(*it));
}
::Z3_ast *assumptionsArray = NULL;
int numAssumptions = query.constraints.size();
@@ -152,10 +160,11 @@ char *Z3SolverImpl::getConstraintLog(const Query &query) {
// the negation of the equivalent i.e.
// ∃ X Constraints(X) ∧ ¬ query(X)
Z3ASTHandle formula = Z3ASTHandle(
- Z3_mk_not(builder->ctx, builder->construct(query.expr)), builder->ctx);
+ Z3_mk_not(temp_builder.ctx, temp_builder.construct(query.expr)),
+ temp_builder.ctx);
::Z3_string result = Z3_benchmark_to_smtlib_string(
- builder->ctx,
+ temp_builder.ctx,
/*name=*/"Emited by klee::Z3SolverImpl::getConstraintLog()",
/*logic=*/"",
/*status=*/"unknown",
@@ -166,6 +175,12 @@ char *Z3SolverImpl::getConstraintLog(const Query &query) {
if (numAssumptions)
free(assumptionsArray);
+
+ // We need to trigger a dereference before the `temp_builder` gets destroyed.
+ // We do this indirectly by emptying `assumptions` and assigning to
+ // `formula`.
+ assumptions.clear();
+ formula = Z3ASTHandle(NULL, temp_builder.ctx);
// Client is responsible for freeing the returned C-string
return strdup(result);
}