]> granicus.if.org Git - clang/commitdiff
Warn on missing [super finalize] calls.
authorNico Weber <nicolasweber@gmx.de>
Sun, 28 Aug 2011 22:35:17 +0000 (22:35 +0000)
committerNico Weber <nicolasweber@gmx.de>
Sun, 28 Aug 2011 22:35:17 +0000 (22:35 +0000)
This matches gcc's logic. Second half of PR10661.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138730 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Basic/IdentifierTable.h
include/clang/Sema/Sema.h
lib/AST/DeclObjC.cpp
lib/Analysis/CocoaConventions.cpp
lib/Basic/IdentifierTable.cpp
lib/Sema/Sema.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaExprObjC.cpp
test/SemaObjC/warn-missing-super.m

index d5b3ac3ac32956ac13cc0065765b242326d678e4..7bf2dc4d9cfbec6474efa76cb882b5e52bb116ee 100644 (file)
@@ -573,6 +573,9 @@ def warn_objc_property_attr_mutually_exclusive : Warning<
 def warn_objc_missing_super_dealloc : Warning<
   "method possibly missing a [super dealloc] call">,
   InGroup<ObjCMissingSuperCalls>;
+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<
index 017af5caee0bbf4c8c695724655ee04cbade0079..bd0b539d2094723ec02b1ba6d3b2e2fda70ed194 100644 (file)
@@ -487,6 +487,7 @@ enum ObjCMethodFamily {
   // selector with the given name.
   OMF_autorelease,
   OMF_dealloc,
+  OMF_finalize,
   OMF_release,
   OMF_retain,
   OMF_retainCount,
index 299480399b3d65fffcb339d9b459ffc398d59ec8..f6d5edc4e482bbb752916d620ea4d4841aa39685 100644 (file)
@@ -493,6 +493,9 @@ public:
   /// 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;
 
   /// \brief The set of declarations that have been referenced within
   /// a potentially evaluated expression.
index 367e6a66a4323665ceeb04469b00e7b58a6bd27f..09638fefbd3c9771c21186c28fd67efb839316c5 100644 (file)
@@ -446,6 +446,7 @@ ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
 
   // These selectors have a conventional meaning only for instance methods.
   case OMF_dealloc:
+  case OMF_finalize:
   case OMF_retain:
   case OMF_release:
   case OMF_autorelease:
index ea60f26e22a249cc104f5364ac657dcbaa5001b4..3926ce55aa256e38f93717f9d7bf705c5592e0da 100644 (file)
@@ -40,6 +40,7 @@ cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S,
   case OMF_None:
   case OMF_autorelease:
   case OMF_dealloc:
+  case OMF_finalize:
   case OMF_release:
   case OMF_retain:
   case OMF_retainCount:
index edf2e99a518b1e22b0d89ee20bb7716ebccb6b19..792b0c9c6171f5505381ed9268cf559523bde7e4 100644 (file)
@@ -392,6 +392,7 @@ ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
   if (sel.isUnarySelector()) {
     if (name == "autorelease") return OMF_autorelease;
     if (name == "dealloc") return OMF_dealloc;
+    if (name == "finalize") return OMF_finalize;
     if (name == "release") return OMF_release;
     if (name == "retain") return OMF_retain;
     if (name == "retainCount") return OMF_retainCount;
index d3ace9dc69e149c55ecee025808eb980470c2e9b..7bd0a4a3308d6a72fd1844a09ac3e275ea87df43 100644 (file)
@@ -85,6 +85,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
     IdResolver(pp.getLangOptions()), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
     GlobalNewDeleteDeclared(false), 
     ObjCShouldCallSuperDealloc(false),
+    ObjCShouldCallSuperFinalize(false),
     TUKind(TUKind),
     NumSFINAEErrors(0), SuppressAccessChecking(false), 
     AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
index 8f08af4778b464de1eaaa981ffd5f63de7a7cdcf..2f2ba7f8e6d64ac68570e602a5c5087fb8a76a4c 100644 (file)
@@ -6674,12 +6674,18 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
       Diag(MD->getLocEnd(), diag::warn_objc_missing_super_dealloc);
       ObjCShouldCallSuperDealloc = false;
     }
+    if (ObjCShouldCallSuperFinalize) {
+      Diag(MD->getLocEnd(), diag::warn_objc_missing_super_finalize);
+      ObjCShouldCallSuperFinalize = false;
+    }
   } else {
     return 0;
   }
 
   assert(!ObjCShouldCallSuperDealloc && "This should only be set for "
          "ObjC methods, which should have been handled in the block above.");
+  assert(!ObjCShouldCallSuperFinalize && "This should only be set for "
+         "ObjC methods, which should have been handled in the block above.");
 
   // Verify and clean out per-function state.
   if (Body) {
index c7d3590fb855a35db4e37326a661f5c25a1882a8..9b6166bc5b22e180e5a59027cb222d77105d186f 100644 (file)
@@ -162,6 +162,7 @@ static bool CheckARCMethodDecl(Sema &S, ObjCMethodDecl *method) {
   switch (family) {
   case OMF_None:
   case OMF_dealloc:
+  case OMF_finalize:
   case OMF_retain:
   case OMF_release:
   case OMF_autorelease:
@@ -267,6 +268,7 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
 
     case OMF_None:
     case OMF_dealloc:
+    case OMF_finalize:
     case OMF_alloc:
     case OMF_init:
     case OMF_mutableCopy:
@@ -287,14 +289,16 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
                                           dyn_cast<NamedDecl>(IMD), 
                                           MDecl->getLocation(), 0);
 
-    // If this is "dealloc", set some bit here.
+    // If this is "dealloc" or "finalize", set some bit here.
     // Then in ActOnSuperMessage() (SemaExprObjC), set it back to false.
     // Finally, in ActOnFinishFunctionBody() (SemaDecl), warn if flag is set.
     // Only do this if the current class actually has a superclass.
-    if (IC->getSuperClass())
+    if (IC->getSuperClass()) {
       ObjCShouldCallSuperDealloc = 
         !Context.getLangOptions().ObjCAutoRefCount &&      
         MDecl->getMethodFamily() == OMF_dealloc;
+      ObjCShouldCallSuperFinalize = MDecl->getMethodFamily() == OMF_finalize;
+    }
   }
 }
 
@@ -1256,6 +1260,7 @@ static bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl,
   case OMF_release:
   case OMF_autorelease:
   case OMF_dealloc:
+  case OMF_finalize:
   case OMF_retainCount:
   case OMF_self:
   case OMF_performSelector:
@@ -2637,6 +2642,7 @@ Decl *Sema::ActOnMethodDeclaration(
     case OMF_None:
     case OMF_copy:
     case OMF_dealloc:
+    case OMF_finalize:
     case OMF_mutableCopy:
     case OMF_release:
     case OMF_retainCount:
index db5de4ca9c0d196d323f98fc145712c6e061242e..402e54c0e80190f8525ea44801c3b289e6a21f11 100644 (file)
@@ -203,6 +203,7 @@ ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
     case OMF_None:
     case OMF_alloc:
     case OMF_copy:
+    case OMF_finalize:
     case OMF_init:
     case OMF_mutableCopy:
     case OMF_new:
@@ -977,6 +978,8 @@ ExprResult Sema::ActOnSuperMessage(Scope *S,
   if (Method->isInstanceMethod()) {
     if (Sel.getMethodFamily() == OMF_dealloc)
       ObjCShouldCallSuperDealloc = false;
+    if (Sel.getMethodFamily() == OMF_finalize)
+      ObjCShouldCallSuperFinalize = false;
 
     // Since we are in an instance method, this is an instance
     // message to the superclass instance.
@@ -1418,6 +1421,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
     case OMF_None:
     case OMF_alloc:
     case OMF_copy:
+    case OMF_finalize:
     case OMF_mutableCopy:
     case OMF_new:
     case OMF_self:
index 19c6b62577ea0a08a3a7c55a96ccfe318295e3a0..ff0c415872fc34628905f57cc256a360f44723fc 100644 (file)
@@ -8,31 +8,43 @@
 - (void)dealloc {
   // Root class, shouldn't warn
 }
+- (void)finalize {
+  // Root class, shouldn't warn
+}
 @end
 
 @interface Subclass1 : NSObject
 - (void)dealloc;
+- (void)finalize;
 @end
 
 @implementation Subclass1
 - (void)dealloc {
 }
+- (void)finalize {
+}
 @end
 
 @interface Subclass2 : NSObject
 - (void)dealloc;
+- (void)finalize;
 @end
 
 @implementation Subclass2
 - (void)dealloc {
   [super dealloc];  // Shouldn't warn
 }
+- (void)finalize {
+  [super finalize];  // Shouldn't warn
+}
 @end
 
 // RUN: %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck %s
-// CHECK: warn-missing-super.m:19:1: warning: method possibly missing a [super dealloc] call
-// CHECK: 1 warning generated.
+// CHECK: warn-missing-super.m:23:1: warning: method possibly missing a [super dealloc] call
+// CHECK: warn-missing-super.m:25:1: warning: method possibly missing a [super finalize] call
+// CHECK: 2 warnings generated.
 
 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fobjc-arc %s 2>&1 | FileCheck --check-prefix=CHECK-ARC %s
-// CHECK-ARC: warn-missing-super.m:28:4: error: ARC forbids explicit message send of 'dealloc'
-// CHECK-ARC: 1 error generated.
+// CHECK-ARC: warn-missing-super.m:25:1: warning: method possibly missing a [super finalize] call
+// CHECK-ARC: warn-missing-super.m:35:4: error: ARC forbids explicit message send of 'dealloc'
+// CHECK-ARC: 1 warning and 1 error generated.