Author: andersca
Date: Tue Mar  8 14:05:26 2011
New Revision: 127268

URL: http://llvm.org/viewvc/llvm-project?rev=127268&view=rev
Log:
Make the Objective-C checker look for subclasses of NSString instead of just 
NSString and NSMutableString.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
    cfe/trunk/test/Analysis/NSString.m

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp?rev=127268&r1=127267&r2=127268&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp Tue Mar 
 8 14:05:26 2011
@@ -41,20 +41,21 @@
 // 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::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())

Modified: cfe/trunk/test/Analysis/NSString.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NSString.m?rev=127268&r1=127267&r2=127268&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/NSString.m (original)
+++ cfe/trunk/test/Analysis/NSString.m Tue Mar  8 14:05:26 2011
@@ -190,6 +190,13 @@
   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;


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to