aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
authorTaras Bereznyak <bereznyak.taras1@huawei.com>2021-11-04 13:33:01 +0300
committerCristian Cadar <c.cadar@imperial.ac.uk>2021-11-20 12:34:37 +0100
commit0379144709c2bc47b6fc4bc42c5fe00a24d01a0d (patch)
tree375dfb5b52d24bb4aa1aecb98d708c6d82379ae6 /lib
parentf4c4f164a2d9132fcc53c0ce44ea8c5379d4d93e (diff)
downloadklee-0379144709c2bc47b6fc4bc42c5fe00a24d01a0d.tar.gz
Fixed fail with preferCex, removed relation from first argument
Diffstat (limited to 'lib')
-rw-r--r--lib/Core/ExecutionState.cpp5
-rw-r--r--lib/Core/ExecutionState.h6
-rw-r--r--lib/Core/Executor.cpp34
-rw-r--r--lib/Core/Memory.h6
-rw-r--r--lib/Core/SpecialFunctionHandler.cpp8
5 files changed, 25 insertions, 34 deletions
diff --git a/lib/Core/ExecutionState.cpp b/lib/Core/ExecutionState.cpp
index 47a3b3c6..2f585f96 100644
--- a/lib/Core/ExecutionState.cpp
+++ b/lib/Core/ExecutionState.cpp
@@ -103,6 +103,7 @@ ExecutionState::ExecutionState(const ExecutionState& state):
symPathOS(state.symPathOS),
coveredLines(state.coveredLines),
symbolics(state.symbolics),
+ cexPreferences(state.cexPreferences),
arrayNames(state.arrayNames),
openMergeStack(state.openMergeStack),
steppedInstructions(state.steppedInstructions),
@@ -358,3 +359,7 @@ void ExecutionState::addConstraint(ref<Expr> e) {
ConstraintManager c(constraints);
c.addConstraint(e);
}
+
+void ExecutionState::addCexPreference(const ref<Expr> &cond) {
+ cexPreferences = cexPreferences.insert(cond);
+}
diff --git a/lib/Core/ExecutionState.h b/lib/Core/ExecutionState.h
index f91790d5..8f5e57e8 100644
--- a/lib/Core/ExecutionState.h
+++ b/lib/Core/ExecutionState.h
@@ -13,6 +13,7 @@
#include "AddressSpace.h"
#include "MergeHandler.h"
+#include "klee/ADT/ImmutableSet.h"
#include "klee/ADT/TreeStream.h"
#include "klee/Expr/Constraints.h"
#include "klee/Expr/Expr.h"
@@ -207,6 +208,10 @@ public:
// FIXME: Move to a shared list structure (not critical).
std::vector<std::pair<ref<const MemoryObject>, const Array *>> symbolics;
+ /// @brief A set of boolean expressions
+ /// the user has requested be true of a counterexample.
+ ImmutableSet<ref<Expr>> cexPreferences;
+
/// @brief Set of used array names for this state. Used to avoid collisions.
std::set<std::string> arrayNames;
@@ -259,6 +264,7 @@ public:
void addSymbolic(const MemoryObject *mo, const Array *array);
void addConstraint(ref<Expr> e);
+ void addCexPreference(const ref<Expr> &cond);
bool merge(const ExecutionState &b);
void dumpStack(llvm::raw_ostream &out) const;
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index dcb078df..3d6ea4ae 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -4560,27 +4560,19 @@ bool Executor::getSymbolicSolution(const ExecutionState &state,
// the preferred constraints. See test/Features/PreferCex.c for
// an example) While this process can be very expensive, it can
// also make understanding individual test cases much easier.
- for (unsigned i = 0; i != state.symbolics.size(); ++i) {
- const auto &mo = state.symbolics[i].first;
- std::vector< ref<Expr> >::const_iterator pi =
- mo->cexPreferences.begin(), pie = mo->cexPreferences.end();
- for (; pi != pie; ++pi) {
- bool mustBeTrue;
- // Attempt to bound byte to constraints held in cexPreferences
- bool success =
- solver->mustBeTrue(extendedConstraints, Expr::createIsZero(*pi),
- mustBeTrue, state.queryMetaData);
- // If it isn't possible to constrain this particular byte in the desired
- // way (normally this would mean that the byte can't be constrained to
- // be between 0 and 127 without making the entire constraint list UNSAT)
- // then just continue on to the next byte.
- if (!success) break;
- // If the particular constraint operated on in this iteration through
- // the loop isn't implied then add it to the list of constraints.
- if (!mustBeTrue)
- cm.addConstraint(*pi);
- }
- if (pi!=pie) break;
+ for (auto& pi: state.cexPreferences) {
+ bool mustBeTrue;
+ // Attempt to bound byte to constraints held in cexPreferences
+ bool success =
+ solver->mustBeTrue(extendedConstraints, Expr::createIsZero(pi),
+ mustBeTrue, state.queryMetaData);
+ // If it isn't possible to add the condition without making the entire list
+ // UNSAT, then just continue to the next condition
+ if (!success) break;
+ // If the particular constraint operated on in this iteration through
+ // the loop isn't implied then add it to the list of constraints.
+ if (!mustBeTrue)
+ cm.addConstraint(pi);
}
std::vector< std::vector<unsigned char> > values;
diff --git a/lib/Core/Memory.h b/lib/Core/Memory.h
index e88d5f55..d5189df5 100644
--- a/lib/Core/Memory.h
+++ b/lib/Core/Memory.h
@@ -64,12 +64,6 @@ public:
/// should be either the allocating instruction or the global object
/// it was allocated for (or whatever else makes sense).
const llvm::Value *allocSite;
-
- /// A list of boolean expressions the user has requested be true of
- /// a counterexample. Mutable since we play a little fast and loose
- /// with allowing it to be added to during execution (although
- /// should sensibly be only at creation time).
- mutable std::vector< ref<Expr> > cexPreferences;
// DO NOT IMPLEMENT
MemoryObject(const MemoryObject &b);
diff --git a/lib/Core/SpecialFunctionHandler.cpp b/lib/Core/SpecialFunctionHandler.cpp
index 27ca385c..94c4dc3c 100644
--- a/lib/Core/SpecialFunctionHandler.cpp
+++ b/lib/Core/SpecialFunctionHandler.cpp
@@ -549,13 +549,7 @@ void SpecialFunctionHandler::handlePreferCex(ExecutionState &state,
if (cond->getWidth() != Expr::Bool)
cond = NeExpr::create(cond, ConstantExpr::alloc(0, cond->getWidth()));
- Executor::ExactResolutionList rl;
- executor.resolveExact(state, arguments[0], rl, "prefex_cex");
-
- assert(rl.size() == 1 &&
- "prefer_cex target must resolve to precisely one object");
-
- rl[0].first.first->cexPreferences.push_back(cond);
+ state.addCexPreference(cond);
}
void SpecialFunctionHandler::handlePosixPreferCex(ExecutionState &state,