]> granicus.if.org Git - clang/commitdiff
Tweak VariadicMethodTypeChecker to only create one ExplodedNode when issuing multiple...
authorTed Kremenek <kremenek@apple.com>
Mon, 14 Mar 2011 19:50:37 +0000 (19:50 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 14 Mar 2011 19:50:37 +0000 (19:50 +0000)
Also add a test case showing that we correctly report multiple warnings for the same message expression.

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

lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
test/Analysis/variadic-method-types.m

index a6f980ad49dcaa15bef1ea0d75abd33031070c19..8677f08ab9bce27059b1bbec242f8840b87c2a17 100644 (file)
@@ -502,10 +502,7 @@ public:
 bool
 VariadicMethodTypeChecker::isVariadicMessage(const ObjCMessage &msg) const {
   const ObjCMethodDecl *MD = msg.getMethodDecl();
-  if (!MD)
-    return false;
-  
-  if (!MD->isVariadic())
+  if (!MD || !MD->isVariadic())
     return false;
   
   Selector S = msg.getSelector();
@@ -586,13 +583,19 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
     return;
 
   // Verify that all arguments have Objective-C types.
+  llvm::Optional<ExplodedNode*> errorNode;
+  
   for (unsigned I = variadicArgsBegin; I != variadicArgsEnd; ++I) {
     QualType ArgTy = msg.getArgType(I);
     if (ArgTy->isObjCObjectPointerType())
       continue;
 
-    ExplodedNode *N = C.generateNode();
-    if (!N)
+    // Generate only one error node to use for all bug reports.
+    if (!errorNode.hasValue()) {
+      errorNode = C.generateNode();
+    }
+
+    if (!errorNode.getValue())
       continue;
 
     llvm::SmallString<128> sbuf;
@@ -607,7 +610,8 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
       << "' should be an Objective-C pointer type, not '" 
       << ArgTy.getAsString() << "'";
 
-    RangedBugReport *R = new RangedBugReport(*BT, os.str(), N);
+    RangedBugReport *R = new RangedBugReport(*BT, os.str(),
+                                             errorNode.getValue());
     R->addRange(msg.getArgSourceRange(I));
     C.EmitReport(R);
   }
index 5b187edced76271b1d67694649870ba6ca6c5756..bd1b227f9f8b3c4f229c230c72f1b884c69a2bd3 100644 (file)
@@ -63,7 +63,7 @@ typedef struct {} NSFastEnumerationState;
 void f(id a, id<P> b, C* c, C<P> *d) {
   [NSArray arrayWithObjects:@"Hello", a, b, c, d, nil];
 
-  [NSArray arrayWithObjects:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSArray' method 'arrayWithObjects:' should be an Objective-C pointer type, not 'char *'}}
+  [NSArray arrayWithObjects:@"Foo", "Bar", "Baz", nil]; // expected-warning 2 {{Argument to 'NSArray' method 'arrayWithObjects:' should be an Objective-C pointer type, not 'char *'}}
   [NSDictionary dictionaryWithObjectsAndKeys:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSDictionary' method 'dictionaryWithObjectsAndKeys:' should be an Objective-C pointer type, not 'char *'}}
   [NSSet setWithObjects:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSSet' method 'setWithObjects:' should be an Objective-C pointer type, not 'char *'}}