Objective-C ARC. Do not warn about properties with both

IBOutlet and weak attributes when accessed being
unpredictably set to nil because usage of such properties
are always single threaded and its ivar cannot be set
to nil asynchronously. // rdar://15885642 

llvm-svn: 211132
This commit is contained in:
Fariborz Jahanian 2014-06-17 23:35:13 +00:00
parent f6e456dd63
commit 9277ff426d
4 changed files with 44 additions and 12 deletions

View File

@ -158,8 +158,14 @@ void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
// Has this weak object been seen before?
FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E))
Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
if (isa<OpaqueValueExpr>(RefExpr->getBase()))
Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
else {
markSafeWeakUse(RefExpr->getBase());
return;
}
}
else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))

View File

@ -2640,7 +2640,14 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
}
if (getLangOpts().ObjCAutoRefCount) {
DiagnoseARCUseOfWeakReceiver(*this, Receiver);
// Do not warn about IBOutlet weak property receivers being set to null
// as this cannot asynchronously happen.
bool WarnWeakReceiver = true;
if (isImplicit && Method)
if (const ObjCPropertyDecl *PropertyDecl = Method->findPropertyDecl())
WarnWeakReceiver = !PropertyDecl->hasAttr<IBOutletAttr>();
if (WarnWeakReceiver)
DiagnoseARCUseOfWeakReceiver(*this, Receiver);
// In ARC, annotate delegate init calls.
if (Result->getMethodFamily() == OMF_init &&

View File

@ -542,7 +542,7 @@ bool ObjCPropertyOpBuilder::isWeakProperty() const {
if (RefExpr->isExplicitProperty()) {
const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty();
if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
return true;
return !Prop->hasAttr<IBOutletAttr>();
T = Prop->getType();
} else if (Getter) {
@ -816,13 +816,20 @@ ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
// As a special case, if the method returns 'id', try to get
// a better type from the property.
if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
result.get()->getType()->isObjCIdType()) {
if (RefExpr->isExplicitProperty() && result.get()->isRValue()) {
QualType propType = RefExpr->getExplicitProperty()->getType();
if (const ObjCObjectPointerType *ptr
= propType->getAs<ObjCObjectPointerType>()) {
if (!ptr->isObjCIdType())
result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
if (result.get()->getType()->isObjCIdType()) {
if (const ObjCObjectPointerType *ptr
= propType->getAs<ObjCObjectPointerType>()) {
if (!ptr->isObjCIdType())
result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
}
}
if (S.getLangOpts().ObjCAutoRefCount) {
Qualifiers::ObjCLifetime LT = propType.getObjCLifetime();
if (LT == Qualifiers::OCL_Weak)
if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation()))
S.getCurFunction()->markSafeWeakUse(RefExpr);
}
}

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s
// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -Wno-objc-root-class -verify %s
// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -Wno-objc-root-class -Wreceiver-is-weak -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s
// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-arc -Wno-objc-root-class -Wreceiver-is-weak -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s
// rdar://11448209
#define READONLY readonly
@ -40,3 +40,15 @@
@implementation RKTFHView
@synthesize synthReadOnlyReadWrite=_synthReadOnlyReadWrite;
@end
// rdar://15885642
@interface WeakOutlet
@property IBOutlet __weak WeakOutlet* WeakProp;
@end
WeakOutlet* func() {
__weak WeakOutlet* pwi;
pwi.WeakProp = (WeakOutlet*)0;
pwi.WeakProp = pwi.WeakProp;
return pwi.WeakProp;
}