aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp12
-rw-r--r--test/Analysis/variadic-method-types.m8
2 files changed, 20 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index dd4235af5e..6dd0a8c01f 100644
--- a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -485,6 +485,7 @@ class VariadicMethodTypeChecker : public Checker<check::PreObjCMessage> {
mutable Selector arrayWithObjectsS;
mutable Selector dictionaryWithObjectsAndKeysS;
mutable Selector setWithObjectsS;
+ mutable Selector orderedSetWithObjectsS;
mutable Selector initWithObjectsS;
mutable Selector initWithObjectsAndKeysS;
mutable OwningPtr<BugType> BT;
@@ -530,6 +531,11 @@ VariadicMethodTypeChecker::isVariadicMessage(const ObjCMessage &msg) const {
if (isReceiverClassOrSuperclass(Class, "NSSet") &&
S == initWithObjectsS)
return true;
+
+ // -[NSOrderedSet initWithObjects:]
+ if (isReceiverClassOrSuperclass(Class, "NSOrderedSet") &&
+ S == initWithObjectsS)
+ return true;
} else {
const ObjCInterfaceDecl *Class = msg.getReceiverInterface();
@@ -547,6 +553,11 @@ VariadicMethodTypeChecker::isVariadicMessage(const ObjCMessage &msg) const {
if (isReceiverClassOrSuperclass(Class, "NSSet") &&
S == setWithObjectsS)
return true;
+
+ // -[NSOrderedSet orderedSetWithObjects:]
+ if (isReceiverClassOrSuperclass(Class, "NSOrderedSet") &&
+ S == orderedSetWithObjectsS)
+ return true;
}
return false;
@@ -563,6 +574,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
dictionaryWithObjectsAndKeysS =
GetUnarySelector("dictionaryWithObjectsAndKeys", Ctx);
setWithObjectsS = GetUnarySelector("setWithObjects", Ctx);
+ orderedSetWithObjectsS = GetUnarySelector("orderedSetWithObjects", Ctx);
initWithObjectsS = GetUnarySelector("initWithObjects", Ctx);
initWithObjectsAndKeysS = GetUnarySelector("initWithObjectsAndKeys", Ctx);
diff --git a/test/Analysis/variadic-method-types.m b/test/Analysis/variadic-method-types.m
index caa0c59deb..4d0f6bc3f7 100644
--- a/test/Analysis/variadic-method-types.m
+++ b/test/Analysis/variadic-method-types.m
@@ -57,6 +57,12 @@ typedef struct {} NSFastEnumerationState;
+ (id)setWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1)));
- (id)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1)));
@end
+@interface NSOrderedSet : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+@end
+@interface NSOrderedSet (NSOrderedSetCreation)
++ (id)orderedSetWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1)));
+- (id)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1)));
+@end
@protocol P;
@class C;
@@ -71,6 +77,7 @@ void f(id a, id<P> b, C* c, C<P> *d, FooType fooType, BarType barType) {
[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 *'}}
+ [NSOrderedSet orderedSetWithObjects:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSOrderedSet' method 'orderedSetWithObjects:' should be an Objective-C pointer type, not 'char *'}}
[[[NSArray alloc] initWithObjects:@"Foo", "Bar", nil] autorelease]; // expected-warning {{Argument to 'NSArray' method 'initWithObjects:' should be an Objective-C pointer type, not 'char *'}}
[[[NSDictionary alloc] initWithObjectsAndKeys:@"Foo", "Bar", nil] autorelease]; // expected-warning {{Argument to 'NSDictionary' method 'initWithObjectsAndKeys:' should be an Objective-C pointer type, not 'char *'}}
@@ -79,6 +86,7 @@ void f(id a, id<P> b, C* c, C<P> *d, FooType fooType, BarType barType) {
[[[NSDictionary alloc] initWithObjectsAndKeys:@"Foo", fooType, nil] autorelease]; // no-warning
[[[NSDictionary alloc] initWithObjectsAndKeys:@"Foo", barType, nil] autorelease]; // expected-warning {{Argument to 'NSDictionary' method 'initWithObjectsAndKeys:' should be an Objective-C pointer type, not 'BarType'}}
[[[NSSet alloc] initWithObjects:@"Foo", "Bar", nil] autorelease]; // expected-warning {{Argument to 'NSSet' method 'initWithObjects:' should be an Objective-C pointer type, not 'char *'}}
+ [[[NSOrderedSet alloc] initWithObjects:@"Foo", "Bar", nil] autorelease]; // expected-warning {{Argument to 'NSOrderedSet' method 'initWithObjects:' should be an Objective-C pointer type, not 'char *'}}
}
// This previously crashed the variadic argument checker.