diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | include/clang/Sema/ScopeInfo.h | 14 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 28 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 16 | ||||
-rw-r--r-- | test/SemaObjC/super-dealloc-attribute.m | 21 |
6 files changed, 48 insertions, 47 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 51bb9f51e1..18600a4446 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -754,9 +754,6 @@ def warn_objc_missing_super_call : Warning< def error_dealloc_bad_result_type : Error< "dealloc return type must be correctly specified as 'void' under ARC, " "instead of %0">; -def warn_objc_missing_super_finalize : Warning< - "method possibly missing a [super finalize] call">, - InGroup<ObjCMissingSuperCalls>; def warn_undeclared_selector : Warning< "undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore; def warn_implicit_atomic_property : Warning< diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index c0c907e834..0bfc6dcae6 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -91,13 +91,10 @@ public: /// \brief Whether this function contains any indirect gotos. bool HasIndirectGoto; - /// A flag that is set when parsing a -dealloc method and no [super dealloc] - /// call was found yet. - bool ObjCShouldCallSuperDealloc; - - /// A flag that is set when parsing a -finalize method and no [super finalize] - /// call was found yet. - bool ObjCShouldCallSuperFinalize; + /// A flag that is set when parsing a method that must call super's + /// implementation, such as \c -dealloc, \c -finalize, or any method marked + /// with \c __attribute__((objc_requires_super)). + bool ObjCShouldCallSuper; /// \brief Used to determine if errors occurred in this function or block. DiagnosticErrorTrap ErrorTrap; @@ -299,8 +296,7 @@ public: HasBranchProtectedScope(false), HasBranchIntoScope(false), HasIndirectGoto(false), - ObjCShouldCallSuperDealloc(false), - ObjCShouldCallSuperFinalize(false), + ObjCShouldCallSuper(false), ErrorTrap(Diag) { } virtual ~FunctionScopeInfo(); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 6791273384..f55415996b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -7944,23 +7944,16 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (Body) computeNRVO(Body, getCurFunction()); } - if (getCurFunction()->ObjCShouldCallSuperDealloc) { + if (getCurFunction()->ObjCShouldCallSuper) { Diag(MD->getLocEnd(), diag::warn_objc_missing_super_call) << MD->getSelector().getAsString(); - getCurFunction()->ObjCShouldCallSuperDealloc = false; - } - if (getCurFunction()->ObjCShouldCallSuperFinalize) { - Diag(MD->getLocEnd(), diag::warn_objc_missing_super_finalize); - getCurFunction()->ObjCShouldCallSuperFinalize = false; + getCurFunction()->ObjCShouldCallSuper = false; } } else { return 0; } - assert(!getCurFunction()->ObjCShouldCallSuperDealloc && - "This should only be set for ObjC methods, which should have been " - "handled in the block above."); - assert(!getCurFunction()->ObjCShouldCallSuperFinalize && + assert(!getCurFunction()->ObjCShouldCallSuper && "This should only be set for ObjC methods, which should have been " "handled in the block above."); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index fa330d63c4..a4fec7aebf 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -383,19 +383,23 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { // Finally, in ActOnFinishFunctionBody() (SemaDecl), warn if flag is set. // Only do this if the current class actually has a superclass. if (IC->getSuperClass()) { - getCurFunction()->ObjCShouldCallSuperDealloc = - !(Context.getLangOpts().ObjCAutoRefCount || - Context.getLangOpts().getGC() == LangOptions::GCOnly) && - MDecl->getMethodFamily() == OMF_dealloc; - if (!getCurFunction()->ObjCShouldCallSuperDealloc) { - IMD = IC->getSuperClass()->lookupMethod(MDecl->getSelector(), - MDecl->isInstanceMethod()); - getCurFunction()->ObjCShouldCallSuperDealloc = - (IMD && IMD->hasAttr<ObjCRequiresSuperAttr>()); + ObjCMethodFamily Family = MDecl->getMethodFamily(); + if (Family == OMF_dealloc) { + if (!(getLangOpts().ObjCAutoRefCount || + getLangOpts().getGC() == LangOptions::GCOnly)) + getCurFunction()->ObjCShouldCallSuper = true; + + } else if (Family == OMF_finalize) { + if (Context.getLangOpts().getGC() != LangOptions::NonGC) + getCurFunction()->ObjCShouldCallSuper = true; + + } else { + const ObjCMethodDecl *SuperMethod = + IC->getSuperClass()->lookupMethod(MDecl->getSelector(), + MDecl->isInstanceMethod()); + getCurFunction()->ObjCShouldCallSuper = + (SuperMethod && SuperMethod->hasAttr<ObjCRequiresSuperAttr>()); } - getCurFunction()->ObjCShouldCallSuperFinalize = - Context.getLangOpts().getGC() != LangOptions::NonGC && - MDecl->getMethodFamily() == OMF_finalize; } } } diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 3f9c14c685..e43b6bff55 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1772,20 +1772,10 @@ ExprResult Sema::ActOnSuperMessage(Scope *S, // We are in a method whose class has a superclass, so 'super' // is acting as a keyword. - if (Method->isInstanceMethod()) { - if (Sel.getMethodFamily() == OMF_dealloc) - getCurFunction()->ObjCShouldCallSuperDealloc = false; - else if (const ObjCMethodDecl *IMD = - Class->lookupMethod(Method->getSelector(), - Method->isInstanceMethod())) - // Must check for name of message since the method could - // be another method with objc_requires_super attribute set. - if (IMD->hasAttr<ObjCRequiresSuperAttr>() && - Sel == IMD->getSelector()) - getCurFunction()->ObjCShouldCallSuperDealloc = false; - if (Sel.getMethodFamily() == OMF_finalize) - getCurFunction()->ObjCShouldCallSuperFinalize = false; + if (Method->getSelector() == Sel) + getCurFunction()->ObjCShouldCallSuper = false; + if (Method->isInstanceMethod()) { // Since we are in an instance method, this is an instance // message to the superclass instance. QualType SuperTy = Context.getObjCInterfaceType(Super); diff --git a/test/SemaObjC/super-dealloc-attribute.m b/test/SemaObjC/super-dealloc-attribute.m index 0ba65cc078..35f6dac9bf 100644 --- a/test/SemaObjC/super-dealloc-attribute.m +++ b/test/SemaObjC/super-dealloc-attribute.m @@ -19,6 +19,8 @@ - (void) MyDeallocMeth; // Method in root is not annotated. - (void) AnnotMyDeallocMeth __attribute((objc_requires_super)); - (void) AnnotMyDeallocMethCAT NS_REQUIRES_SUPER; + ++ (void)registerClass:(id)name __attribute((objc_requires_super)); @end @interface Baz : Root<NSObject> @@ -41,6 +43,8 @@ - (void) MyDeallocMeth {} // No warning here. - (void) AnnotMyDeallocMeth{} // expected-warning {{method possibly missing a [super AnnotMyDeallocMeth] call}} - (void) AnnotMeth{}; // No warning here. Annotation is in its class. + ++ (void)registerClass:(id)name {} // expected-warning {{method possibly missing a [super registerClass:] call}} @end @interface Bar : Baz @@ -64,3 +68,20 @@ - (void) AnnotMyDeallocMethCAT{}; // expected-warning {{method possibly missing a [super AnnotMyDeallocMethCAT] call}} - (void) AnnotMethCAT {}; @end + + +@interface Valid : Baz +@end + +@implementation Valid + +- (void)MyDeallocMeth { + [super MyDeallocMeth]; // no-warning +} + + ++ (void)registerClass:(id)name { + [super registerClass:name]; // no-warning +} + +@end |