summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2011-03-08 20:05:26 +0000
committerAnders Carlsson <andersca@mac.com>2011-03-08 20:05:26 +0000
commit3c50aea73fee98d6236f7022685685fd9c4b32d4 (patch)
treefd5c04ff77ff710e2aeeecfdb42dc3ed8a8a628e /clang
parenteee5413f3b941ddbb44ceba55a50641dcae3fbf1 (diff)
downloadbcm5719-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.cpp27
-rw-r--r--clang/test/Analysis/NSString.m7
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;
OpenPOWER on IntegriCloud