Objective-C. Allow [super initialize] in an +initialize

implementation but not anywhere else.
rdar://16628028

llvm-svn: 216408
This commit is contained in:
Fariborz Jahanian 2014-08-25 21:27:38 +00:00
parent 74bd6bc9f9
commit 4229228389
4 changed files with 30 additions and 10 deletions

View File

@ -268,6 +268,7 @@ def ObjCRootClass : DiagGroup<"objc-root-class">;
def ObjCPointerIntrospectPerformSelector : DiagGroup<"deprecated-objc-pointer-introspection-performSelector">;
def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>;
def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
def Packed : DiagGroup<"packed">;
def Padded : DiagGroup<"padded">;
def PointerArith : DiagGroup<"pointer-arith">;

View File

@ -6879,7 +6879,11 @@ def warn_ivar_use_hidden : Warning<
InGroup<DiagGroup<"shadow-ivar">>;
def warn_direct_initialize_call : Warning<
"explicit call to +initialize results in duplicate call to +initialize">,
InGroup<DiagGroup<"explicit-initialize-call">>;
InGroup<ExplicitInitializeCall>;
def warn_direct_super_initialize_call : Warning<
"explicit call to [super initialize] should only be in implementation "
"of +initialize">,
InGroup<ExplicitInitializeCall>;
def error_ivar_use_in_class_method : Error<
"instance variable %0 accessed in class method">;
def error_implicit_ivar_access : Error<

View File

@ -2237,8 +2237,8 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
return ExprError();
// Warn about explicit call of +initialize on its own class. But not on 'super'.
if (Method && Method->getMethodFamily() == OMF_initialize &&
!SuperLoc.isValid()) {
if (Method && Method->getMethodFamily() == OMF_initialize) {
if (!SuperLoc.isValid()) {
const ObjCInterfaceDecl *ID =
dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext());
if (ID == Class) {
@ -2247,6 +2247,17 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
<< Method->getDeclName();
}
}
else if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
// [super initialize] is allowed only within an +initialize implementation
if (CurMeth->getMethodFamily() != OMF_initialize) {
Diag(Loc, diag::warn_direct_super_initialize_call);
Diag(Method->getLocation(), diag::note_method_declared_at)
<< Method->getDeclName();
Diag(CurMeth->getLocation(), diag::note_method_declared_at)
<< CurMeth->getDeclName();
}
}
}
// Construct the appropriate ObjCMessageExpr.
ObjCMessageExpr *Result;

View File

@ -2,11 +2,12 @@
// rdar://16628028
@interface NSObject
+ (void)initialize; // expected-note {{method 'initialize' declared here}}
+ (void)initialize; // expected-note 2 {{method 'initialize' declared here}}
@end
@interface I : NSObject
+ (void)initialize; // expected-note {{method 'initialize' declared here}}
+ (void)SomeRandomMethod;
@end
@implementation I
@ -17,5 +18,8 @@
+ (void)initialize {
[super initialize];
}
+ (void)SomeRandomMethod { // expected-note {{method 'SomeRandomMethod' declared here}}
[super initialize]; // expected-warning {{explicit call to [super initialize] should only be in implementation of +initialize}}
}
@end