diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index 17233e194e6d78a12d96a6eea8a15f3e47e4380b..9266588163ce5ee992592929b45d6fd9dd6fc2f8 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -72,19 +72,33 @@ public:
 
   virtual SVal evalComplement(NonLoc val) = 0;
 
+  /// Create a new value which represents a binary expression with two non
+  /// location operands.
   virtual SVal evalBinOpNN(const ProgramState *state, BinaryOperator::Opcode op,
                            NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
 
+  /// Create a new value which represents a binary expression with two memory
+  /// location operands.
   virtual SVal evalBinOpLL(const ProgramState *state, BinaryOperator::Opcode op,
                            Loc lhs, Loc rhs, QualType resultTy) = 0;
 
+  /// Create a new value which represents a binary expression with a memory
+  /// location and non location operands. For example, this would be used to
+  /// evaluate a pointer arithmetic operation.
   virtual SVal evalBinOpLN(const ProgramState *state, BinaryOperator::Opcode op,
                            Loc lhs, NonLoc rhs, QualType resultTy) = 0;
 
-  /// getKnownValue - evaluates a given SVal. If the SVal has only one possible
-  ///  (integer) value, that value is returned. Otherwise, returns NULL.
+  /// Evaluates a given SVal. If the SVal has only one possible (integer) value,
+  /// that value is returned. Otherwise, returns NULL.
   virtual const llvm::APSInt *getKnownValue(const ProgramState *state, SVal val) = 0;
   
+  /// Handles generation of the value in case the builder is not smart enough to
+  /// handle the given binary expression. Depending on the state, decides to
+  /// either keep the expression or forget the history and generate an
+  /// UnknownVal.
+  SVal generateUnknownVal(const ProgramState *state, BinaryOperator::Opcode op,
+                          NonLoc lhs, NonLoc rhs, QualType resultTy);
+
   SVal evalBinOp(const ProgramState *state, BinaryOperator::Opcode op,
                  SVal lhs, SVal rhs, QualType type);
   
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index b82dfea58defd040a0289ff109cb058dc96d464e..d74c48d962c785d1de081fa2e907b82efc115a4f 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -361,7 +361,8 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
       // UnknownVal.
       if ((InitVal.isUnknown() ||
            !getConstraintManager().canReasonAbout(InitVal)) &&
-          !VD->getType()->isReferenceType()) {
+          !VD->getType()->isReferenceType() &&
+          !Pred->getState()->isTainted(InitVal)) {
         InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx,
                                  currentBuilderContext->getCurrentBlockCount());
       }
diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp
index f118f4a0f0969c5c7e67599d52ea8bb9b5043a83..db2097c16f20ff5d80093da8d70953f5025eb499 100644
--- a/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -43,12 +43,14 @@ NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
   // The Environment ensures we always get a persistent APSInt in
   // BasicValueFactory, so we don't need to get the APSInt from
   // BasicValueFactory again.
+  assert(lhs);
   assert(!Loc::isLocType(type));
   return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, rhs, type));
 }
 
 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
                                const SymExpr *rhs, QualType type) {
+  assert(lhs && rhs);
   assert(SymMgr.getType(lhs) == SymMgr.getType(rhs));
   assert(!Loc::isLocType(type));
   return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, type));
@@ -162,6 +164,29 @@ DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block,
 
 //===----------------------------------------------------------------------===//
 
+SVal SValBuilder::generateUnknownVal(const ProgramState *State,
+                                     BinaryOperator::Opcode Op,
+                                     NonLoc LHS, NonLoc RHS,
+                                     QualType ResultTy) {
+  // If operands are tainted, create a symbol to ensure that we propagate taint.
+  if (State->isTainted(RHS) || State->isTainted(LHS)) {
+    const SymExpr *symLHS;
+    const SymExpr *symRHS;
+
+    if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS)) {
+      symLHS = LHS.getAsSymExpr();
+      return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
+    }
+    // TODO: Handle the case when lhs is ConcreteInt.
+
+    symLHS = LHS.getAsSymExpr();
+    symRHS = RHS.getAsSymExpr();
+    return makeNonLoc(symLHS, Op, symRHS, ResultTy);
+  }
+  return UnknownVal();
+}
+
+
 SVal SValBuilder::evalBinOp(const ProgramState *state, BinaryOperator::Opcode op,
                             SVal lhs, SVal rhs, QualType type) {
 
diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index bd63ecf775d3c39ea51b98bd54a3cf45a2be4353..f7924319e5bf16e3525452f744d3e100421d293e 100644
--- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -298,7 +298,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
   while (1) {
     switch (lhs.getSubKind()) {
     default:
-      return UnknownVal();
+      return generateUnknownVal(state, op, lhs, rhs, resultTy);
     case nonloc::LocAsIntegerKind: {
       Loc lhsL = cast<nonloc::LocAsInteger>(lhs).getLoc();
       switch (rhs.getSubKind()) {
@@ -321,7 +321,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
               return makeTruthVal(true, resultTy);
             default:
               // This case also handles pointer arithmetic.
-              return UnknownVal();
+              return generateUnknownVal(state, op, lhs, rhs, resultTy);
           }
       }
     }
@@ -333,7 +333,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
         dyn_cast<SymIntExpr>(selhs->getSymbolicExpression());
 
       if (!symIntExpr)
-        return UnknownVal();
+        return generateUnknownVal(state, op, lhs, rhs, resultTy);
 
       // Is this a logical not? (!x is represented as x == 0.)
       if (op == BO_EQ && rhs.isZeroConstant()) {
@@ -381,7 +381,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
       // For now, only handle expressions whose RHS is a constant.
       const nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs);
       if (!rhsInt)
-        return UnknownVal();
+        return generateUnknownVal(state, op, lhs, rhs, resultTy);
 
       // If both the LHS and the current expression are additive,
       // fold their constants.
@@ -467,9 +467,9 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
             if (lhsValue == 0)
               // At this point lhs and rhs have been swapped.
               return rhs;
-            return UnknownVal();
+            return generateUnknownVal(state, op, lhs, rhs, resultTy);
           default:
-            return UnknownVal();
+            return generateUnknownVal(state, op, lhs, rhs, resultTy);
         }
       }
     }
@@ -529,7 +529,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
                              resultTy);
       }
 
-      return UnknownVal();
+      return generateUnknownVal(state, op, lhs, rhs, resultTy);
     }
     }
   }
diff --git a/test/Analysis/taint-generic.c b/test/Analysis/taint-generic.c
index 9179a57dad87bab3aa8c1acf5500aca1927b8e5e..2e3def36709adb5ea0354c3c65243190369b845b 100644
--- a/test/Analysis/taint-generic.c
+++ b/test/Analysis/taint-generic.c
@@ -12,3 +12,17 @@ void bufferFoo1(void)
   scanf("%d", &n);
   Buffer[n] = 1; // expected-warning {{Out of bound memory access }}
 }
+
+void bufferScanfArithmetic1(int x) {
+  int n;
+  scanf("%d", &n);
+  int m = (n - 3);
+  Buffer[m] = 1; // expected-warning {{Out of bound memory access }}
+}
+
+void bufferScanfArithmetic2(int x) {
+  int n;
+  scanf("%d", &n);
+  int m = (n + 3) * x;
+  Buffer[m] = 1; // expected-warning {{Out of bound memory access }}
+}