Correctly propagate uninitialized values within logical expressions.

Fixes assertion failure reported in PR 14635 and
<rdar://problem/12902945> respectively.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172263 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 3444557..1253f88 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -537,24 +537,28 @@
     const Expr *RHS = cast<Expr>(Elem.getStmt());
     SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
 
-    DefinedOrUnknownSVal DefinedRHS = cast<DefinedOrUnknownSVal>(RHSVal);
-    ProgramStateRef StTrue, StFalse;
-    llvm::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS);
-    if (StTrue) {
-      if (StFalse) {
-        // We can't constrain the value to 0 or 1; the best we can do is a cast.
-        X = getSValBuilder().evalCast(RHSVal, B->getType(), RHS->getType());
-      } else {
-        // The value is known to be true.
-        X = getSValBuilder().makeIntVal(1, B->getType());
-      }
+    if (RHSVal.isUndef()) {
+      X = RHSVal;
     } else {
-      // The value is known to be false.
-      assert(StFalse && "Infeasible path!");
-      X = getSValBuilder().makeIntVal(0, B->getType());
+      DefinedOrUnknownSVal DefinedRHS = cast<DefinedOrUnknownSVal>(RHSVal);
+      ProgramStateRef StTrue, StFalse;
+      llvm::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS);
+      if (StTrue) {
+        if (StFalse) {
+          // We can't constrain the value to 0 or 1.
+          // The best we can do is a cast.
+          X = getSValBuilder().evalCast(RHSVal, B->getType(), RHS->getType());
+        } else {
+          // The value is known to be true.
+          X = getSValBuilder().makeIntVal(1, B->getType());
+        }
+      } else {
+        // The value is known to be false.
+        assert(StFalse && "Infeasible path!");
+        X = getSValBuilder().makeIntVal(0, B->getType());
+      }
     }
   }
-
   Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
 }
 
diff --git a/test/Analysis/misc-ps.c b/test/Analysis/misc-ps.c
index ef89321..ef65e0d 100644
--- a/test/Analysis/misc-ps.c
+++ b/test/Analysis/misc-ps.c
@@ -151,3 +151,9 @@
   return 0;
 }
 
+// Test that we handle an uninitialized value within a logical expression.
+void PR14635(int *p) {
+  int a = 0, b;
+  *p = a || b; // expected-warning {{Assigned value is garbage or undefined}}
+}
+