[cfe-commits] r81579 - in /cfe/trunk: include/clang/Analysis/PathSensitive/ lib/Analysis/ test/Analysis/

Ted Kremenek kremenek at apple.com
Fri Sep 11 15:07:29 PDT 2009


Author: kremenek
Date: Fri Sep 11 17:07:28 2009
New Revision: 81579

URL: http://llvm.org/viewvc/llvm-project?rev=81579&view=rev
Log:
Introduce "DefinedOrUnknownSVal" into the SVal class hierarchy, providing a way
to statically type various methods in SValuator/GRState as required either a
defined value or a defined-but-possibly-unknown value. This leads to various
logic cleanups in GRExprEngine, and lets the compiler enforce via type checking
our assumptions about what symbolic values are possibly undefined and what are
not.

Along the way, clean up some of the static analyzer diagnostics regarding the uses of uninitialized values.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/ConstraintManager.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
    cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
    cfe/trunk/include/clang/Analysis/PathSensitive/SValuator.h
    cfe/trunk/include/clang/Analysis/PathSensitive/ValueManager.h
    cfe/trunk/lib/Analysis/BasicStore.cpp
    cfe/trunk/lib/Analysis/BugReporter.cpp
    cfe/trunk/lib/Analysis/BugReporterVisitors.cpp
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp
    cfe/trunk/lib/Analysis/SValuator.cpp
    cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp
    cfe/trunk/lib/Analysis/SimpleConstraintManager.h
    cfe/trunk/lib/Analysis/SimpleSValuator.cpp
    cfe/trunk/lib/Analysis/ValueManager.cpp
    cfe/trunk/test/Analysis/uninit-vals-ps-region.c
    cfe/trunk/test/Analysis/uninit-vals-ps.c

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ConstraintManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ConstraintManager.h?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ConstraintManager.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ConstraintManager.h Fri Sep 11 17:07:28 2009
@@ -30,11 +30,11 @@
 class ConstraintManager {
 public:
   virtual ~ConstraintManager();
-  virtual const GRState *Assume(const GRState *state, SVal Cond,
+  virtual const GRState *Assume(const GRState *state, DefinedSVal Cond,
                                 bool Assumption) = 0;
 
-  virtual const GRState *AssumeInBound(const GRState *state, SVal Idx,
-                                       SVal UpperBound, bool Assumption) = 0;
+  virtual const GRState *AssumeInBound(const GRState *state, DefinedSVal Idx,
+                                       DefinedSVal UpperBound, bool Assumption) = 0;
 
   std::pair<const GRState*, const GRState*> AssumeDual(const GRState *state,
                                                        DefinedSVal Cond) {

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Fri Sep 11 17:07:28 2009
@@ -134,7 +134,7 @@
   ///  taking a dereference on a symbolic pointer that MUST be NULL.
   ErrorNodes ExplicitNullDeref;
 
-  /// UnitDeref - Nodes in the ExplodedGraph that result from
+  /// UndefDeref - Nodes in the ExplodedGraph that result from
   ///  taking a dereference on an undefined value.
   ErrorNodes UndefDeref;
 
@@ -596,9 +596,8 @@
                  SVal LHS, SVal RHS, QualType T) {
     return SVator.EvalBinOp(ST, Op, LHS, RHS, T);
   }
-
+  
 protected:
-
   void EvalCall(ExplodedNodeSet& Dst, CallExpr* CE, SVal L, ExplodedNode* Pred);
 
   void EvalObjCMessageExpr(ExplodedNodeSet& Dst, ObjCMessageExpr* ME, ExplodedNode* Pred) {

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h Fri Sep 11 17:07:28 2009
@@ -194,9 +194,10 @@
   //  (i.e., (b) could just be set to NULL).
   //
 
-  const GRState *assume(SVal condition, bool assumption) const;
+  const GRState *Assume(DefinedOrUnknownSVal cond, bool assumption) const;
 
-  const GRState *assumeInBound(SVal idx, SVal upperBound,
+  const GRState *AssumeInBound(DefinedOrUnknownSVal idx,
+                               DefinedOrUnknownSVal upperBound,
                                bool assumption) const;
 
   //==---------------------------------------------------------------------==//
@@ -570,13 +571,24 @@
   return getStateManager().getRegionManager().getVarRegion(D, LC);
 }
 
-inline const GRState *GRState::assume(SVal Cond, bool Assumption) const {
-  return getStateManager().ConstraintMgr->Assume(this, Cond, Assumption);
+inline const GRState *GRState::Assume(DefinedOrUnknownSVal Cond,
+                                      bool Assumption) const {
+  if (Cond.isUnknown())
+    return this;
+  
+  return getStateManager().ConstraintMgr->Assume(this, cast<DefinedSVal>(Cond),
+                                                 Assumption);
 }
 
-inline const GRState *GRState::assumeInBound(SVal Idx, SVal UpperBound,
+inline const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
+                                             DefinedOrUnknownSVal UpperBound,
                                              bool Assumption) const {
-  return getStateManager().ConstraintMgr->AssumeInBound(this, Idx, UpperBound, Assumption);
+  if (Idx.isUnknown() || UpperBound.isUnknown())
+    return this;
+
+  ConstraintManager &CM = *getStateManager().ConstraintMgr;
+  return CM.AssumeInBound(this, cast<DefinedSVal>(Idx),
+                           cast<DefinedSVal>(UpperBound), Assumption);
 }
 
 inline const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h Fri Sep 11 17:07:28 2009
@@ -152,14 +152,6 @@
   static inline bool classof(const SVal*) { return true; }
 };
 
-class UnknownVal : public SVal {
-public:
-  UnknownVal() : SVal(UnknownKind) {}
-
-  static inline bool classof(const SVal* V) {
-    return V->getBaseKind() == UnknownKind;
-  }
-};
 
 class UndefinedVal : public SVal {
 public:
@@ -173,10 +165,46 @@
   void* getData() const { return Data; }
 };
 
-class DefinedSVal : public SVal {
+class DefinedOrUnknownSVal : public SVal {
+private:
+  // Do not implement.  We want calling these methods to be a compiler
+  // error since they are tautologically false.
+  bool isUndef() const;
+  bool isValid() const;
+  
 protected:
-  DefinedSVal(const void* d, bool isLoc, unsigned ValKind)
+  explicit DefinedOrUnknownSVal(const void* d, bool isLoc, unsigned ValKind)
     : SVal(d, isLoc, ValKind) {}
+  
+  explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
+    : SVal(k, D) {}
+  
+public:
+    // Implement isa<T> support.
+  static inline bool classof(const SVal *V) {
+    return !V->isUndef();
+  }
+};
+  
+class UnknownVal : public DefinedOrUnknownSVal {
+public:
+  UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
+  
+  static inline bool classof(const SVal *V) {
+    return V->getBaseKind() == UnknownKind;
+  }
+};
+  
+class DefinedSVal : public DefinedOrUnknownSVal {
+private:
+  // Do not implement.  We want calling these methods to be a compiler
+  // error since they are tautologically true/false.
+  bool isUnknown() const;
+  bool isUnknownOrUndef() const;
+  bool isValid() const;  
+protected:
+  DefinedSVal(const void* d, bool isLoc, unsigned ValKind)
+    : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
 public:
   // Implement isa<T> support.
   static inline bool classof(const SVal *V) {

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SValuator.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SValuator.h?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SValuator.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SValuator.h Fri Sep 11 17:07:28 2009
@@ -36,16 +36,32 @@
   SValuator(ValueManager &valMgr) : ValMgr(valMgr) {}
   virtual ~SValuator() {}
 
-  class CastResult : public std::pair<const GRState *, SVal> {
+  template <typename T>
+  class GenericCastResult : public std::pair<const GRState *, T> {
   public:
-    const GRState *getState() const { return first; }
-    SVal getSVal() const { return second; }
-    CastResult(const GRState *s, SVal v)
-      : std::pair<const GRState*, SVal>(s, v) {}
+    const GRState *getState() const { return this->first; }
+    T getSVal() const { return this->second; }
+    GenericCastResult(const GRState *s, T v)
+      : std::pair<const GRState*,T>(s, v) {}
+  };
+  
+  class CastResult : public GenericCastResult<SVal> {
+  public:
+    CastResult(const GRState *s, SVal v) : GenericCastResult<SVal>(s, v) {}
+  };
+  
+  class DefinedOrUnknownCastResult :
+    public GenericCastResult<DefinedOrUnknownSVal> {
+  public:
+    DefinedOrUnknownCastResult(const GRState *s, DefinedOrUnknownSVal v)
+      : GenericCastResult<DefinedOrUnknownSVal>(s, v) {}
   };
 
-  CastResult EvalCast(SVal val, const GRState *state,
+  CastResult EvalCast(SVal V, const GRState *ST,
                       QualType castTy, QualType originalType);
+  
+  DefinedOrUnknownCastResult EvalCast(DefinedOrUnknownSVal V, const GRState *ST,
+                                      QualType castTy, QualType originalType);
 
   virtual SVal EvalMinus(NonLoc val) = 0;
 
@@ -59,9 +75,12 @@
 
   virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode Op,
                            Loc lhs, NonLoc rhs, QualType resultTy) = 0;
-
+  
   SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
                  SVal L, SVal R, QualType T);
+  
+  DefinedOrUnknownSVal EvalEQ(const GRState *ST, DefinedOrUnknownSVal L,
+                              DefinedOrUnknownSVal R);
 };
 
 SValuator* CreateSimpleSValuator(ValueManager &valMgr);

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ValueManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ValueManager.h?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ValueManager.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ValueManager.h Fri Sep 11 17:07:28 2009
@@ -91,23 +91,27 @@
   }
 
   /// makeZeroVal - Construct an SVal representing '0' for the specified type.
-  SVal makeZeroVal(QualType T);
+  DefinedOrUnknownSVal makeZeroVal(QualType T);
 
   /// getRegionValueSymbolVal - make a unique symbol for value of R.
-  SVal getRegionValueSymbolVal(const MemRegion *R, QualType T = QualType());
+  DefinedOrUnknownSVal getRegionValueSymbolVal(const MemRegion *R,
+                                               QualType T = QualType());
 
-  SVal getRegionValueSymbolValOrUnknown(const MemRegion *R, QualType T) {
-    return SymMgr.canSymbolicate(T) ? getRegionValueSymbolVal(R, T)
-                                    : UnknownVal();
+  DefinedOrUnknownSVal getRegionValueSymbolValOrUnknown(const MemRegion *R,
+                                                        QualType T) {
+    if (SymMgr.canSymbolicate(T))
+      return getRegionValueSymbolVal(R, T);
+    return UnknownVal();
   }
 
-  SVal getConjuredSymbolVal(const Expr *E, unsigned Count);
-  SVal getConjuredSymbolVal(const Expr* E, QualType T, unsigned Count);
+  DefinedOrUnknownSVal getConjuredSymbolVal(const Expr *E, unsigned Count);
+  DefinedOrUnknownSVal getConjuredSymbolVal(const Expr *E, QualType T,
+                                            unsigned Count);
 
-  SVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
-                                      const TypedRegion *R);
+  DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
+                                                      const TypedRegion *R);
 
-  SVal getFunctionPointer(const FunctionDecl* FD);
+  DefinedSVal getFunctionPointer(const FunctionDecl *FD);
 
   NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) {
     return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
@@ -144,7 +148,7 @@
     return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned));
   }
 
-  SVal makeIntVal(uint64_t X, QualType T) {
+  DefinedSVal makeIntVal(uint64_t X, QualType T) {
     if (Loc::IsLocType(T))
       return loc::ConcreteInt(BasicVals.getValue(X, T));
 

Modified: cfe/trunk/lib/Analysis/BasicStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicStore.cpp?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/BasicStore.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicStore.cpp Fri Sep 11 17:07:28 2009
@@ -530,9 +530,9 @@
       // Initialize globals and parameters to symbolic values.
       // Initialize local variables to undefined.
       const MemRegion *R = ValMgr.getRegionManager().getVarRegion(VD, InitLoc);
-      SVal X = R->hasGlobalsOrParametersStorage()
-               ? ValMgr.getRegionValueSymbolVal(R)
-               : UndefinedVal();
+      SVal X = UndefinedVal();
+      if (R->hasGlobalsOrParametersStorage())
+        X = ValMgr.getRegionValueSymbolVal(R);
 
       St = BindInternal(St, ValMgr.makeLoc(R), X);
     }

Modified: cfe/trunk/lib/Analysis/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BugReporter.cpp?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Fri Sep 11 17:07:28 2009
@@ -1259,8 +1259,11 @@
   if (EndNode)
     if (const Stmt* S = GetCurrentOrPreviousStmt(EndNode)) {
       // For member expressions, return the location of the '.' or '->'.
-      if (const MemberExpr* ME = dyn_cast<MemberExpr>(S))
+      if (const MemberExpr *ME = dyn_cast<MemberExpr>(S))
         return ME->getMemberLoc();
+      // For binary operators, return the location of the operator.
+      if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S))
+        return B->getOperatorLoc();
 
       return S->getLocStart();
     }

Modified: cfe/trunk/lib/Analysis/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BugReporterVisitors.cpp?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporterVisitors.cpp Fri Sep 11 17:07:28 2009
@@ -232,11 +232,11 @@
 }
 
 class VISIBILITY_HIDDEN TrackConstraintBRVisitor : public BugReporterVisitor {
-  SVal Constraint;
+  DefinedSVal Constraint;
   const bool Assumption;
   bool isSatisfied;
 public:
-  TrackConstraintBRVisitor(SVal constraint, bool assumption)
+  TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
   : Constraint(constraint), Assumption(assumption), isSatisfied(false) {}
 
   PathDiagnosticPiece* VisitNode(const ExplodedNode *N,
@@ -247,14 +247,14 @@
 
     // Check if in the previous state it was feasible for this constraint
     // to *not* be true.
-    if (PrevN->getState()->assume(Constraint, !Assumption)) {
+    if (PrevN->getState()->Assume(Constraint, !Assumption)) {
 
       isSatisfied = true;
 
       // As a sanity check, make sure that the negation of the constraint
       // was infeasible in the current state.  If it is feasible, we somehow
       // missed the transition point.
-      if (N->getState()->assume(Constraint, !Assumption))
+      if (N->getState()->Assume(Constraint, !Assumption))
         return NULL;
 
       // We found the transition point for the constraint.  We now need to
@@ -295,7 +295,8 @@
 };
 } // end anonymous namespace
 
-static void registerTrackConstraint(BugReporterContext& BRC, SVal Constraint,
+static void registerTrackConstraint(BugReporterContext& BRC,
+                                    DefinedSVal Constraint,
                                     bool Assumption) {
   BRC.addVisitor(new TrackConstraintBRVisitor(Constraint, Assumption));
 }

Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Fri Sep 11 17:07:28 2009
@@ -214,12 +214,15 @@
       if (T->isIntegerType())
         if (const MemRegion *R = state->getRegion(PD, InitLoc)) {
           SVal V = state->getSVal(loc::MemRegionVal(R));
-          SVal Constraint = EvalBinOp(state, BinaryOperator::GT, V,
-                                      ValMgr.makeZeroVal(T),
-                                      getContext().IntTy);
-
-          if (const GRState *newState = state->assume(Constraint, true))
-            state = newState;
+          SVal Constraint_untested = EvalBinOp(state, BinaryOperator::GT, V,
+                                               ValMgr.makeZeroVal(T),
+                                               getContext().IntTy);
+
+          if (DefinedOrUnknownSVal *Constraint =
+              dyn_cast<DefinedOrUnknownSVal>(&Constraint_untested)) {
+            if (const GRState *newState = state->Assume(*Constraint, true))
+              state = newState;
+          }
         }
     }
   }
@@ -232,7 +235,7 @@
     
     if (const Loc *LV = dyn_cast<Loc>(&V)) {
       // Assume that the pointer value in 'self' is non-null.
-      state = state->assume(*LV, true);
+      state = state->Assume(*LV, true);
       assert(state && "'self' cannot be null");
     }
   }
@@ -710,37 +713,38 @@
                                 "Error evaluating branch");
 
   const GRState* PrevState = builder.getState();
-  SVal V = PrevState->getSVal(Condition);
-
-  switch (V.getBaseKind()) {
-    default:
-      break;
+  SVal X = PrevState->getSVal(Condition);
+  DefinedSVal *V = NULL;
+  
+  while (true) {
+    V = dyn_cast<DefinedSVal>(&X);
 
-    case SVal::UnknownKind: {
-      if (Expr *Ex = dyn_cast<Expr>(Condition)) {
+    if (!V) {
+      if (X.isUnknown()) {
+        if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
           if (Ex->getType()->isIntegerType()) {
-          // Try to recover some path-sensitivity.  Right now casts of symbolic
-          // integers that promote their values are currently not tracked well.
-          // If 'Condition' is such an expression, try and recover the
-          // underlying value and use that instead.
-          SVal recovered = RecoverCastedSymbol(getStateManager(),
-                                               builder.getState(), Condition,
-                                               getContext());
-
-          if (!recovered.isUnknown()) {
-            V = recovered;
-            break;
+            // Try to recover some path-sensitivity.  Right now casts of symbolic
+            // integers that promote their values are currently not tracked well.
+            // If 'Condition' is such an expression, try and recover the
+            // underlying value and use that instead.
+            SVal recovered = RecoverCastedSymbol(getStateManager(),
+                                                 builder.getState(), Condition,
+                                                 getContext());
+
+            if (!recovered.isUnknown()) {
+              X = recovered;
+              continue;
+            }
           }
-        }
-      }
+        }    
 
-      builder.generateNode(MarkBranch(PrevState, Term, true), true);
-      builder.generateNode(MarkBranch(PrevState, Term, false), false);
-      return;
-    }
+        builder.generateNode(MarkBranch(PrevState, Term, true), true);
+        builder.generateNode(MarkBranch(PrevState, Term, false), false);
+        return;
+      }
 
-    case SVal::UndefinedKind: {
-      ExplodedNode* N = builder.generateNode(PrevState, true);
+      assert(X.isUndef());
+      ExplodedNode *N = builder.generateNode(PrevState, true);
 
       if (N) {
         N->markAsSink();
@@ -750,11 +754,13 @@
       builder.markInfeasible(false);
       return;
     }
+    
+    break;
   }
 
   // Process the true branch.
   if (builder.isFeasible(true)) {
-    if (const GRState *state = PrevState->assume(V, true))
+    if (const GRState *state = PrevState->Assume(*V, true))
       builder.generateNode(MarkBranch(state, Term, true), true);
     else
       builder.markInfeasible(true);
@@ -762,7 +768,7 @@
 
   // Process the false branch.
   if (builder.isFeasible(false)) {
-    if (const GRState *state = PrevState->assume(V, false))
+    if (const GRState *state = PrevState->Assume(*V, false))
       builder.generateNode(MarkBranch(state, Term, false), false);
     else
       builder.markInfeasible(false);
@@ -838,15 +844,16 @@
   typedef GRSwitchNodeBuilder::iterator iterator;
   const GRState* state = builder.getState();
   Expr* CondE = builder.getCondition();
-  SVal  CondV = state->getSVal(CondE);
+  SVal  CondV_untested = state->getSVal(CondE);
 
-  if (CondV.isUndef()) {
+  if (CondV_untested.isUndef()) {
     ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
     UndefBranches.insert(N);
     return;
   }
+  DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
 
-  const GRState*  DefaultSt = state;
+  const GRState *DefaultSt = state;
   bool defaultIsFeasible = false;
 
   for (iterator I = builder.begin(), EI = builder.end(); I != EI; ++I) {
@@ -881,11 +888,10 @@
 
     do {
       nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1.Val.getInt()));
-      SVal Res = EvalBinOp(DefaultSt, BinaryOperator::EQ, CondV, CaseVal,
-                           getContext().IntTy);
-
+      DefinedOrUnknownSVal Res = SVator.EvalEQ(DefaultSt, CondV, CaseVal);
+            
       // Now "assume" that the case matches.
-      if (const GRState* stateNew = state->assume(Res, true)) {
+      if (const GRState* stateNew = state->Assume(Res, true)) {
         builder.generateCaseStmtNode(I, stateNew);
 
         // If CondV evaluates to a constant, then we know that this
@@ -897,7 +903,7 @@
 
       // Now "assume" that the case doesn't match.  Add this state
       // to the default state (if it is feasible).
-      if (const GRState *stateNew = DefaultSt->assume(Res, false)) {
+      if (const GRState *stateNew = DefaultSt->Assume(Res, false)) {
         defaultIsFeasible = true;
         DefaultSt = stateNew;
       }
@@ -933,20 +939,19 @@
   SVal X = state->getSVal(B);
   assert(X.isUndef());
 
-  Expr* Ex = (Expr*) cast<UndefinedVal>(X).getData();
-
+  const Expr *Ex = (const Expr*) cast<UndefinedVal>(X).getData();
   assert(Ex);
 
   if (Ex == B->getRHS()) {
-
     X = state->getSVal(Ex);
 
     // Handle undefined values.
-
     if (X.isUndef()) {
       MakeNode(Dst, B, Pred, state->BindExpr(B, X));
       return;
     }
+    
+    DefinedOrUnknownSVal XD = cast<DefinedOrUnknownSVal>(X);
 
     // We took the RHS.  Because the value of the '&&' or '||' expression must
     // evaluate to 0 or 1, we must assume the value of the RHS evaluates to 0
@@ -954,11 +959,11 @@
     // value later when necessary.  We don't have the machinery in place for
     // this right now, and since most logical expressions are used for branches,
     // the payoff is not likely to be large.  Instead, we do eager evaluation.
-    if (const GRState *newState = state->assume(X, true))
+    if (const GRState *newState = state->Assume(XD, true))
       MakeNode(Dst, B, Pred,
                newState->BindExpr(B, ValMgr.makeIntVal(1U, B->getType())));
 
-    if (const GRState *newState = state->assume(X, false))
+    if (const GRState *newState = state->Assume(XD, false))
       MakeNode(Dst, B, Pred,
                newState->BindExpr(B, ValMgr.makeIntVal(0U, B->getType())));
   }
@@ -979,9 +984,8 @@
 void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
                                     ExplodedNodeSet &Dst, bool asLValue) {
 
-  const GRState* state = GetState(Pred);
-
-  const NamedDecl* D = Ex->getDecl();
+  const GRState *state = GetState(Pred);
+  const NamedDecl *D = Ex->getDecl();
 
   if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
 
@@ -1225,10 +1229,10 @@
   Loc LV = cast<Loc>(location);
 
   // "Assume" that the pointer is not NULL.
-  const GRState *StNotNull = state->assume(LV, true);
+  const GRState *StNotNull = state->Assume(LV, true);
 
   // "Assume" that the pointer is NULL.
-  const GRState *StNull = state->assume(LV, false);
+  const GRState *StNull = state->Assume(LV, false);
 
   if (StNull) {
     // Use the Generic Data Map to mark in the state what lval was null.
@@ -1264,9 +1268,9 @@
       SVal NumElements = getStoreManager().getSizeInElements(StNotNull,
                                                           ER->getSuperRegion());
 
-      const GRState * StInBound = StNotNull->assumeInBound(Idx, NumElements,
+      const GRState * StInBound = StNotNull->AssumeInBound(Idx, NumElements,
                                                            true);
-      const GRState* StOutBound = StNotNull->assumeInBound(Idx, NumElements,
+      const GRState* StOutBound = StNotNull->AssumeInBound(Idx, NumElements,
                                                            false);
 
       if (StOutBound) {
@@ -1361,21 +1365,26 @@
 
     ExplodedNode *N = *I;
     const GRState *stateLoad = N->getState();
-    SVal theValueVal = stateLoad->getSVal(theValueExpr);
-    SVal oldValueVal = stateLoad->getSVal(oldValueExpr);
+    SVal theValueVal_untested = stateLoad->getSVal(theValueExpr);
+    SVal oldValueVal_untested = stateLoad->getSVal(oldValueExpr);
 
     // FIXME: Issue an error.
-    if (theValueVal.isUndef() || oldValueVal.isUndef()) {
+    if (theValueVal_untested.isUndef() || oldValueVal_untested.isUndef()) {
       return false;
     }
+    
+    DefinedOrUnknownSVal theValueVal =
+      cast<DefinedOrUnknownSVal>(theValueVal_untested);
+    DefinedOrUnknownSVal oldValueVal =
+      cast<DefinedOrUnknownSVal>(oldValueVal_untested);
 
     SValuator &SVator = Engine.getSValuator();
 
     // Perform the comparison.
-    SVal Cmp = SVator.EvalBinOp(stateLoad, BinaryOperator::EQ, theValueVal,
-                                oldValueVal, Engine.getContext().IntTy);
+    DefinedOrUnknownSVal Cmp = SVator.EvalEQ(stateLoad, theValueVal,
+                                             oldValueVal);
 
-    const GRState *stateEqual = stateLoad->assume(Cmp, true);
+    const GRState *stateEqual = stateLoad->Assume(Cmp, true);
 
     // Were they equal?
     if (stateEqual) {
@@ -1404,7 +1413,7 @@
     }
 
     // Were they not equal?
-    if (const GRState *stateNotEqual = stateLoad->assume(Cmp, false)) {
+    if (const GRState *stateNotEqual = stateLoad->Assume(Cmp, false)) {
       SVal Res = Engine.getValueManager().makeTruthVal(false, CE->getType());
       Engine.MakeNode(Dst, CE, N, stateNotEqual->BindExpr(CE, Res));
     }
@@ -1687,9 +1696,9 @@
 
     const GRState* state = Pred->getState();
     SVal V = state->getSVal(Ex);
-    if (isa<nonloc::SymExprVal>(V)) {
+    if (nonloc::SymExprVal *SEV = dyn_cast<nonloc::SymExprVal>(&V)) {
       // First assume that the condition is true.
-      if (const GRState *stateTrue = state->assume(V, true)) {
+      if (const GRState *stateTrue = state->Assume(*SEV, true)) {
         stateTrue = stateTrue->BindExpr(Ex,
                                         ValMgr.makeIntVal(1U, Ex->getType()));
         Dst.Add(Builder->generateNode(PostStmtCustom(Ex,
@@ -1698,7 +1707,7 @@
       }
 
       // Next, assume that the condition is false.
-      if (const GRState *stateFalse = state->assume(V, false)) {
+      if (const GRState *stateFalse = state->Assume(*SEV, false)) {
         stateFalse = stateFalse->BindExpr(Ex,
                                           ValMgr.makeIntVal(0U, Ex->getType()));
         Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag,
@@ -1887,10 +1896,10 @@
 
   if (Expr* Receiver = ME->getReceiver()) {
 
-    SVal L = state->getSVal(Receiver);
+    SVal L_untested = state->getSVal(Receiver);
 
     // Check for undefined control-flow.
-    if (L.isUndef()) {
+    if (L_untested.isUndef()) {
       ExplodedNode* N = Builder->generateNode(ME, state, Pred);
 
       if (N) {
@@ -1902,10 +1911,11 @@
     }
 
     // "Assume" that the receiver is not NULL.
-    const GRState *StNotNull = state->assume(L, true);
+    DefinedOrUnknownSVal L = cast<DefinedOrUnknownSVal>(L_untested);
+    const GRState *StNotNull = state->Assume(L, true);
 
     // "Assume" that the receiver is NULL.
-    const GRState *StNull = state->assume(L, false);
+    const GRState *StNull = state->Assume(L, false);
 
     if (StNull) {
       QualType RetTy = ME->getType();
@@ -2154,9 +2164,9 @@
       // FIXME: Handle multi-dimensional VLAs.
 
       Expr* SE = VLA->getSizeExpr();
-      SVal Size = state->getSVal(SE);
+      SVal Size_untested = state->getSVal(SE);
 
-      if (Size.isUndef()) {
+      if (Size_untested.isUndef()) {
         if (ExplodedNode* N = Builder->generateNode(DS, state, Pred)) {
           N->markAsSink();
           ExplicitBadSizedVLA.insert(N);
@@ -2164,8 +2174,9 @@
         continue;
       }
 
-      const GRState* zeroState =  state->assume(Size, false);
-      state = state->assume(Size, true);
+      DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Size_untested);
+      const GRState *zeroState =  state->Assume(Size, false);
+      state = state->Assume(Size, true);
 
       if (zeroState) {
         if (ExplodedNode* N = Builder->generateNode(DS, zeroState, Pred)) {
@@ -2557,13 +2568,14 @@
     for (ExplodedNodeSet::iterator I2 = Tmp2.begin(), E2 = Tmp2.end(); I2!=E2; ++I2) {
 
       state = GetState(*I2);
-      SVal V2 = state->getSVal(Ex);
+      SVal V2_untested = state->getSVal(Ex);
 
       // Propagate unknown and undefined values.
-      if (V2.isUnknownOrUndef()) {
-        MakeNode(Dst, U, *I2, state->BindExpr(U, V2));
+      if (V2_untested.isUnknownOrUndef()) {
+        MakeNode(Dst, U, *I2, state->BindExpr(U, V2_untested));
         continue;
-      }
+      }      
+      DefinedSVal V2 = cast<DefinedSVal>(V2_untested);
 
       // Handle all other values.
       BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add
@@ -2583,25 +2595,25 @@
 
       // Conjure a new symbol if necessary to recover precision.
       if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){
-        Result = ValMgr.getConjuredSymbolVal(Ex,
-                                             Builder->getCurrentBlockCount());
+        DefinedOrUnknownSVal SymVal =
+          ValMgr.getConjuredSymbolVal(Ex, Builder->getCurrentBlockCount());
+        Result = SymVal;
 
         // If the value is a location, ++/-- should always preserve
         // non-nullness.  Check if the original value was non-null, and if so
         // propagate that constraint.
         if (Loc::IsLocType(U->getType())) {
-          SVal Constraint = EvalBinOp(state, BinaryOperator::EQ, V2,
-                                      ValMgr.makeZeroVal(U->getType()),
-                                      getContext().IntTy);
+          DefinedOrUnknownSVal Constraint =
+            SVator.EvalEQ(state, V2, ValMgr.makeZeroVal(U->getType()));
 
-          if (!state->assume(Constraint, true)) {
+          if (!state->Assume(Constraint, true)) {
             // It isn't feasible for the original value to be null.
             // Propagate this constraint.
-            Constraint = EvalBinOp(state, BinaryOperator::EQ, Result,
-                                   ValMgr.makeZeroVal(U->getType()),
-                                   getContext().IntTy);
+            Constraint = SVator.EvalEQ(state, SymVal,
+                                       ValMgr.makeZeroVal(U->getType()));
+
 
-            state = state->assume(Constraint, false);
+            state = state->Assume(Constraint, false);
             assert(state);
           }
         }
@@ -2759,11 +2771,7 @@
     Visit(LHS, Pred, Tmp1);
 
   for (ExplodedNodeSet::iterator I1=Tmp1.begin(), E1=Tmp1.end(); I1!=E1; ++I1) {
-
     SVal LeftV = (*I1)->getState()->getSVal(LHS);
-
-    // Process the RHS.
-
     ExplodedNodeSet Tmp2;
     Visit(RHS, *I1, Tmp2);
 
@@ -2775,14 +2783,12 @@
     for (ExplodedNodeSet::iterator I2=CheckedSet.begin(), E2=CheckedSet.end();
          I2 != E2; ++I2) {
 
-      const GRState* state = GetState(*I2);
-      const GRState* OldSt = state;
-
+      const GRState *state = GetState(*I2);
+      const GRState *OldSt = state;
       SVal RightV = state->getSVal(RHS);
-      BinaryOperator::Opcode Op = B->getOpcode();
 
+      BinaryOperator::Opcode Op = B->getOpcode();
       switch (Op) {
-
         case BinaryOperator::Assign: {
 
           // EXPERIMENTAL: "Conjured" symbols.
@@ -2826,22 +2832,20 @@
             continue;
           }
 
-          if (Result.isUndef() && !LeftV.isUndef() && !RightV.isUndef()) {
+          state = state->BindExpr(B, Result);
 
+          if (Result.isUndef()) {
             // The operands were *not* undefined, but the result is undefined.
             // This is a special node that should be flagged as an error.
-
-            if (ExplodedNode* UndefNode = Builder->generateNode(B, state, *I2)){
+            if (ExplodedNode *UndefNode = Builder->generateNode(B, state, *I2)){
               UndefNode->markAsSink();
               UndefResults.insert(UndefNode);
             }
-
             continue;
           }
 
           // Otherwise, create a new node.
-
-          MakeNode(Dst, B, *I2, state->BindExpr(B, Result));
+          MakeNode(Dst, B, *I2, state);
           continue;
         }
       }
@@ -2875,25 +2879,6 @@
         state = GetState(*I3);
         SVal V = state->getSVal(LHS);
 
-        // Propagate undefined values (left-side).
-        if (V.isUndef()) {
-          EvalStore(Dst, B, LHS, *I3, state->BindExpr(B, V),
-                    location, V);
-          continue;
-        }
-
-        // Propagate unknown values (left and right-side).
-        if (RightV.isUnknown() || V.isUnknown()) {
-          EvalStore(Dst, B, LHS, *I3, state->BindExpr(B, UnknownVal()),
-                    location, UnknownVal());
-          continue;
-        }
-
-        // At this point:
-        //
-        //  The LHS is not Undef/Unknown.
-        //  The RHS is not Unknown.
-
         // Get the computation type.
         QualType CTy =
           cast<CompoundAssignOperator>(B)->getComputationResultType();
@@ -2909,14 +2894,6 @@
         // Promote LHS.
         llvm::tie(state, V) = SVator.EvalCast(V, state, CLHSTy, LTy);
 
-        // Evaluate operands and promote to result type.
-        if (RightV.isUndef()) {
-          // Propagate undefined values (right-side).
-          EvalStore(Dst, B, LHS, *I3, state->BindExpr(B, RightV), location,
-                    RightV);
-          continue;
-        }
-
         // Compute the result of the operation.
         SVal Result;
         llvm::tie(state, Result) = SVator.EvalCast(EvalBinOp(state, Op, V,

Modified: cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp Fri Sep 11 17:07:28 2009
@@ -126,7 +126,7 @@
       os << "The receiver in the message expression is 'nil' and results in the"
             " returned value (of type '"
          << ME->getType().getAsString()
-         << "') to be garbage or otherwise undefined.";
+         << "') to be garbage or otherwise undefined";
 
       BuiltinBugReport *R = new BuiltinBugReport(*this, os.str().c_str(), *I);
       R->addRange(ME->getReceiver()->getSourceRange());
@@ -161,7 +161,7 @@
       << ME->getType().getAsString()
       << "' and of size "
       << Eng.getContext().getTypeSize(ME->getType()) / 8
-      << " bytes) to be garbage or otherwise undefined.";
+      << " bytes) to be garbage or otherwise undefined";
 
       BuiltinBugReport *R = new BuiltinBugReport(*this, os.str().c_str(), *I);
       R->addRange(ME->getReceiver()->getSourceRange());
@@ -206,11 +206,66 @@
 
 class VISIBILITY_HIDDEN UndefResult : public BuiltinBug {
 public:
-  UndefResult(GRExprEngine* eng) : BuiltinBug(eng,"Undefined result",
-                             "Result of operation is undefined.") {}
+  UndefResult(GRExprEngine* eng)
+    : BuiltinBug(eng,"Undefined or garbage result",
+                 "Result of operation is garbage or undefined") {}
 
   void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
-    Emit(BR, Eng.undef_results_begin(), Eng.undef_results_end());
+    for (GRExprEngine::undef_result_iterator I=Eng.undef_results_begin(),
+         E = Eng.undef_results_end(); I!=E; ++I) {
+      
+      ExplodedNode *N = *I;
+      const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();        
+      BuiltinBugReport *report = NULL;
+      
+      if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S)) {
+        llvm::SmallString<256> sbuf;
+        llvm::raw_svector_ostream OS(sbuf);
+        const GRState *ST = N->getState();
+        const Expr *Ex;
+
+        if (ST->getSVal(B->getLHS()).isUndef()) {
+          Ex = B->getLHS()->IgnoreParenCasts();
+          OS << "The left operand of the '";
+        }
+        else {
+          assert(ST->getSVal(B->getRHS()).isUndef());
+          Ex = B->getRHS()->IgnoreParenCasts();
+          OS << "The right operand of the '";
+        }
+                
+        OS << BinaryOperator::getOpcodeStr(B->getOpcode())
+           << "' expression is an undefined "
+              "or otherwise garbage value";
+        
+        // FIXME: Use StringRefs to pass string information.
+        report = new BuiltinBugReport(*this, OS.str().str().c_str(), N);
+        report->addRange(Ex->getSourceRange());
+      }
+      else {
+        report = new BuiltinBugReport(*this, 
+                                      "Expression evaluates to an uninitialized"
+                                      " or undefined value", N);
+      }
+
+      BR.EmitReport(report);
+    }
+  }
+  
+  void registerInitialVisitors(BugReporterContext& BRC,
+                               const ExplodedNode* N,
+                               BuiltinBugReport *R) {
+    
+    const Stmt *S = N->getLocationAs<StmtPoint>()->getStmt();
+    const Stmt *X = S;
+    
+    if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S)) {
+      const GRState *ST = N->getState();
+      X = ST->getSVal(B->getLHS()).isUndef()
+          ? B->getLHS()->IgnoreParenCasts() : B->getRHS()->IgnoreParenCasts();
+    }
+    
+    registerTrackNullOrUndefValue(BRC, X, N);
   }
 };
 
@@ -245,7 +300,7 @@
 class VISIBILITY_HIDDEN BadArg : public BuiltinBug {
 public:
   BadArg(GRExprEngine* eng=0) : BuiltinBug(eng,"Uninitialized argument",
-    "Pass-by-value argument in function call is undefined.") {}
+    "Pass-by-value argument in function call is undefined") {}
 
   BadArg(GRExprEngine* eng, const char* d)
     : BuiltinBug(eng,"Uninitialized argument", d) {}
@@ -362,8 +417,8 @@
 
 class VISIBILITY_HIDDEN RetUndef : public BuiltinBug {
 public:
-  RetUndef(GRExprEngine* eng) : BuiltinBug(eng, "Uninitialized return value",
-              "Uninitialized or undefined value returned to caller.") {}
+  RetUndef(GRExprEngine* eng) : BuiltinBug(eng, "Garbage return value",
+              "Undefined or garbage value returned to caller") {}
 
   void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
     Emit(BR, Eng.ret_undef_begin(), Eng.ret_undef_end());
@@ -401,8 +456,9 @@
 
 public:
   UndefBranch(GRExprEngine *eng)
-    : BuiltinBug(eng,"Use of uninitialized value",
-                 "Branch condition evaluates to an uninitialized value.") {}
+    : BuiltinBug(eng,"Use of garbage value",
+                 "Branch condition evaluates to an undefined or garbage value")
+       {}
 
   void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
     for (GRExprEngine::undef_branch_iterator I=Eng.undef_branches_begin(),

Modified: cfe/trunk/lib/Analysis/SValuator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SValuator.cpp?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/SValuator.cpp (original)
+++ cfe/trunk/lib/Analysis/SValuator.cpp Fri Sep 11 17:07:28 2009
@@ -46,6 +46,13 @@
   return EvalBinOpNN(Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
 }
 
+DefinedOrUnknownSVal SValuator::EvalEQ(const GRState *ST,
+                                       DefinedOrUnknownSVal L,
+                                       DefinedOrUnknownSVal R) {
+  return cast<DefinedOrUnknownSVal>(EvalBinOp(ST, BinaryOperator::EQ, L, R,
+                                              ValMgr.getContext().IntTy));
+}
+
 SValuator::CastResult SValuator::EvalCast(SVal val, const GRState *state,
                                           QualType castTy, QualType originalTy){
 
@@ -146,3 +153,11 @@
                     isa<Loc>(val) ? EvalCastL(cast<Loc>(val), castTy)
                                   : EvalCastNL(cast<NonLoc>(val), castTy));
 }
+
+SValuator::DefinedOrUnknownCastResult
+SValuator::EvalCast(DefinedOrUnknownSVal V, const GRState *ST,
+                    QualType castTy, QualType originalType) {
+  SValuator::CastResult X = EvalCast((SVal) V, ST, castTy, originalType);
+  return DefinedOrUnknownCastResult(X.getState(),
+                                    cast<DefinedOrUnknownSVal>(X.getSVal()));
+}

Modified: cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp (original)
+++ cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp Fri Sep 11 17:07:28 2009
@@ -56,11 +56,8 @@
 }
 
 const GRState *SimpleConstraintManager::Assume(const GRState *state,
-                                               SVal Cond, bool Assumption) {
-  if (Cond.isUnknown()) {
-    return state;
-  }
-
+                                               DefinedSVal Cond,
+                                               bool Assumption) {
   if (isa<NonLoc>(Cond))
     return Assume(state, cast<NonLoc>(Cond), Assumption);
   else
@@ -226,8 +223,8 @@
 }
 
 const GRState *SimpleConstraintManager::AssumeInBound(const GRState *state,
-                                                      SVal Idx,
-                                                      SVal UpperBound,
+                                                      DefinedSVal Idx,
+                                                      DefinedSVal UpperBound,
                                                       bool Assumption) {
 
   // Only support ConcreteInt for now.

Modified: cfe/trunk/lib/Analysis/SimpleConstraintManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SimpleConstraintManager.h?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/SimpleConstraintManager.h (original)
+++ cfe/trunk/lib/Analysis/SimpleConstraintManager.h Fri Sep 11 17:07:28 2009
@@ -30,7 +30,8 @@
 
   bool canReasonAbout(SVal X) const;
 
-  const GRState *Assume(const GRState *state, SVal Cond, bool Assumption);
+  const GRState *Assume(const GRState *state, DefinedSVal Cond,
+                        bool Assumption);
 
   const GRState *Assume(const GRState *state, Loc Cond, bool Assumption);
 
@@ -39,7 +40,8 @@
   const GRState *AssumeSymInt(const GRState *state, bool Assumption,
                               const SymIntExpr *SE);
 
-  const GRState *AssumeInBound(const GRState *state, SVal Idx, SVal UpperBound,
+  const GRState *AssumeInBound(const GRState *state, DefinedSVal Idx,
+                               DefinedSVal UpperBound,
                                bool Assumption);
 
 protected:

Modified: cfe/trunk/lib/Analysis/SimpleSValuator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SimpleSValuator.cpp?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/SimpleSValuator.cpp (original)
+++ cfe/trunk/lib/Analysis/SimpleSValuator.cpp Fri Sep 11 17:07:28 2009
@@ -97,8 +97,6 @@
   //   can be introduced by the frontend for corner cases, e.g
   //   casting from va_list* to __builtin_va_list&.
   //
-  assert(!val.isUnknownOrUndef());
-
   if (Loc::IsLocType(castTy) || castTy->isReferenceType())
     return val;
 
@@ -202,10 +200,6 @@
 SVal SimpleSValuator::EvalBinOpNN(BinaryOperator::Opcode op,
                                   NonLoc lhs, NonLoc rhs,
                                   QualType resultTy)  {
-
-  assert(!lhs.isUnknownOrUndef());
-  assert(!rhs.isUnknownOrUndef());
-
   // Handle trivial case where left-side and right-side are the same.
   if (lhs == rhs)
     switch (op) {

Modified: cfe/trunk/lib/Analysis/ValueManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ValueManager.cpp?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/ValueManager.cpp (original)
+++ cfe/trunk/lib/Analysis/ValueManager.cpp Fri Sep 11 17:07:28 2009
@@ -22,7 +22,7 @@
 // Utility methods for constructing SVals.
 //===----------------------------------------------------------------------===//
 
-SVal ValueManager::makeZeroVal(QualType T) {
+DefinedOrUnknownSVal ValueManager::makeZeroVal(QualType T) {
   if (Loc::IsLocType(T))
     return makeNull();
 
@@ -69,7 +69,8 @@
   return SVator->EvalCastNL(cast<NonLoc>(V), ArrayIndexTy);
 }
 
-SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) {
+DefinedOrUnknownSVal ValueManager::getRegionValueSymbolVal(const MemRegion* R,
+                                                           QualType T) {
 
   if (T.isNull()) {
     const TypedRegion* TR = cast<TypedRegion>(R);
@@ -87,7 +88,7 @@
   return nonloc::SymbolVal(sym);
 }
 
-SVal ValueManager::getConjuredSymbolVal(const Expr *E, unsigned Count) {
+DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const Expr *E, unsigned Count) {
   QualType T = E->getType();
 
   if (!SymbolManager::canSymbolicate(T))
@@ -101,9 +102,10 @@
   return nonloc::SymbolVal(sym);
 }
 
-SVal ValueManager::getConjuredSymbolVal(const Expr *E, QualType T,
-                                        unsigned Count) {
-
+DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const Expr *E,
+                                                        QualType T,
+                                                        unsigned Count) {
+  
   if (!SymbolManager::canSymbolicate(T))
     return UnknownVal();
 
@@ -116,8 +118,9 @@
 }
 
 
-SVal ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
-                                                  const TypedRegion *R) {
+DefinedOrUnknownSVal
+ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
+                                             const TypedRegion *R) {
   QualType T = R->getValueType(R->getContext());
 
   if (!SymbolManager::canSymbolicate(T))
@@ -131,7 +134,7 @@
   return nonloc::SymbolVal(sym);
 }
 
-SVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
+DefinedSVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
   CodeTextRegion *R  = MemMgr.getCodeTextRegion(FD);
   return loc::MemRegionVal(R);
 }

Modified: cfe/trunk/test/Analysis/uninit-vals-ps-region.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/uninit-vals-ps-region.c?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/uninit-vals-ps-region.c (original)
+++ cfe/trunk/test/Analysis/uninit-vals-ps-region.c Fri Sep 11 17:07:28 2009
@@ -25,7 +25,7 @@
   struct TestUninit v2 = test_uninit_aux();
   int z;
   v1.y = z;
-  test_unit_aux2(v2.x + v1.y);  // expected-warning{{Pass-by-value argument in function call is undefined}}
+  test_unit_aux2(v2.x + v1.y);  // expected-warning{{The right operand of the '+' expression is an undefined or otherwise garbage value}}
 }
 void test_uninit_neg() {
   struct TestUninit v1 = { 0, 0 };

Modified: cfe/trunk/test/Analysis/uninit-vals-ps.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/uninit-vals-ps.c?rev=81579&r1=81578&r2=81579&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/uninit-vals-ps.c (original)
+++ cfe/trunk/test/Analysis/uninit-vals-ps.c Fri Sep 11 17:07:28 2009
@@ -22,7 +22,7 @@
   
   int x;
   
-  if (x+1)  // expected-warning{{Branch}}
+  if (x+1)  // expected-warning{{The left operand of the '+' expression is an undefined or otherwise garbage value}}
     return 1;
     
   return 2;  
@@ -31,13 +31,13 @@
 int f2_b() {
   int x;
   
-  return ((x+1)+2+((x))) + 1 ? 1 : 2; // expected-warning{{Branch}}
+  return ((1+x)+2+((x))) + 1 ? 1 : 2; // expected-warning{{The right operand of the '+' expression is an undefined or otherwise garbage value}}
 }
 
 int f3(void) {
   int i;
   int *p = &i;
-  if (*p > 0) // expected-warning{{Branch condition evaluates to an uninitialized value}}
+  if (*p > 0) // expected-warning{{The left operand of the '>' expression is an undefined or otherwise garbage value}}
     return 0;
   else
     return 1;
@@ -61,7 +61,7 @@
 int ret_uninit() {
   int i;
   int *p = &i;
-  return *p;  // expected-warning{{Uninitialized or undefined value returned to caller.}}
+  return *p;  // expected-warning{{Undefined or garbage value returned to caller}}
 }
 
 // <rdar://problem/6451816>





More information about the cfe-commits mailing list