Fix false positive null dereference by unifying code paths in GRSimpleVals for
'==' and '!=' (some code in the '!=' was not replicated in the '==' code,
causing some constraints to get lost).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70885 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp
index 8600138..3d1c764 100644
--- a/lib/Analysis/GRSimpleVals.cpp
+++ b/lib/Analysis/GRSimpleVals.cpp
@@ -249,15 +249,11 @@
                              Loc L, Loc R) {
   
   switch (Op) {
-
     default:
-      return UnknownVal();
-      
+      return UnknownVal();      
     case BinaryOperator::EQ:
-      return EvalEQ(Eng, L, R);
-      
     case BinaryOperator::NE:
-      return EvalNE(Eng, L, R);      
+      return EvalEquality(Eng, L, R, Op == BinaryOperator::EQ);
   }
 }
 
@@ -286,14 +282,14 @@
 // FIXME: All this logic will be revamped when we have MemRegion::getLocation()
 // implemented.
 
-SVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, Loc L, Loc R) {
+SVal GRSimpleVals::EvalEquality(GRExprEngine& Eng, Loc L, Loc R, bool isEqual) {
   
   BasicValueFactory& BasicVals = Eng.getBasicVals();
 
   switch (L.getSubKind()) {
 
     default:
-      assert(false && "EQ not implemented for this Loc.");
+      assert(false && "EQ/NE not implemented for this Loc.");
       return UnknownVal();
       
     case loc::ConcreteIntKind:
@@ -302,8 +298,21 @@
         bool b = cast<loc::ConcreteInt>(L).getValue() ==
                  cast<loc::ConcreteInt>(R).getValue();
         
+        // Are we computing '!='?  Flip the result.
+        if (!isEqual)
+          b = !b;
+        
         return NonLoc::MakeIntTruthVal(BasicVals, b);
       }
+      else if (SymbolRef Sym = R.getAsSymbol()) {
+        const SymIntExpr * SE =
+        Eng.getSymbolManager().getSymIntExpr(Sym,
+                                             isEqual ? BinaryOperator::EQ
+                                                     : BinaryOperator::NE,
+                                             cast<loc::ConcreteInt>(L).getValue(),
+                                             Eng.getContext().IntTy);
+        return nonloc::SymExprVal(SE);
+      }
       
       break;
       
@@ -311,7 +320,9 @@
       if (SymbolRef LSym = L.getAsLocSymbol()) {
         if (isa<loc::ConcreteInt>(R)) {
           const SymIntExpr *SE =
-            Eng.getSymbolManager().getSymIntExpr(LSym, BinaryOperator::EQ,
+            Eng.getSymbolManager().getSymIntExpr(LSym,
+                                           isEqual ? BinaryOperator::EQ
+                                                   : BinaryOperator::NE,
                                            cast<loc::ConcreteInt>(R).getValue(),
                                            Eng.getContext().IntTy);
         
@@ -323,58 +334,10 @@
     // Fall-through.
       
     case loc::GotoLabelKind:
-      return NonLoc::MakeIntTruthVal(BasicVals, L == R);
+      return NonLoc::MakeIntTruthVal(BasicVals, isEqual ? L == R : L != R);
   }
   
-  return NonLoc::MakeIntTruthVal(BasicVals, false);
-}
-
-SVal GRSimpleVals::EvalNE(GRExprEngine& Eng, Loc L, Loc R) {
-  
-  BasicValueFactory& BasicVals = Eng.getBasicVals();
-
-  switch (L.getSubKind()) {
-
-    default:
-      assert(false && "NE not implemented for this Loc.");
-      return UnknownVal();
-      
-    case loc::ConcreteIntKind:
-      
-      if (isa<loc::ConcreteInt>(R)) {
-        bool b = cast<loc::ConcreteInt>(L).getValue() !=
-                 cast<loc::ConcreteInt>(R).getValue();
-        
-        return NonLoc::MakeIntTruthVal(BasicVals, b);
-      }
-      else if (SymbolRef Sym = R.getAsSymbol()) {
-        const SymIntExpr * SE =
-          Eng.getSymbolManager().getSymIntExpr(Sym, BinaryOperator::NE,
-                                           cast<loc::ConcreteInt>(L).getValue(),
-                                             Eng.getContext().IntTy);
-        return nonloc::SymExprVal(SE);
-      }
-      
-      break;
-
-    case loc::MemRegionKind: {
-      if (SymbolRef LSym = L.getAsLocSymbol()) {
-        if (isa<loc::ConcreteInt>(R)) {
-          const SymIntExpr* SE =
-            Eng.getSymbolManager().getSymIntExpr(LSym, BinaryOperator::NE,
-                                          cast<loc::ConcreteInt>(R).getValue(),
-                                                 Eng.getContext().IntTy);
-          return nonloc::SymExprVal(SE);
-        }
-      }
-      // Fall through:
-    }
-      
-    case loc::GotoLabelKind:
-      return NonLoc::MakeIntTruthVal(BasicVals, L != R);
-  }
-  
-  return NonLoc::MakeIntTruthVal(BasicVals, true);
+  return NonLoc::MakeIntTruthVal(BasicVals, isEqual ? false : true);
 }
 
 //===----------------------------------------------------------------------===//