about summary refs log tree commit diff homepage
path: root/lib/Core/ExecutionState.cpp
diff options
context:
space:
mode:
authorNguyễn Gia Phong <mcsinyx@disroot.org>2023-03-30 20:11:04 +0900
committerNguyễn Gia Phong <cnx@loang.net>2023-11-10 16:47:52 +0900
commit570be9543a034d17591f91c9e46b593c9e4ad7f4 (patch)
tree42de26bebdd1bb3c1ddea38946106bab898d2c45 /lib/Core/ExecutionState.cpp
parent088487330da284c743971f4eb4dd1f57abe4984b (diff)
downloadklee-570be9543a034d17591f91c9e46b593c9e4ad7f4.tar.gz
Implement differentiator extraction
Diffstat (limited to 'lib/Core/ExecutionState.cpp')
-rw-r--r--lib/Core/ExecutionState.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/Core/ExecutionState.cpp b/lib/Core/ExecutionState.cpp
index 1c1f477c..a38e717a 100644
--- a/lib/Core/ExecutionState.cpp
+++ b/lib/Core/ExecutionState.cpp
@@ -372,7 +372,36 @@ void ExecutionState::dumpStack(llvm::raw_ostream &out) const {
   }
 }
 
+bool isMetaConstraint(ref<Expr> e) {
+  if (e.get()->getKind() != Expr::Eq)
+    return false;
+  const auto eq = dyn_cast<EqExpr>(e.get());
+  if (eq->left.get()->getKind() != Expr::Constant)
+    return false;
+  const auto constant = dyn_cast<ConstantExpr>(eq->left.get());
+  if (constant->isFalse()) // the else branch
+    return isMetaConstraint(eq->right);
+
+  if (eq->right.get()->getKind() != Expr::Concat)
+    return false;
+  const auto concat = dyn_cast<ConcatExpr>(eq->right.get());
+  if (concat->getLeft().get()->getKind() != Expr::Read)
+    return false;
+
+  const auto read = dyn_cast<ReadExpr>(concat->getLeft().get());
+  const auto& name = read->updates.root->name;
+  // string::starts_with requires C++20
+  if (name.substr(0, 8) != "__choose")
+    return false;
+  for (const auto c : name.substr(8))
+    if ('0' > c || c > '9')
+      return false;
+  return true;
+}
+
 void ExecutionState::addConstraint(ref<Expr> e) {
+  if (isMetaConstraint(e))
+    return;
   ConstraintManager c(constraints);
   c.addConstraint(e);
 }