summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaObjCProperty.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaObjCProperty.cpp')
-rw-r--r--clang/lib/Sema/SemaObjCProperty.cpp82
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
OpenPOWER on IntegriCloud