Don't issue a missing +dealloc warning for classes that just contain SEL ivars.

This fixes PR 2592: http://llvm.org/bugs/show_bug.cgi?id=2592

llvm-svn: 53987
This commit is contained in:
Ted Kremenek 2008-07-24 17:45:56 +00:00
parent 66cd9a32d2
commit 0e60b7588a
3 changed files with 40 additions and 21 deletions

View File

@ -42,6 +42,13 @@ static bool scan_dealloc(Stmt* S, Selector Dealloc) {
return false;
}
static bool isSEL(QualType T, IdentifierInfo* SelII) {
if (const TypedefType* Ty = T->getAsTypedefType())
return Ty->getDecl()->getIdentifier() == SelII;
return false;
}
void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
const LangOptions& LOpts, BugReporter& BR) {
@ -56,6 +63,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
// http://llvm.org/bugs/show_bug.cgi?id=2517
bool containsPointerIvar = false;
IdentifierInfo* SelII = &Ctx.Idents.get("SEL");
for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
I!=E; ++I) {
@ -64,7 +72,8 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
QualType T = ID->getType();
if ((T->isPointerType() || T->isObjCQualifiedIdType()) &&
ID->getAttr<IBOutletAttr>() == 0) { // Skip IBOutlets.
(ID->getAttr<IBOutletAttr>() == 0 && // Skip IBOutlets.
!isSEL(T, SelII))) { // Skip SEL ivars.
containsPointerIvar = true;
break;
}

View File

@ -1,20 +0,0 @@
// RUN: clang -warn-objc-missing-dealloc '-DIBOutlet=__attribute__((iboutlet))' %s --verify
#ifndef IBOutlet
#define IBOutlet
#endif
@class NSWindow;
@interface NSObject {}
- (void)dealloc;
@end
@interface A : NSObject {
IBOutlet NSWindow *window;
}
@end
@implementation A // no-warning
@end

View File

@ -0,0 +1,30 @@
// RUN: clang -warn-objc-missing-dealloc -verify %s
typedef struct objc_selector *SEL;
typedef signed char BOOL;
typedef unsigned int NSUInteger;
typedef struct _NSZone NSZone;
@protocol NSObject
- (BOOL)isEqual:(id)object;
@end
@interface NSObject <NSObject> {}
- (id)init;
@end
@interface TestSELs : NSObject {
SEL a;
SEL b;
}
@end
@implementation TestSELs // no-warning
- (id)init {
if( (self = [super init]) ) {
a = @selector(a);
b = @selector(b);
}
return self;
}
@end