Objective-C. Consider blocks for designated initializer

warnings (warning or lack there of) as well since
blocks are another pattern for envoking other
designated initializers. // rdar://16323233

llvm-svn: 204081
This commit is contained in:
Fariborz Jahanian 2014-03-17 21:41:40 +00:00
parent 2fe531cb07
commit ba419ce21d
3 changed files with 48 additions and 9 deletions

View File

@ -1013,6 +1013,18 @@ public:
return FunctionScopes.back(); return FunctionScopes.back();
} }
sema::FunctionScopeInfo *getEnclosingFunction() const {
if (FunctionScopes.empty())
return 0;
for (int e = FunctionScopes.size()-1; e >= 0; --e) {
if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
continue;
return FunctionScopes[e];
}
return 0;
}
template <typename ExprT> template <typename ExprT>
void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) { void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) {
if (!isUnevaluatedContext()) if (!isUnevaluatedContext())

View File

@ -2499,8 +2499,12 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
} }
} }
if (Method && Method->getMethodFamily() == OMF_init && FunctionScopeInfo *DIFunctionScopeInfo =
getCurFunction()->ObjCIsDesignatedInit && (Method && Method->getMethodFamily() == OMF_init)
? getEnclosingFunction() : 0;
if (DIFunctionScopeInfo &&
DIFunctionScopeInfo->ObjCIsDesignatedInit &&
(SuperLoc.isValid() || isSelfExpr(Receiver))) { (SuperLoc.isValid() || isSelfExpr(Receiver))) {
bool isDesignatedInitChain = false; bool isDesignatedInitChain = false;
if (SuperLoc.isValid()) { if (SuperLoc.isValid()) {
@ -2512,7 +2516,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
if (!ID->declaresOrInheritsDesignatedInitializers() || if (!ID->declaresOrInheritsDesignatedInitializers() ||
ID->isDesignatedInitializer(Sel)) { ID->isDesignatedInitializer(Sel)) {
isDesignatedInitChain = true; isDesignatedInitChain = true;
getCurFunction()->ObjCWarnForNoDesignatedInitChain = false; DIFunctionScopeInfo->ObjCWarnForNoDesignatedInitChain = false;
} }
} }
} }
@ -2531,13 +2535,13 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
} }
} }
if (Method && Method->getMethodFamily() == OMF_init && if (DIFunctionScopeInfo &&
getCurFunction()->ObjCIsSecondaryInit && DIFunctionScopeInfo->ObjCIsSecondaryInit &&
(SuperLoc.isValid() || isSelfExpr(Receiver))) { (SuperLoc.isValid() || isSelfExpr(Receiver))) {
if (SuperLoc.isValid()) { if (SuperLoc.isValid()) {
Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call); Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);
} else { } else {
getCurFunction()->ObjCWarnForNoInitDelegation = false; DIFunctionScopeInfo->ObjCWarnForNoInitDelegation = false;
} }
} }

View File

@ -36,7 +36,7 @@ __attribute__((objc_root_class))
@interface B1 @interface B1
-(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 6 {{method marked as designated initializer of the class here}} -(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 6 {{method marked as designated initializer of the class here}}
-(id)initB2; -(id)initB2;
-(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 3 {{method marked as designated initializer of the class here}} -(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
@end @end
@implementation B1 @implementation B1
@ -131,7 +131,7 @@ __attribute__((objc_root_class))
[s initB1]; [s initB1];
[self meth]; [self meth];
void (^blk)(void) = ^{ void (^blk)(void) = ^{
[self initB1]; [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
}; };
return [super initB3]; return [super initB3];
} }
@ -168,7 +168,7 @@ __attribute__((objc_root_class))
-(id)initS5 { -(id)initS5 {
[super initB1]; // expected-warning {{secondary initializer should not invoke an initializer on 'super'}} [super initB1]; // expected-warning {{secondary initializer should not invoke an initializer on 'super'}}
void (^blk)(void) = ^{ void (^blk)(void) = ^{
[super initB1]; [super initB1]; // expected-warning {{secondary initializer should not invoke an initializer on 'super'}}
}; };
return [self initS1]; return [self initS1];
} }
@ -262,3 +262,26 @@ __attribute__((objc_root_class))
return ((void*)0); return ((void*)0);
} }
@end @end
// rdar://16323233
__attribute__((objc_root_class))
@interface B4
-(id)initB4 NS_DESIGNATED_INITIALIZER;
@end
@interface rdar16323233 : B4
-(id)initS4 NS_DESIGNATED_INITIALIZER;
@end
@implementation rdar16323233
-(id)initS4 {
static id sSharedObject = (void*)0;
(void)^(void) {
sSharedObject = [super initB4];
};
return 0;
}
-(id)initB4 {
return [self initS4];
}
@end