r196319 - [objc] Add a warning when a class that provides a designated initializer, does not

Argyrios Kyrtzidis akyrtzi at gmail.com
Tue Dec 3 13:11:54 PST 2013


Author: akirtzidis
Date: Tue Dec  3 15:11:54 2013
New Revision: 196319

URL: http://llvm.org/viewvc/llvm-project?rev=196319&view=rev
Log:
[objc] Add a warning when a class that provides a designated initializer, does not
override all of the designated initializers of its superclass.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaObjCProperty.cpp
    cfe/trunk/test/SemaObjC/attr-designated-init.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=196319&r1=196318&r2=196319&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Dec  3 15:11:54 2013
@@ -2449,6 +2449,9 @@ def warn_objc_secondary_init_super_init_
 def warn_objc_secondary_init_missing_init_call : Warning<
   "secondary initializer missing a 'self' call to another initializer">,
   InGroup<ObjCDesignatedInit>;
+def warn_objc_implementation_missing_designated_init_override : Warning<
+  "method override for the designated initializer of the superclass %objcinstance0 not found">,
+  InGroup<ObjCDesignatedInit>;
 
 def err_ns_bridged_not_interface : Error<
   "parameter of 'ns_bridged' attribute does not name an Objective-C class">;

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=196319&r1=196318&r2=196319&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Dec  3 15:11:54 2013
@@ -2686,6 +2686,10 @@ public:
 
   void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D);
 
+  void DiagnoseMissingDesignatedInitOverrides(
+                                          const ObjCImplementationDecl *ImplD,
+                                          const ObjCInterfaceDecl *IFD);
+
   void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
 
   enum MethodMatchStrategy {

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=196319&r1=196318&r2=196319&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Tue Dec  3 15:11:54 2013
@@ -2674,7 +2674,9 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceR
       ImplMethodsVsClassMethods(S, IC, IDecl);
       AtomicPropertySetterGetterRules(IC, IDecl);
       DiagnoseOwningPropertyGetterSynthesis(IC);
-  
+      if (IDecl->hasDesignatedInitializers())
+        DiagnoseMissingDesignatedInitOverrides(IC, IDecl);
+
       bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>();
       if (IDecl->getSuperClass() == NULL) {
         // This class has no superclass, so check that it has been marked with

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=196319&r1=196318&r2=196319&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Tue Dec  3 15:11:54 2013
@@ -1830,6 +1830,34 @@ void Sema::DiagnoseOwningPropertyGetterS
   }
 }
 
+void Sema::DiagnoseMissingDesignatedInitOverrides(
+                                            const ObjCImplementationDecl *ImplD,
+                                            const ObjCInterfaceDecl *IFD) {
+  assert(IFD->hasDesignatedInitializers());
+  const ObjCInterfaceDecl *SuperD = IFD->getSuperClass();
+  if (!SuperD)
+    return;
+
+  SelectorSet InitSelSet;
+  for (ObjCImplementationDecl::instmeth_iterator
+         I = ImplD->instmeth_begin(), E = ImplD->instmeth_end(); I!=E; ++I)
+    if ((*I)->getMethodFamily() == OMF_init)
+      InitSelSet.insert((*I)->getSelector());
+
+  SmallVector<const ObjCMethodDecl *, 8> DesignatedInits;
+  SuperD->getDesignatedInitializers(DesignatedInits);
+  for (SmallVector<const ObjCMethodDecl *, 8>::iterator
+         I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
+    const ObjCMethodDecl *MD = *I;
+    if (!InitSelSet.count(MD->getSelector())) {
+      Diag(ImplD->getLocation(),
+           diag::warn_objc_implementation_missing_designated_init_override)
+        << MD->getSelector();
+      Diag(MD->getLocation(), diag::note_objc_designated_init_marked_here);
+    }
+  }
+}
+
 /// AddPropertyAttrs - Propagates attributes from a property to the
 /// implicitly-declared getter or setter for that property.
 static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod,

Modified: cfe/trunk/test/SemaObjC/attr-designated-init.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-designated-init.m?rev=196319&r1=196318&r2=196319&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/attr-designated-init.m (original)
+++ cfe/trunk/test/SemaObjC/attr-designated-init.m Tue Dec  3 15:11:54 2013
@@ -34,9 +34,9 @@ __attribute__((objc_root_class))
 
 __attribute__((objc_root_class))
 @interface B1
--(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
+-(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
 -(id)initB2;
--(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
+-(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 3 {{method marked as designated initializer of the class here}}
 @end
 
 @implementation B1
@@ -82,21 +82,22 @@ __attribute__((objc_root_class))
 -(id)initSS1 NS_DESIGNATED_INITIALIZER;
 @end
 
- at implementation SS2
+ at implementation SS2 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \
+                    // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
 -(id)initSS1 {
   return [super initB1];
 }
 @end
 
 @interface S3 : B1
--(id)initS1 NS_DESIGNATED_INITIALIZER;
+-(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
 @end
 
 @interface SS3 : S3
 -(id)initSS1 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
 @end
 
- at implementation SS3
+ at implementation SS3 // expected-warning {{method override for the designated initializer of the superclass '-initS1' not found}}
 -(id)initSS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
   return [super initB1]; // expected-warning {{designated initializer invoked a non-designated initializer}}
 }
@@ -150,7 +151,8 @@ __attribute__((objc_root_class))
 -(id)initS4;
 @end
 
- at implementation S6
+ at implementation S6 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \
+                   // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
 -(id)initS1 {
   return [super initB1];
 }





More information about the cfe-commits mailing list