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();
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;
<< "' 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);
}
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 *'}}