diff options
author | Anders Carlsson <andersca@mac.com> | 2011-03-08 20:05:26 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2011-03-08 20:05:26 +0000 |
commit | 3c50aea73fee98d6236f7022685685fd9c4b32d4 (patch) | |
tree | fd5c04ff77ff710e2aeeecfdb42dc3ed8a8a628e /clang | |
parent | eee5413f3b941ddbb44ceba55a50641dcae3fbf1 (diff) | |
download | bcm5719-llvm-3c50aea73fee98d6236f7022685685fd9c4b32d4.tar.gz bcm5719-llvm-3c50aea73fee98d6236f7022685685fd9c4b32d4.zip |
Make the Objective-C checker look for subclasses of NSString instead of just NSString and NSMutableString.
llvm-svn: 127268
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp | 27 | ||||
-rw-r--r-- | clang/test/Analysis/NSString.m | 7 |
2 files changed, 21 insertions, 13 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp index e002a29379d..f7a1ebe3863 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp @@ -41,20 +41,21 @@ public: // Utility functions. //===----------------------------------------------------------------------===// -static const ObjCInterfaceType* GetReceiverType(const ObjCMessage &msg) { +static const char* GetReceiverNameType(const ObjCMessage &msg) { if (const ObjCInterfaceDecl *ID = msg.getReceiverInterface()) - return ID->getTypeForDecl()->getAs<ObjCInterfaceType>(); - return NULL; + return ID->getIdentifier()->getNameStart(); + return 0; } -static const char* GetReceiverNameType(const ObjCMessage &msg) { - if (const ObjCInterfaceType *ReceiverType = GetReceiverType(msg)) - return ReceiverType->getDecl()->getIdentifier()->getNameStart(); - return NULL; -} +static bool isReceiverClassOrSuperclass(const ObjCInterfaceDecl *ID, + llvm::StringRef ClassName) { + if (ID->getIdentifier()->getName() == ClassName) + return true; + + if (const ObjCInterfaceDecl *Super = ID->getSuperClass()) + return isReceiverClassOrSuperclass(Super, ClassName); -static bool isNSString(llvm::StringRef ClassName) { - return ClassName == "NSString" || ClassName == "NSMutableString"; + return false; } static inline bool isNil(SVal X) { @@ -98,11 +99,11 @@ void NilArgChecker::WarnNilArg(CheckerContext &C, void NilArgChecker::checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const { - const ObjCInterfaceType *ReceiverType = GetReceiverType(msg); - if (!ReceiverType) + const ObjCInterfaceDecl *ID = msg.getReceiverInterface(); + if (!ID) return; - if (isNSString(ReceiverType->getDecl()->getIdentifier()->getName())) { + if (isReceiverClassOrSuperclass(ID, "NSString")) { Selector S = msg.getSelector(); if (S.isUnarySelector()) diff --git a/clang/test/Analysis/NSString.m b/clang/test/Analysis/NSString.m index 16b527fcc7c..76bf4a14717 100644 --- a/clang/test/Analysis/NSString.m +++ b/clang/test/Analysis/NSString.m @@ -190,6 +190,13 @@ void f13(void) { CFRelease(ref); // expected-warning{{Reference-counted object is used after it is released}} } +@interface MyString : NSString +@end + +void f14(MyString *s) { + [s compare:0]; // expected-warning {{Argument to 'MyString' method 'compare:' cannot be nil.}} +} + // Test regular use of -autorelease @interface TestAutorelease -(NSString*) getString; |