]> granicus.if.org Git - clang/commitdiff
Change the binary operator data recursive evaluator to not stop at the first
authorRichard Trieu <rtrieu@google.com>
Wed, 21 Mar 2012 23:30:30 +0000 (23:30 +0000)
committerRichard Trieu <rtrieu@google.com>
Wed, 21 Mar 2012 23:30:30 +0000 (23:30 +0000)
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

lib/AST/ExprConstant.cpp
test/Sema/return.c

index 331c757c1246b488bb2b0b557cf401d229f6a4df..583bbfc9883e87a94fad8512955f3b28a51afe6f 100644 (file)
@@ -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;
     }
   }
   
index 7a4c1f8e514cdb9eccaf5473b882ae962671c5cc..77bd3f688ed9e2d90231690c896571af6bebcaa0 100644 (file)
@@ -255,3 +255,12 @@ int test_enum_cases(enum Cases C) {
   case C3: return 4;
   }
 } // no-warning
+
+// PR12318 - Don't give a may reach end of non-void function warning.
+int test34(int x) {
+  if (x == 1) {
+    return 3;
+  } else if ( x == 2 || 1) {
+    return 5;
+  }
+}