diff options
| author | Jordy Rose <jediknil@belkadan.com> | 2012-04-06 19:06:01 +0000 |
|---|---|---|
| committer | Jordy Rose <jediknil@belkadan.com> | 2012-04-06 19:06:01 +0000 |
| commit | c0230d7a35fcb0c3de63aa1e2e1a845d53e400f6 (patch) | |
| tree | 8dac12e4abb0c01f03aea0728a9481ea26c3100d | |
| parent | 6fb26f8c7e2be6aa6ed347d87f3c75189f8e9ac3 (diff) | |
| download | bcm5719-llvm-c0230d7a35fcb0c3de63aa1e2e1a845d53e400f6.tar.gz bcm5719-llvm-c0230d7a35fcb0c3de63aa1e2e1a845d53e400f6.zip | |
[analyzer] Check that the arguments to NSOrderedSet creation methods are valid ObjC objects.
Patch by Sean McBride!
llvm-svn: 154194
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp | 12 | ||||
| -rw-r--r-- | clang/test/Analysis/variadic-method-types.m | 8 |
2 files changed, 20 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp index dd4235af5ef..6dd0a8c01fe 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp +++ b/clang/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/clang/test/Analysis/variadic-method-types.m b/clang/test/Analysis/variadic-method-types.m index caa0c59debb..4d0f6bc3f75 100644 --- a/clang/test/Analysis/variadic-method-types.m +++ b/clang/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. |

