diff options
author | Richard Trieu <rtrieu@google.com> | 2012-03-21 23:30:30 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2012-03-21 23:30:30 +0000 |
commit | b778305e95f9977e6710f2b04830ecc36398ab5e (patch) | |
tree | 66fe05c7de832007641775f2880d0b91ba4948f1 /lib/AST/ExprConstant.cpp | |
parent | 850f1b1af015719ec10351bb93530101c265dd29 (diff) |
Change the binary operator data recursive evaluator to not stop at the first
non-constant value encountered. This allows the evaluator to deduce that
expressions like (x < 5 || true) is equal to true. Previously, it would visit
x and determined that the entire expression is could not evaluated to a
constant.
This fixes PR12318.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153226 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 331c757c12..583bbfc988 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -4510,12 +4510,10 @@ public: bool Traverse(const BinaryOperator *E) { enqueue(E); EvalResult PrevResult; - while (!Queue.empty()) { - if (!process(PrevResult)) { - Queue.clear(); - return false; - } - } + while (!Queue.empty()) + process(PrevResult); + + if (PrevResult.Failed) return false; FinalResult.swap(PrevResult.Val); return true; @@ -4552,7 +4550,7 @@ private: Result.Val = APValue(); } - bool process(EvalResult &Result); + void process(EvalResult &Result); void enqueue(const Expr *E) { E = E->IgnoreParens(); @@ -4785,7 +4783,7 @@ bool DataRecursiveIntBinOpEvaluator:: } } -bool DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) { +void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) { Job &job = Queue.back(); switch (job.Kind) { @@ -4794,13 +4792,13 @@ bool DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) { if (shouldEnqueue(Bop)) { job.Kind = Job::BinOpKind; enqueue(Bop->getLHS()); - return true; + return; } } EvaluateExpr(job.E, Result); Queue.pop_back(); - return true; + return; } case Job::BinOpKind: { @@ -4808,26 +4806,26 @@ bool DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) { job.LHSResult.swap(Result); bool IgnoreRHS = false; bool SuppressRHSDiags = false; - bool ret = VisitBinOpLHSOnly(job.LHSResult, Bop, IgnoreRHS, Result.Val, - SuppressRHSDiags); + Result.Failed = !VisitBinOpLHSOnly(job.LHSResult, Bop, IgnoreRHS, + Result.Val, SuppressRHSDiags); if (IgnoreRHS) { Queue.pop_back(); - return ret; + return; } if (SuppressRHSDiags) job.startSpeculativeEval(Info); job.Kind = Job::BinOpVisitedLHSKind; enqueue(Bop->getRHS()); - return ret; + return; } case Job::BinOpVisitedLHSKind: { const BinaryOperator *Bop = cast<BinaryOperator>(job.E); EvalResult RHS; RHS.swap(Result); - bool ret = VisitBinOp(job.LHSResult, RHS, Bop, Result.Val); + Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val); Queue.pop_back(); - return ret; + return; } } |