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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211132
91177308-0d34-0410-b5e6-
96231b3b80d8
// 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))
}
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 &&
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) {
// 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);
}
}
-// 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
@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;
+}