From ae81e172e93b75594c7053f3226a16b9d8daa6fd Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Fri, 11 Jan 2013 03:52:37 +0000 Subject: [PATCH] [analyzer] Ivar invalidation: track ivars declared in categories. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172168 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/IvarInvalidationChecker.cpp | 22 +++++++++++++------ test/Analysis/objc_invalidation.m | 9 ++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp b/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp index 80cb58d76b..527470a17c 100644 --- a/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp @@ -227,15 +227,23 @@ void IvarInvalidationChecker::containsInvalidationMethod( } // If interface, check all parent protocols and super. - // TODO: Visit all categories in case the invalidation method is declared in - // a category. - if (const ObjCInterfaceDecl *InterfaceD = dyn_cast(D)) { + if (const ObjCInterfaceDecl *InterfD = dyn_cast(D)) { + + // Visit all protocols. for (ObjCInterfaceDecl::protocol_iterator - I = InterfaceD->protocol_begin(), - E = InterfaceD->protocol_end(); I != E; ++I) { + I = InterfD->protocol_begin(), + E = InterfD->protocol_end(); I != E; ++I) { containsInvalidationMethod(*I, OutInfo); } - containsInvalidationMethod(InterfaceD->getSuperClass(), OutInfo); + + // Visit all categories in case the invalidation method is declared in + // a category. + for (const ObjCCategoryDecl *I = InterfD->getFirstClassExtension(); I; + I = I->getNextClassExtension()) { + containsInvalidationMethod(I, OutInfo); + } + + containsInvalidationMethod(InterfD->getSuperClass(), OutInfo); return; } @@ -249,7 +257,7 @@ void IvarInvalidationChecker::containsInvalidationMethod( return; } - llvm_unreachable("One of the casts above should have succeeded."); + return; } bool IvarInvalidationChecker::trackIvar(const ObjCIvarDecl *Iv, diff --git a/test/Analysis/objc_invalidation.m b/test/Analysis/objc_invalidation.m index f21bfdf474..15bcabec69 100644 --- a/test/Analysis/objc_invalidation.m +++ b/test/Analysis/objc_invalidation.m @@ -41,6 +41,13 @@ extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, @interface Invalidation1Class @end +@interface ClassWithInvalidationMethodInCategory +@end + +@interface ClassWithInvalidationMethodInCategory () +- (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator"))); +@end + @interface SomeInvalidationImplementingObject: NSObject { SomeInvalidationImplementingObject *ObjA; // invalidation in the parent } @@ -107,6 +114,7 @@ extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, @implementation SomeSubclassInvalidatableObject{ @private SomeInvalidationImplementingObject *Ivar5; + ClassWithInvalidationMethodInCategory *Ivar13; } @synthesize Prop7 = _propIvar; @@ -156,6 +164,7 @@ extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, // expected-warning@-5 {{Instance variable _Ivar3 needs to be invalidated}} // expected-warning@-6 {{Instance variable _Ivar4 needs to be invalidated}} // expected-warning@-7 {{Instance variable Ivar5 needs to be invalidated or set to nil}} +// expected-warning@-8 {{Instance variable Ivar13 needs to be invalidated or set to nil}} @end // Example, where the same property is inherited through -- 2.50.1