diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-12-03 21:11:54 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-12-03 21:11:54 +0000 |
commit | db5ce0f71ec99f0e60b99b6353b2e925af6c881b (patch) | |
tree | 345eb6ea6d7e265092b9a07285a53a3aa5fa744a /clang | |
parent | b66d3cf5cf8400d9c99d5dd237ab6908377bbbfa (diff) | |
download | bcm5719-llvm-db5ce0f71ec99f0e60b99b6353b2e925af6c881b.tar.gz bcm5719-llvm-db5ce0f71ec99f0e60b99b6353b2e925af6c881b.zip |
[objc] Add a warning when a class that provides a designated initializer, does not
override all of the designated initializers of its superclass.
llvm-svn: 196319
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaObjCProperty.cpp | 28 | ||||
-rw-r--r-- | clang/test/SemaObjC/attr-designated-init.m | 14 |
5 files changed, 46 insertions, 7 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 0ca9a082108..e0eaf341adc 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2449,6 +2449,9 @@ def warn_objc_secondary_init_super_init_call : Warning< 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">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 06edb443cde..3fbe2b78270 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -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 { diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index a41bd22cdf1..6020473e979 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -2674,7 +2674,9 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods, 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 diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index d9d9cec1b70..f70e84d7a06 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -1830,6 +1830,34 @@ void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D } } +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, diff --git a/clang/test/SemaObjC/attr-designated-init.m b/clang/test/SemaObjC/attr-designated-init.m index 513e51515d6..3d8bd1c3e5e 100644 --- a/clang/test/SemaObjC/attr-designated-init.m +++ b/clang/test/SemaObjC/attr-designated-init.m @@ -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 -@implementation SS2 +@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 -@implementation SS3 +@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 -@implementation S6 +@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]; } |