]> granicus.if.org Git - clang/commitdiff
Objective-C. Allow [super initialize] in an +initialize
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 25 Aug 2014 21:27:38 +0000 (21:27 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 25 Aug 2014 21:27:38 +0000 (21:27 +0000)
implementation but not anywhere else.
rdar://16628028

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

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExprObjC.cpp
test/SemaObjC/warn-explicit-call-initialize.m

index 7a74a9830490f5c44c56ecd44e4a448326f182d5..93328ca3ebdc0bd60652ef80785a6358a8591093 100644 (file)
@@ -268,6 +268,7 @@ def ObjCRootClass : DiagGroup<"objc-root-class">;
 def ObjCPointerIntrospectPerformSelector : DiagGroup<"deprecated-objc-pointer-introspection-performSelector">;
 def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>;
 def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
+def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
 def Packed : DiagGroup<"packed">;
 def Padded : DiagGroup<"padded">;
 def PointerArith : DiagGroup<"pointer-arith">;
index 869be0477b807325cb0830988bc316c49058741f..ca4e4b9b0dc51e57253a5f7ae6e0b9c34ce19905 100644 (file)
@@ -6879,7 +6879,11 @@ def warn_ivar_use_hidden : Warning<
    InGroup<DiagGroup<"shadow-ivar">>;
 def warn_direct_initialize_call : Warning<
   "explicit call to +initialize results in duplicate call to +initialize">,
-   InGroup<DiagGroup<"explicit-initialize-call">>;
+   InGroup<ExplicitInitializeCall>;
+def warn_direct_super_initialize_call : Warning<
+  "explicit call to [super initialize] should only be in implementation "
+  "of +initialize">,
+   InGroup<ExplicitInitializeCall>;
 def error_ivar_use_in_class_method : Error<
   "instance variable %0 accessed in class method">;
 def error_implicit_ivar_access : Error<
index 7ade45d49299375b316e1596f836610179b53e06..a30eaeae361fcc301941a8c6ad14e01b3302c0f3 100644 (file)
@@ -2237,14 +2237,25 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
     return ExprError();
   
   // Warn about explicit call of +initialize on its own class. But not on 'super'.
-  if (Method && Method->getMethodFamily() == OMF_initialize &&
-      !SuperLoc.isValid()) {
-    const ObjCInterfaceDecl *ID =
-      dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext());
-    if (ID == Class) {
-      Diag(Loc, diag::warn_direct_initialize_call);
-      Diag(Method->getLocation(), diag::note_method_declared_at)
-      << Method->getDeclName();
+  if (Method && Method->getMethodFamily() == OMF_initialize) {
+    if (!SuperLoc.isValid()) {
+      const ObjCInterfaceDecl *ID =
+        dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext());
+      if (ID == Class) {
+        Diag(Loc, diag::warn_direct_initialize_call);
+        Diag(Method->getLocation(), diag::note_method_declared_at)
+          << Method->getDeclName();
+      }
+    }
+    else if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
+      // [super initialize] is allowed only within an +initialize implementation
+      if (CurMeth->getMethodFamily() != OMF_initialize) {
+        Diag(Loc, diag::warn_direct_super_initialize_call);
+        Diag(Method->getLocation(), diag::note_method_declared_at)
+          << Method->getDeclName();
+        Diag(CurMeth->getLocation(), diag::note_method_declared_at)
+        << CurMeth->getDeclName();
+      }
     }
   }
 
index 1c7baef15e61696bff35b03c83ccc8dd05dc52c8..99fdf530afd86729a735a1f6cb5827bfd6245436 100644 (file)
@@ -2,11 +2,12 @@
 // rdar://16628028
 
 @interface NSObject
-+ (void)initialize; // expected-note {{method 'initialize' declared here}}
++ (void)initialize; // expected-note {{method 'initialize' declared here}}
 @end
 
 @interface I : NSObject 
 + (void)initialize; // expected-note {{method 'initialize' declared here}}
++ (void)SomeRandomMethod;
 @end
 
 @implementation I
@@ -17,5 +18,8 @@
 + (void)initialize {
   [super initialize];
 }
++ (void)SomeRandomMethod { // expected-note {{method 'SomeRandomMethod' declared here}}
+  [super initialize]; // expected-warning {{explicit call to [super initialize] should only be in implementation of +initialize}}
+}
 @end