diff options
Diffstat (limited to 'clang/lib/Sema/SemaObjCProperty.cpp')
-rw-r--r-- | clang/lib/Sema/SemaObjCProperty.cpp | 82 |
1 files changed, 44 insertions, 38 deletions
diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index 374e5ccd918..04465958c1c 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -663,8 +663,10 @@ static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc, // We're fine if they match. if (propertyLifetime == ivarLifetime) return; - // These aren't valid lifetimes for object ivars; don't diagnose twice. - if (ivarLifetime == Qualifiers::OCL_None || + // None isn't a valid lifetime for an object ivar in ARC, and + // __autoreleasing is never valid; don't diagnose twice. + if ((ivarLifetime == Qualifiers::OCL_None && + S.getLangOpts().ObjCAutoRefCount) || ivarLifetime == Qualifiers::OCL_Autoreleasing) return; @@ -953,18 +955,46 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, ObjCPropertyDecl::PropertyAttributeKind kind = property->getPropertyAttributes(); - // Add GC __weak to the ivar type if the property is weak. - if ((kind & ObjCPropertyDecl::OBJC_PR_weak) && - getLangOpts().getGC() != LangOptions::NonGC) { - assert(!getLangOpts().ObjCAutoRefCount); - if (PropertyIvarType.isObjCGCStrong()) { - Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type); - Diag(property->getLocation(), diag::note_property_declare); + bool isARCWeak = false; + if (kind & ObjCPropertyDecl::OBJC_PR_weak) { + // Add GC __weak to the ivar type if the property is weak. + if (getLangOpts().getGC() != LangOptions::NonGC) { + assert(!getLangOpts().ObjCAutoRefCount); + if (PropertyIvarType.isObjCGCStrong()) { + Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type); + Diag(property->getLocation(), diag::note_property_declare); + } else { + PropertyIvarType = + Context.getObjCGCQualType(PropertyIvarType, Qualifiers::Weak); + } + + // Otherwise, check whether ARC __weak is enabled and works with + // the property type. } else { - PropertyIvarType = - Context.getObjCGCQualType(PropertyIvarType, Qualifiers::Weak); + if (!getLangOpts().ObjCWeak) { + if (getLangOpts().ObjCWeakRuntime) { + Diag(PropertyDiagLoc, diag::err_arc_weak_disabled); + } else { + Diag(PropertyDiagLoc, diag::err_arc_weak_no_runtime); + } + Diag(property->getLocation(), diag::note_property_declare); + } else { + isARCWeak = true; + if (const ObjCObjectPointerType *ObjT = + PropertyIvarType->getAs<ObjCObjectPointerType>()) { + const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl(); + if (ObjI && ObjI->isArcWeakrefUnavailable()) { + Diag(property->getLocation(), + diag::err_arc_weak_unavailable_property) + << PropertyIvarType; + Diag(ClassImpDecl->getLocation(), diag::note_implemented_by_class) + << ClassImpDecl->getName(); + } + } + } } } + if (AtLoc.isInvalid()) { // Check when default synthesizing a property that there is // an ivar matching property name and issue warning; since this @@ -987,7 +1017,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, if (!Ivar) { // In ARC, give the ivar a lifetime qualifier based on the // property attributes. - if (getLangOpts().ObjCAutoRefCount && + if ((getLangOpts().ObjCAutoRefCount || isARCWeak) && !PropertyIvarType.getObjCLifetime() && PropertyIvarType->isObjCRetainableType()) { @@ -1002,24 +1032,6 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, Qualifiers::ObjCLifetime lifetime = getImpliedARCOwnership(kind, PropertyIvarType); assert(lifetime && "no lifetime for property?"); - if (lifetime == Qualifiers::OCL_Weak) { - bool err = false; - if (const ObjCObjectPointerType *ObjT = - PropertyIvarType->getAs<ObjCObjectPointerType>()) { - const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl(); - if (ObjI && ObjI->isArcWeakrefUnavailable()) { - Diag(property->getLocation(), - diag::err_arc_weak_unavailable_property) << PropertyIvarType; - Diag(ClassImpDecl->getLocation(), diag::note_implemented_by_class) - << ClassImpDecl->getName(); - err = true; - } - } - if (!err && !getLangOpts().ObjCARCWeak) { - Diag(PropertyDiagLoc, diag::err_arc_weak_no_runtime); - Diag(property->getLocation(), diag::note_property_declare); - } - } Qualifiers qs; qs.addObjCLifetime(lifetime); @@ -1027,13 +1039,6 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, } } - if (kind & ObjCPropertyDecl::OBJC_PR_weak && - !getLangOpts().ObjCAutoRefCount && - getLangOpts().getGC() == LangOptions::NonGC) { - Diag(PropertyDiagLoc, diag::error_synthesize_weak_non_arc_or_gc); - Diag(property->getLocation(), diag::note_property_declare); - } - Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyIvarLoc,PropertyIvarLoc, PropertyIvar, PropertyIvarType, /*Dinfo=*/nullptr, @@ -1121,7 +1126,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, // Fall thru - see previous comment } } - if (getLangOpts().ObjCAutoRefCount) + if (getLangOpts().ObjCAutoRefCount || isARCWeak || + Ivar->getType().getObjCLifetime()) checkARCPropertyImpl(*this, PropertyLoc, property, Ivar); } else if (PropertyIvar) // @dynamic |