diff options
author | Andrea Mattavelli <andreamattavelli@users.noreply.github.com> | 2017-02-14 14:46:56 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-14 14:46:56 +0000 |
commit | 293f6e05ab8abdfca141eaa348da716b674c30e7 (patch) | |
tree | 55128d04f6d03b4308a8ae3e9a5241d2a94794e3 /lib | |
parent | c3c3332a039e8e9cc10f93c3acb71c4240d4cab8 (diff) | |
parent | 44b24dac6a05ccde0e01b54fd2b787a31e5d8811 (diff) | |
download | klee-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.cpp | 13 |
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); } |