aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--include/clang/Sema/ScopeInfo.h14
-rw-r--r--lib/Sema/SemaDecl.cpp13
-rw-r--r--lib/Sema/SemaDeclObjC.cpp28
-rw-r--r--lib/Sema/SemaExprObjC.cpp16
-rw-r--r--test/SemaObjC/super-dealloc-attribute.m21
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