]> granicus.if.org Git - clang/commitdiff
Add "KnownSVal" to represent SVals that cannot be UnknownSVal.
authorTed Kremenek <kremenek@apple.com>
Sun, 24 Feb 2013 07:20:53 +0000 (07:20 +0000)
committerTed Kremenek <kremenek@apple.com>
Sun, 24 Feb 2013 07:20:53 +0000 (07:20 +0000)
This provides a few sundry cleanups, and allows us to provide
a compile-time check for a case that was a runtime assertion.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175987 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

index 75bf9613e2d5b372a0ac2d6fda6b2bed4c9fa137..bef4b30a35746fd25e2c90c075fb6bc8a48e0668 100644 (file)
@@ -99,7 +99,7 @@ class FindLastStoreBRVisitor
 {
   const MemRegion *R;
   SVal V;
-  bool satisfied;
+  bool Satisfied;
 
 public:
   /// \brief Convenience method to create a visitor given only the MemRegion.
@@ -112,13 +112,10 @@ public:
   /// the BugReport.
   static void registerStatementVarDecls(BugReport &BR, const Stmt *S);
 
-  FindLastStoreBRVisitor(SVal v, const MemRegion *r)
-  : R(r), V(v), satisfied(false) {
-    assert (!V.isUnknown() && "Cannot track unknown value.");
-
-    // TODO: Does it make sense to allow undef values here?
-    // (If not, also see UndefCapturedBlockVarChecker)?
-  }
+  FindLastStoreBRVisitor(KnownSVal V, const MemRegion *R)
+  : R(R),
+    V(V),
+    Satisfied(false) {}
 
   void Profile(llvm::FoldingSetNodeID &ID) const;
 
index 31d02f51ea0faf087243943444f56bf15370272c..03e84447e7b9e0ca728f94ea20b13ffec4b79c82 100644 (file)
@@ -219,7 +219,7 @@ public:
   
 private:
   friend class SVal;
-  static bool isKind(const SValV) {
+  static bool isKind(const SVal &V) {
     return V.getBaseKind() == UnknownKind;
   }
 };
@@ -242,6 +242,19 @@ private:
   }
 };
 
+
+/// \brief Represents an SVal that is guaranteed to not be UnknownVal.
+class KnownSVal : public SVal {
+  KnownSVal() {}
+  friend class SVal;
+  static bool isKind(const SVal &V) {
+    return !V.isUnknown();
+  }
+public:
+  KnownSVal(const DefinedSVal &V) : SVal(V) {}
+  KnownSVal(const UndefinedVal &V) : SVal(V) {}
+};
+
 class NonLoc : public DefinedSVal {
 protected:
   NonLoc() {}
index 3f8363762fdf05a4f6c40bbbee84ffe3a5bf4529..f0ca8a8312b229cd34202674d1ff301ee24f1088 100644 (file)
@@ -75,9 +75,8 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE,
       continue;
 
     // Get the VarRegion associated with VD in the local stack frame.
-    SVal VRVal = state->getSVal(I.getOriginalRegion());
-
-    if (VRVal.isUndef())
+    if (Optional<UndefinedVal> V =
+          state->getSVal(I.getOriginalRegion()).getAs<UndefinedVal>()) {
       if (ExplodedNode *N = C.generateSink()) {
         if (!BT)
           BT.reset(new BuiltinBug("uninitialized variable captured by block"));
@@ -92,11 +91,12 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE,
         BugReport *R = new BugReport(*BT, os.str(), N);
         if (const Expr *Ex = FindBlockDeclRefExpr(BE->getBody(), VD))
           R->addRange(Ex->getSourceRange());
-        R->addVisitor(new FindLastStoreBRVisitor(VRVal, VR));
+        R->addVisitor(new FindLastStoreBRVisitor(*V, VR));
         R->disablePathPruning();
         // need location of block
         C.emitReport(R);
       }
+    }
   }
 }
 
index 5dc8dfc8deac80fc4f5045c5a2512d87bde00177..f59458ca6ecc672a06aa96ada2e785351f7ce1d4 100644 (file)
@@ -354,7 +354,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
                                                        BugReporterContext &BRC,
                                                        BugReport &BR) {
 
-  if (satisfied)
+  if (Satisfied)
     return NULL;
 
   const ExplodedNode *StoreSite = 0;
@@ -410,7 +410,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
 
   if (!StoreSite)
     return NULL;
-  satisfied = true;
+  Satisfied = true;
 
   // If we have an expression that provided the value, try to track where it
   // came from.
@@ -449,8 +449,9 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
         if (const BlockDataRegion *BDR =
               dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
           if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
-            V = State->getSVal(OriginalR);
-            BR.addVisitor(new FindLastStoreBRVisitor(V, OriginalR));
+            if (Optional<KnownSVal> KV =
+                State->getSVal(OriginalR).getAs<KnownSVal>())
+              BR.addVisitor(new FindLastStoreBRVisitor(*KV, OriginalR));
           }
         }
       }
@@ -698,7 +699,8 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
           report.addVisitor(ConstraintTracker);
         }
 
-        report.addVisitor(new FindLastStoreBRVisitor(V, R));
+        if (Optional<KnownSVal> KV = V.getAs<KnownSVal>())
+          report.addVisitor(new FindLastStoreBRVisitor(*KV, R));
         return true;
       }
     }
@@ -711,7 +713,6 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
   // Uncomment this to find cases where we aren't properly getting the
   // base value that was dereferenced.
   // assert(!V.isUnknownOrUndef());
-
   // Is it a symbolic value?
   if (Optional<loc::MemRegionVal> L = V.getAs<loc::MemRegionVal>()) {
     // At this point we are dealing with the region's LValue.
@@ -743,14 +744,11 @@ FindLastStoreBRVisitor::createVisitorObject(const ExplodedNode *N,
   assert(R && "The memory region is null.");
 
   ProgramStateRef state = N->getState();
-  SVal V = state->getSVal(R);
-  if (V.isUnknown())
-    return 0;
-
-  return new FindLastStoreBRVisitor(V, R);
+  if (Optional<KnownSVal> KV = state->getSVal(R).getAs<KnownSVal>())
+    return new FindLastStoreBRVisitor(*KV, R);
+  return 0;
 }
 
-
 PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
                                                      const ExplodedNode *PrevN,
                                                      BugReporterContext &BRC,
@@ -808,7 +806,7 @@ void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
 
         if (V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) {
           // Register a new visitor with the BugReport.
-          BR.addVisitor(new FindLastStoreBRVisitor(V, R));
+          BR.addVisitor(new FindLastStoreBRVisitor(V.castAs<KnownSVal>(), R));
         }
       }
     }