[cfe-commits] r48895 - in /cfe/trunk: include/clang/Analysis/PathSensitive/AnnotatedPath.h include/clang/Analysis/PathSensitive/GRCoreEngine.h include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h lib/Analysis/BasicObjCFoundationChecks.cpp lib/Analysis/GRExprEngine.cpp lib/Analysis/GRSimpleVals.cpp

Ted Kremenek kremenek at apple.com
Thu Mar 27 14:15:17 PDT 2008


Author: kremenek
Date: Thu Mar 27 16:15:17 2008
New Revision: 48895

URL: http://llvm.org/viewvc/llvm-project?rev=48895&view=rev
Log:
Hooked up initial NSString interface checking to GRSimpleVals.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/AnnotatedPath.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h
    cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/lib/Analysis/GRSimpleVals.cpp

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

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/AnnotatedPath.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/AnnotatedPath.h Thu Mar 27 16:15:17 2008
@@ -34,7 +34,7 @@
                 Expr* e = NULL)
   : Node(N), annotation(annot), E(e) {}
 
-  ExplodedNode<STATE> getNode() const { return Node; }
+  ExplodedNode<STATE>* getNode() const { return Node; }
   
   const std::string& getString() const { return annotation; }
   
@@ -58,6 +58,8 @@
   iterator begin() { return path.begin(); }
   iterator end() { return path.end(); }
   
+  AnnotatedNode<STATE>& back() { return path.back(); }
+  const AnnotatedNode<STATE>& back() const { return path.back(); }
 };
   
 } // end clang namespace

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

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h Thu Mar 27 16:15:17 2008
@@ -19,6 +19,7 @@
 #include "clang/Analysis/PathSensitive/ExplodedGraph.h"
 #include "clang/Analysis/PathSensitive/GRWorkList.h"
 #include "clang/Analysis/PathSensitive/GRBlockCounter.h"
+#include "clang/Analysis/PathSensitive/GRAuditor.h"
 #include "llvm/ADT/OwningPtr.h"
 
 namespace clang {
@@ -162,15 +163,6 @@
   
   CFGBlock* getBlock() const { return &B; }
 };
-
-template <typename STATE>
-class GRNodeAuditor {
-public:
-  typedef ExplodedNode<STATE>   NodeTy;
-  
-  virtual ~GRNodeAuditor() {}
-  virtual bool Audit(NodeTy* N) = 0;
-};
   
   
 template<typename STATE>
@@ -181,8 +173,8 @@
   GRStmtNodeBuilderImpl& NB;
   StateTy* CleanedState;
   
-  GRNodeAuditor<StateTy> **CallExprAuditBeg, **CallExprAuditEnd;
-  GRNodeAuditor<StateTy> **ObjCMsgExprAuditBeg, **ObjCMsgExprAuditEnd;
+  GRAuditor<StateTy> **CallExprAuditBeg, **CallExprAuditEnd;
+  GRAuditor<StateTy> **ObjCMsgExprAuditBeg, **ObjCMsgExprAuditEnd;
   
 public:
   GRStmtNodeBuilder(GRStmtNodeBuilderImpl& nb) : NB(nb),
@@ -192,14 +184,14 @@
     CleanedState = getLastNode()->getState();
   }
   
-  void setObjCMsgExprAuditors(GRNodeAuditor<StateTy> **B,
-                              GRNodeAuditor<StateTy> **E) {
+  void setObjCMsgExprAuditors(GRAuditor<StateTy> **B,
+                              GRAuditor<StateTy> **E) {
     ObjCMsgExprAuditBeg = B;
     ObjCMsgExprAuditEnd = E;
   }
   
-  void setCallExprAuditors(GRNodeAuditor<StateTy> **B,
-                           GRNodeAuditor<StateTy> **E) {
+  void setCallExprAuditors(GRAuditor<StateTy> **B,
+                           GRAuditor<StateTy> **E) {
     CallExprAuditBeg = B;
     CallExprAuditEnd = E;
   }  
@@ -240,8 +232,22 @@
     
     StateTy* PredState = GetState(Pred);
     
+    GRAuditor<StateTy> **AB = NULL, **AE = NULL;
+    
+    switch (S->getStmtClass()) {
+      default: break;
+      case Stmt::CallExprClass:
+        AB = CallExprAuditBeg;
+        AE = CallExprAuditEnd;
+        break;
+      case Stmt::ObjCMessageExprClass:
+        AB = ObjCMsgExprAuditBeg;
+        AE = ObjCMsgExprAuditEnd;
+        break;
+    }
+    
     // If the state hasn't changed, don't generate a new node.
-    if (!BuildSinks && St == PredState) {
+    if (!BuildSinks && St == PredState && AB == NULL) {
       Dst.Add(Pred);
       return NULL;
     }
@@ -254,14 +260,8 @@
       else {
         Dst.Add(N);
         
-        if (isa<CallExpr>(S))
-          for (GRNodeAuditor<StateTy>** I = CallExprAuditBeg;
-               I != CallExprAuditEnd; ++I)
-            (*I)->Audit(N);
-        else if (isa<ObjCMessageExpr>(S))
-          for (GRNodeAuditor<StateTy>** I = ObjCMsgExprAuditBeg;
-               I != ObjCMsgExprAuditEnd; ++I)
-            (*I)->Audit(N);
+        for ( ; AB != AE; ++AB)
+          (*AB)->Audit(N);
       }
     }
     

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

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h Thu Mar 27 16:15:17 2008
@@ -21,13 +21,13 @@
 namespace clang {
   
 class ValueState;
+class Diagnostic;
   
 class GRSimpleAPICheck : public GRAuditor<ValueState> {
 public:
   GRSimpleAPICheck() {}
   virtual ~GRSimpleAPICheck() {}
-
-
+  virtual void ReportResults(Diagnostic& D) {}
 };
 
 } // end namespace clang

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

==============================================================================
--- cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp Thu Mar 27 16:15:17 2008
@@ -32,16 +32,18 @@
   
 class VISIBILITY_HIDDEN BasicObjCFoundationChecks : public GRSimpleAPICheck {
 
- ASTContext &Ctx;
- ValueStateManager* VMgr;
- std::list<AnnotatedPath<ValueState> > Errors;
+  ASTContext &Ctx;
+  ValueStateManager* VMgr;
+  
+  typedef std::list<AnnotatedPath<ValueState> > ErrorsTy;
+  ErrorsTy Errors;
       
- RVal GetRVal(ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); }
+  RVal GetRVal(ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); }
       
- bool isNSString(ObjCInterfaceType* T, const char* suffix);
- bool AuditNSString(NodeTy* N, ObjCMessageExpr* ME);
+  bool isNSString(ObjCInterfaceType* T, const char* suffix);
+  bool AuditNSString(NodeTy* N, ObjCMessageExpr* ME);
       
- void RegisterError(NodeTy* N, Expr* E, const char *msg);
+  void RegisterError(NodeTy* N, Expr* E, const char *msg);
 
 public:
   BasicObjCFoundationChecks(ASTContext& ctx, ValueStateManager* vmgr) 
@@ -50,6 +52,9 @@
   virtual ~BasicObjCFoundationChecks() {}
   
   virtual bool Audit(ExplodedNode<ValueState>* N);
+  
+  virtual void ReportResults(Diagnostic& D);
+
 };
   
 } // end anonymous namespace
@@ -98,6 +103,10 @@
   return false;  
 }
 
+static inline bool isNil(RVal X) {
+  return isa<lval::ConcreteInt>(X);  
+}
+
 //===----------------------------------------------------------------------===//
 // Error reporting.
 //===----------------------------------------------------------------------===//
@@ -110,6 +119,26 @@
   Errors.back().push_back(N, msg, E);
 }
 
+void BasicObjCFoundationChecks::ReportResults(Diagnostic& D) {
+  
+  // FIXME: Expand errors into paths.  For now, just issue warnings.
+  
+  for (ErrorsTy::iterator I=Errors.begin(), E=Errors.end(); I!=E; ++I) {
+      
+    AnnotatedNode<ValueState>& AN = I->back();
+    
+    unsigned diag = D.getCustomDiagID(Diagnostic::Warning,
+                                      AN.getString().c_str());
+    
+    Stmt* S = cast<PostStmt>(AN.getNode()->getLocation()).getStmt();
+    FullSourceLoc L(S->getLocStart(), Ctx.getSourceManager());
+    
+    SourceRange R = AN.getExpr()->getSourceRange();
+    
+    D.Report(diag, &AN.getString(), 1, &R, 1);
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // NSString checking.
 //===----------------------------------------------------------------------===//
@@ -139,10 +168,9 @@
     Expr * E = ME->getArg(0);
     RVal X = GetRVal(St, E);
     
-    if (isa<lval::ConcreteInt>(X)) {
+    if (isNil(X))
       RegisterError(N, E,
                     "Argument to NSString method 'compare:' cannot be nil.");
-    }
   }
   
   return false;

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Thu Mar 27 16:15:17 2008
@@ -411,14 +411,14 @@
   
   if (!MsgExprChecks.empty())
     Builder->setObjCMsgExprAuditors(
-      (GRNodeAuditor<ValueState>**) &MsgExprChecks[0],
-      (GRNodeAuditor<ValueState>**) (&MsgExprChecks[0] + MsgExprChecks.size()));
+      (GRAuditor<ValueState>**) &MsgExprChecks[0],
+      (GRAuditor<ValueState>**) (&MsgExprChecks[0] + MsgExprChecks.size()));
 
   
   if (!CallChecks.empty())
     Builder->setCallExprAuditors(
-      (GRNodeAuditor<ValueState>**) &CallChecks[0],
-      (GRNodeAuditor<ValueState>**) (&CallChecks[0] + CallChecks.size()));
+      (GRAuditor<ValueState>**) &CallChecks[0],
+      (GRAuditor<ValueState>**) (&CallChecks[0] + CallChecks.size()));
   
   // Create the cleaned state.
 

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/lib/Analysis/GRSimpleVals.cpp Thu Mar 27 16:15:17 2008
@@ -167,7 +167,7 @@
               CheckerState->undef_receivers_end(),
               "Receiver in message expression is an uninitialized value.");
 
-      
+  FoundationCheck.get()->ReportResults(Diag);
 #ifndef NDEBUG
   if (Visualize) CheckerState->ViewGraph(TrimGraph);
 #endif





More information about the cfe-commits mailing list