Hooked up initial NSString interface checking to GRSimpleVals.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48895 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp
index 4d7a4d9..d2a2dd6 100644
--- a/lib/Analysis/BasicObjCFoundationChecks.cpp
+++ b/lib/Analysis/BasicObjCFoundationChecks.cpp
@@ -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;
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index b6f164a..b70e219 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -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.
 
diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp
index 520f624..94cedc0 100644
--- a/lib/Analysis/GRSimpleVals.cpp
+++ b/lib/Analysis/GRSimpleVals.cpp
@@ -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