]> granicus.if.org Git - clang/commitdiff
[PATCH Sema Objective-C]. Patch to warn on missing designated initializer
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 9 Mar 2015 20:39:51 +0000 (20:39 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 9 Mar 2015 20:39:51 +0000 (20:39 +0000)
override where at least a declaration of a designated initializer is in a super
class and not necessarily in the current class. rdar://19653785.

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

include/clang/AST/DeclObjC.h
include/clang/Sema/Sema.h
lib/AST/DeclObjC.cpp
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaObjCProperty.cpp
test/SemaObjC/attr-designated-init.m

index 3c24d05dc5b09487361a7fc8075386c7e578f6cb..46f3c7dfe3c44d5748ae6fd035af128ea45899c6 100644 (file)
@@ -803,6 +803,8 @@ public:
     return hasDesignatedInitializers() || inheritsDesignatedInitializers();
   }
 
+  bool hasDesignatedInitializersInSuperClass() const;
+
   const ObjCProtocolList &getReferencedProtocols() const {
     assert(hasDefinition() && "Caller did not check for forward reference!");
     if (data().ExternallyCompleted)
index aa7107a259d1bcf8b6ac794a895a03070b51a83c..0b36d58806aecfc82e49cba7ad4565245d27aa29 100644 (file)
@@ -2923,8 +2923,7 @@ public:
   void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D);
 
   void DiagnoseMissingDesignatedInitOverrides(
-                                          const ObjCImplementationDecl *ImplD,
-                                          const ObjCInterfaceDecl *IFD);
+                                          const ObjCImplementationDecl *ImplD);
 
   void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
 
index 77995b5261f6ac8860ac936e5a61af468eb1ab0f..abd9b33f5db0a7312f891cb1d362da14d69b1ecb 100644 (file)
@@ -1213,6 +1213,16 @@ bool ObjCInterfaceDecl::hasDesignatedInitializers() const {
   return data().HasDesignatedInitializers;
 }
 
+bool ObjCInterfaceDecl::hasDesignatedInitializersInSuperClass() const {
+  ObjCInterfaceDecl *OSC = getSuperClass();
+  while (OSC) {
+    if (OSC->hasDesignatedInitializers())
+      return true;
+    OSC = OSC->getSuperClass();
+  }
+  return false;
+}
+
 StringRef
 ObjCInterfaceDecl::getObjCRuntimeNameAsString() const {
   if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
index 33d9e95f27f0b6be919753c5d59512edc5d4110d..d958db582afe9406bf705eb554947438f72e89b6 100644 (file)
@@ -2715,8 +2715,9 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods,
       AtomicPropertySetterGetterRules(IC, IDecl);
       DiagnoseOwningPropertyGetterSynthesis(IC);
       DiagnoseUnusedBackingIvarInAccessor(S, IC);
-      if (IDecl->hasDesignatedInitializers())
-        DiagnoseMissingDesignatedInitOverrides(IC, IDecl);
+      if (IDecl->hasDesignatedInitializers() ||
+          IDecl->hasDesignatedInitializersInSuperClass())
+        DiagnoseMissingDesignatedInitOverrides(IC);
 
       bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>();
       if (IDecl->getSuperClass() == nullptr) {
index f4f43360f5e1465e9c4fd4d538a9e8cd4f9ed70f..716fb50ea69198f6e9ddbda7aab1c2ffa69375ae 100644 (file)
@@ -1894,9 +1894,11 @@ void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D
 }
 
 void Sema::DiagnoseMissingDesignatedInitOverrides(
-                                            const ObjCImplementationDecl *ImplD,
-                                            const ObjCInterfaceDecl *IFD) {
-  assert(IFD->hasDesignatedInitializers());
+                                            const ObjCImplementationDecl *ImplD) {
+  const ObjCInterfaceDecl *IFD = ImplD->getClassInterface();
+  assert(IFD);
+  assert(IFD->hasDesignatedInitializers() ||
+         IFD->hasDesignatedInitializersInSuperClass());
   const ObjCInterfaceDecl *SuperD = IFD->getSuperClass();
   if (!SuperD)
     return;
index a8673e1b01912f3a49f402383e60d63069de96d4..f990c35bac827c29ce8e248fd5195e9dd3dfe32e 100644 (file)
@@ -39,7 +39,7 @@ __attribute__((objc_root_class))
 @end
 
 @interface B1()
--(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
+-(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 6 {{method marked as designated initializer of the class here}}
 @end;
 
 @implementation B1
@@ -182,7 +182,7 @@ __attribute__((objc_root_class))
 -(id)initB1;
 @end
 
-@implementation SS4
+@implementation SS4 // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
 -(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
   return 0;
 }
@@ -233,7 +233,7 @@ __attribute__((objc_root_class))
 -(id)initB1;
 @end
 
-@implementation SS9
+@implementation SS9 // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
 -(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
   return 0;
 }
@@ -418,3 +418,41 @@ __attribute__((objc_root_class))
 @interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}}
 - (instancetype)init NS_DESIGNATED_INITIALIZER; // expected-error{{only applies to init methods of interface or class extension declarations}}
 @end
+
+// rdar://19653785
+@class NSCoder;
+
+@interface NSView 
+- (instancetype)initWithFrame:(int)frameRect NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
+- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
+@end
+
+@interface MyHappyView : NSView
+- (instancetype)initWithFrame:(int)frameRect andOtherThing:(id)otherThing NS_DESIGNATED_INITIALIZER;
+@end
+
+@implementation MyHappyView // expected-warning {{method override for the designated initializer of the superclass '-initWithCoder:' not found}}
+- (instancetype)initWithFrame:(int)frameRect andOtherThing:(id)otherThing {
+ if (self = [super initWithFrame:frameRect]) {
+ }
+ return self;
+}
+
+- (instancetype)initWithFrame:(int)frameRect {
+ return [self initWithFrame:frameRect andOtherThing:((void *)0)];
+}
+@end
+
+@interface MySadView : NSView
+@end
+
+@implementation MySadView  // expected-warning {{method override for the designated initializer of the superclass '-initWithFrame:' not found}} \
+                          // expected-warning {{method override for the designated initializer of the superclass '-initWithCoder:' not found}}
+- (instancetype)initWithFrame:(int)frameRect andOtherThing:(id)otherThing {
+ if (self = [super initWithFrame:frameRect]) {
+ }
+
+ return self;
+}
+@end
+