about summary refs log tree commit diff homepage
path: root/lib
diff options
context:
space:
mode:
authorAndrea Mattavelli <andreamattavelli@users.noreply.github.com>2017-02-14 14:46:56 +0000
committerGitHub <noreply@github.com>2017-02-14 14:46:56 +0000
commit293f6e05ab8abdfca141eaa348da716b674c30e7 (patch)
tree55128d04f6d03b4308a8ae3e9a5241d2a94794e3 /lib
parentc3c3332a039e8e9cc10f93c3acb71c4240d4cab8 (diff)
parent44b24dac6a05ccde0e01b54fd2b787a31e5d8811 (diff)
downloadklee-293f6e05ab8abdfca141eaa348da716b674c30e7.tar.gz
Merge pull request #574 from delcypher/read_expr_missed_constaint_fold
ReadExpr::create() was missing an opportunity to constant fold
Diffstat (limited to 'lib')
-rw-r--r--lib/Expr/Expr.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/lib/Expr/Expr.cpp b/lib/Expr/Expr.cpp
index 15f52184..ac50dda2 100644
--- a/lib/Expr/Expr.cpp
+++ b/lib/Expr/Expr.cpp
@@ -529,6 +529,7 @@ ref<Expr> ReadExpr::create(const UpdateList &ul, ref<Expr> index) {
   // a smart UpdateList so it is not worth rescanning.
 
   const UpdateNode *un = ul.head;
+  bool updateListHasSymbolicWrites = false;
   for (; un; un=un->next) {
     ref<Expr> cond = EqExpr::create(index, un->index);
     
@@ -536,10 +537,22 @@ ref<Expr> ReadExpr::create(const UpdateList &ul, ref<Expr> index) {
       if (CE->isTrue())
         return un->value;
     } else {
+      updateListHasSymbolicWrites = true;
       break;
     }
   }
 
+  if (ul.root->isConstantArray() && !updateListHasSymbolicWrites) {
+    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(index)) {
+      assert(CE->getWidth() <= 64 && "Index too large");
+      uint64_t concreteIndex = CE->getZExtValue();
+      uint64_t size = ul.root->size;
+      if (concreteIndex < size) {
+        return ul.root->constantValues[concreteIndex];
+      }
+    }
+  }
+
   return ReadExpr::alloc(ul, index);
 }