]> granicus.if.org Git - clang/commitdiff
Allow EvalBinOpNN to handle expressions of the form $a+$b if $b can be reduced to...
authorJordy Rose <jediknil@belkadan.com>
Mon, 9 Aug 2010 20:31:57 +0000 (20:31 +0000)
committerJordy Rose <jediknil@belkadan.com>
Mon, 9 Aug 2010 20:31:57 +0000 (20:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110592 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Checker/SimpleSValuator.cpp
test/Analysis/misc-ps.m

index 48c8b9a81bddd231ed0df2ebb78c920ec733648c..433c3654fadaa190c0ceb6cb85964466d515a8b2 100644 (file)
@@ -461,10 +461,12 @@ SVal SimpleSValuator::EvalBinOpNN(const GRState *state,
     case nonloc::SymbolValKind: {
       nonloc::SymbolVal *slhs = cast<nonloc::SymbolVal>(&lhs);
       SymbolRef Sym = slhs->getSymbol();
-      
+
+      ASTContext& Ctx = ValMgr.getContext();
+
       // Does the symbol simplify to a constant?  If so, "fold" the constant
       // by setting 'lhs' to a ConcreteInt and try again.
-      if (Sym->getType(ValMgr.getContext())->isIntegerType())
+      if (Sym->getType(Ctx)->isIntegerType())
         if (const llvm::APSInt *Constant = state->getSymVal(Sym)) {
           // The symbol evaluates to a constant. If necessary, promote the
           // folded constant (LHS) to the result type.
@@ -474,7 +476,7 @@ SVal SimpleSValuator::EvalBinOpNN(const GRState *state,
           
           // Also promote the RHS (if necessary).
 
-          // For shifts, it necessary promote the RHS to the result type.
+          // For shifts, it is not necessary to promote the RHS.
           if (BinaryOperator::isShiftOp(op))
             continue;
           
@@ -486,7 +488,20 @@ SVal SimpleSValuator::EvalBinOpNN(const GRState *state,
           
           continue;
         }
-      
+
+      // Is the RHS a symbol we can simplify?
+      if (const nonloc::SymbolVal *srhs = dyn_cast<nonloc::SymbolVal>(&rhs)) {
+        SymbolRef RSym = srhs->getSymbol();
+        if (RSym->getType(Ctx)->isIntegerType()) {
+          if (const llvm::APSInt *Constant = state->getSymVal(RSym)) {
+            // The symbol evaluates to a constant.
+            BasicValueFactory &BVF = ValMgr.getBasicValueFactory();
+            const llvm::APSInt &rhs_I = BVF.Convert(resultTy, *Constant);
+            rhs = nonloc::ConcreteInt(rhs_I);
+          }
+        }
+      }
+
       if (isa<nonloc::ConcreteInt>(rhs)) {
         return MakeSymIntVal(slhs->getSymbol(), op,
                              cast<nonloc::ConcreteInt>(rhs).getValue(),
index a362211049243a954fa822b5999b074cd5b44ce8..f6a92831d7392a8dadffb99ee33f157a3767d292 100644 (file)
@@ -1027,3 +1027,21 @@ float f0(_Complex float x) {
   return  __real l0 + __imag l0;
 }
 
+
+//===----------------------------------------------------------------------===
+// Test that we can reduce symbols to constants whether they are on the left
+//  or right side of an expression.
+//===----------------------------------------------------------------------===
+
+void reduce_to_constant(int x, int y) {
+  if (x != 20)
+    return;
+
+  int a = x + y;
+  int b = y + x;
+
+  if (y == -20 && a != 0)
+    (void)*(char*)0; // no-warning
+  if (y == -20 && b != 0)
+    (void)*(char*)0; // no-warning
+}