forked from OSchip/llvm-project
[objc] Emit warnings when the implementation of a designated initializer calls on
super an initializer that is not a designated one or any initializer on self. llvm-svn: 196317
This commit is contained in:
parent
22bfa2c28b
commit
fcded9b93a
|
@ -457,7 +457,12 @@ public:
|
|||
|
||||
/// Returns true if the method selector resolves to a designated initializer
|
||||
/// in the class's interface.
|
||||
bool isDesignatedInitializerForTheInterface() const;
|
||||
///
|
||||
/// \param InitMethod if non-null and the function returns true, it receives
|
||||
/// the method declaration that was marked with the designated initializer
|
||||
/// attribute.
|
||||
bool isDesignatedInitializerForTheInterface(
|
||||
const ObjCMethodDecl **InitMethod = 0) const;
|
||||
|
||||
/// \brief Determine whether this method has a body.
|
||||
virtual bool hasBody() const { return Body.isValid(); }
|
||||
|
|
|
@ -2437,6 +2437,12 @@ def warn_objc_designated_init_missing_super_call : Warning<
|
|||
InGroup<ObjCDesignatedInit>;
|
||||
def note_objc_designated_init_marked_here : Note<
|
||||
"method marked as designated initializer of the class here">;
|
||||
def warn_objc_designated_init_non_super_designated_init_call : Warning<
|
||||
"designated initializer should only invoke a designated initializer on 'super'">,
|
||||
InGroup<ObjCDesignatedInit>;
|
||||
def warn_objc_designated_init_non_designated_init_call : Warning<
|
||||
"designated initializer invoked a non-designated initializer">,
|
||||
InGroup<ObjCDesignatedInit>;
|
||||
|
||||
def err_ns_bridged_not_interface : Error<
|
||||
"parameter of 'ns_bridged' attribute does not name an Objective-C class">;
|
||||
|
|
|
@ -655,12 +655,15 @@ bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {
|
|||
hasAttr<ObjCDesignatedInitializerAttr>();
|
||||
}
|
||||
|
||||
bool ObjCMethodDecl::isDesignatedInitializerForTheInterface() const {
|
||||
bool ObjCMethodDecl::isDesignatedInitializerForTheInterface(
|
||||
const ObjCMethodDecl **InitMethod) const {
|
||||
if (getMethodFamily() != OMF_init)
|
||||
return false;
|
||||
const DeclContext *DC = getDeclContext();
|
||||
if (isa<ObjCProtocolDecl>(DC))
|
||||
return false;
|
||||
if (const ObjCInterfaceDecl *ID = getClassInterface())
|
||||
return ID->isDesignatedInitializer(getSelector());
|
||||
return ID->isDesignatedInitializer(getSelector(), InitMethod);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -9816,8 +9816,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
|
|||
}
|
||||
if (getCurFunction()->ObjCWarnForNoDesignatedInitChain) {
|
||||
const ObjCMethodDecl *InitMethod = 0;
|
||||
bool isDesignated = MD->getClassInterface()
|
||||
->isDesignatedInitializer(MD->getSelector(), &InitMethod);
|
||||
bool isDesignated =
|
||||
MD->isDesignatedInitializerForTheInterface(&InitMethod);
|
||||
assert(isDesignated && InitMethod);
|
||||
(void)isDesignated;
|
||||
Diag(MD->getLocation(),
|
||||
|
|
|
@ -2447,14 +2447,33 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
|
|||
}
|
||||
}
|
||||
|
||||
if (SuperLoc.isValid() && getCurFunction()->ObjCIsDesignatedInit) {
|
||||
if (const ObjCObjectPointerType *
|
||||
OCIType = ReceiverType->getAsObjCInterfacePointerType()) {
|
||||
if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) {
|
||||
if (ID->isDesignatedInitializer(Sel))
|
||||
getCurFunction()->ObjCWarnForNoDesignatedInitChain = false;
|
||||
if (Method && Method->getMethodFamily() == OMF_init &&
|
||||
getCurFunction()->ObjCIsDesignatedInit &&
|
||||
(SuperLoc.isValid() || isSelfExpr(Receiver))) {
|
||||
bool isDesignatedInitChain = false;
|
||||
if (SuperLoc.isValid()) {
|
||||
if (const ObjCObjectPointerType *
|
||||
OCIType = ReceiverType->getAsObjCInterfacePointerType()) {
|
||||
if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) {
|
||||
if (ID->isDesignatedInitializer(Sel)) {
|
||||
isDesignatedInitChain = true;
|
||||
getCurFunction()->ObjCWarnForNoDesignatedInitChain = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isDesignatedInitChain) {
|
||||
const ObjCMethodDecl *InitMethod = 0;
|
||||
bool isDesignated =
|
||||
getCurMethodDecl()->isDesignatedInitializerForTheInterface(&InitMethod);
|
||||
assert(isDesignated && InitMethod);
|
||||
(void)isDesignated;
|
||||
Diag(SelLoc, SuperLoc.isValid() ?
|
||||
diag::warn_objc_designated_init_non_designated_init_call :
|
||||
diag::warn_objc_designated_init_non_super_designated_init_call);
|
||||
Diag(InitMethod->getLocation(),
|
||||
diag::note_objc_designated_init_marked_here);
|
||||
}
|
||||
}
|
||||
|
||||
// Check the message arguments.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s
|
||||
|
||||
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||
|
||||
|
@ -35,7 +35,7 @@ __attribute__((objc_root_class))
|
|||
@interface B1
|
||||
-(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
|
||||
-(id)initB2;
|
||||
-(id)initB3 NS_DESIGNATED_INITIALIZER;
|
||||
-(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
|
||||
@end
|
||||
|
||||
@implementation B1
|
||||
|
@ -47,8 +47,8 @@ __attribute__((objc_root_class))
|
|||
@interface S1 : B1
|
||||
-(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
|
||||
-(id)initS2 NS_DESIGNATED_INITIALIZER;
|
||||
-(id)initS3 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
|
||||
-(id)initS4 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
|
||||
-(id)initS3 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
|
||||
-(id)initS4 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
|
||||
-(id)initB1;
|
||||
@end
|
||||
|
||||
|
@ -60,10 +60,10 @@ __attribute__((objc_root_class))
|
|||
return [super initB1];
|
||||
}
|
||||
-(id)initS3 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
|
||||
return [super initB2];
|
||||
return [super initB2]; // expected-warning {{designated initializer invoked a non-designated initializer}}
|
||||
}
|
||||
-(id)initS4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
|
||||
return [self initB1];
|
||||
return [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
|
||||
}
|
||||
-(id)initB1 {
|
||||
return [self initS1];
|
||||
|
@ -92,12 +92,12 @@ __attribute__((objc_root_class))
|
|||
@end
|
||||
|
||||
@interface SS3 : S3
|
||||
-(id)initSS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
|
||||
-(id)initSS1 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
|
||||
@end
|
||||
|
||||
@implementation SS3
|
||||
-(id)initSS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
|
||||
return [super initB1];
|
||||
return [super initB1]; // expected-warning {{designated initializer invoked a non-designated initializer}}
|
||||
}
|
||||
@end
|
||||
|
||||
|
@ -116,6 +116,7 @@ __attribute__((objc_root_class))
|
|||
@end
|
||||
|
||||
@interface S5 : B1
|
||||
-(void)meth;
|
||||
@end
|
||||
|
||||
@implementation S5
|
||||
|
@ -123,6 +124,14 @@ __attribute__((objc_root_class))
|
|||
return 0;
|
||||
}
|
||||
-(id)initB3 {
|
||||
[self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
|
||||
S5 *s;
|
||||
[s initB1];
|
||||
[self meth];
|
||||
void (^blk)(void) = ^{
|
||||
[self initB1];
|
||||
};
|
||||
return [super initB3];
|
||||
}
|
||||
-(void)meth {}
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue