summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-12-03 21:11:54 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-12-03 21:11:54 +0000
commitdb5ce0f71ec99f0e60b99b6353b2e925af6c881b (patch)
tree345eb6ea6d7e265092b9a07285a53a3aa5fa744a /clang
parentb66d3cf5cf8400d9c99d5dd237ab6908377bbbfa (diff)
downloadbcm5719-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.td3
-rw-r--r--clang/include/clang/Sema/Sema.h4
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp4
-rw-r--r--clang/lib/Sema/SemaObjCProperty.cpp28
-rw-r--r--clang/test/SemaObjC/attr-designated-init.m14
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];
}
OpenPOWER on IntegriCloud