summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/DeclObjC.h15
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaObjCProperty.cpp63
-rw-r--r--clang/test/SemaObjC/arc.m13
4 files changed, 68 insertions, 25 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index a60d2c92f73..91126f10547 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -1414,7 +1414,10 @@ public:
OBJC_PR_atomic = 0x100,
OBJC_PR_weak = 0x200,
OBJC_PR_strong = 0x400,
- OBJC_PR_unsafe_unretained = 0x800
+ OBJC_PR_unsafe_unretained = 0x800,
+
+ /// \brief Number of bits fitting all the property attributes.
+ OBJC_PR_NumBits = 12
};
enum SetterKind { Assign, Retain, Copy };
@@ -1422,8 +1425,8 @@ public:
private:
SourceLocation AtLoc; // location of @property
TypeSourceInfo *DeclType;
- unsigned PropertyAttributes : 11;
- unsigned PropertyAttributesAsWritten : 11;
+ unsigned PropertyAttributes : OBJC_PR_NumBits;
+ unsigned PropertyAttributesAsWritten : OBJC_PR_NumBits;
// @required/@optional
unsigned PropertyImplementation : 2;
@@ -1466,6 +1469,12 @@ public:
PropertyAttributeKind getPropertyAttributesAsWritten() const {
return PropertyAttributeKind(PropertyAttributesAsWritten);
}
+
+ bool hasWrittenStorageAttribute() const {
+ return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy |
+ OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong |
+ OBJC_PR_weak);
+ }
void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
PropertyAttributesAsWritten = PRVal;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c1b09f7d6d7..97414f23d79 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2602,7 +2602,7 @@ def err_arc_mismatched_cast : Error<
def err_arc_objc_object_in_struct : Error<
"ARC forbids Objective-C objects in structs or unions">;
def err_arc_objc_property_default_assign_on_object : Error<
- "ARC forbids properties of Objective-C objects "
+ "ARC forbids synthesizing a property of an Objective-C object "
"with unspecified storage attribute">;
def err_arc_illegal_selector : Error<
"ARC forbids use of %0 in a @selector">;
diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp
index b47d62780b9..c830c3e1662 100644
--- a/clang/lib/Sema/SemaObjCProperty.cpp
+++ b/clang/lib/Sema/SemaObjCProperty.cpp
@@ -200,10 +200,6 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
CreatePropertyDecl(S, CCPrimary, AtLoc,
FD, GetterSel, SetterSel, isAssign, isReadWrite,
Attributes, T, MethodImplKind, DC);
- // Mark written attribute as having no attribute because
- // this is not a user-written property declaration in primary
- // class.
- PDecl->setPropertyAttributesAsWritten(ObjCPropertyDecl::OBJC_PR_noattr);
// A case of continuation class adding a new property in the class. This
// is not what it was meant for. However, gcc supports it and so should we.
@@ -336,6 +332,35 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
PDecl->setGetterName(GetterSel);
PDecl->setSetterName(SetterSel);
+ unsigned attributesAsWritten = 0;
+ if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readonly;
+ if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readwrite;
+ if (Attributes & ObjCDeclSpec::DQ_PR_getter)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_getter;
+ if (Attributes & ObjCDeclSpec::DQ_PR_setter)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_setter;
+ if (Attributes & ObjCDeclSpec::DQ_PR_assign)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_assign;
+ if (Attributes & ObjCDeclSpec::DQ_PR_retain)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_retain;
+ if (Attributes & ObjCDeclSpec::DQ_PR_strong)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_strong;
+ if (Attributes & ObjCDeclSpec::DQ_PR_weak)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_weak;
+ if (Attributes & ObjCDeclSpec::DQ_PR_copy)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_copy;
+ if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_unsafe_unretained;
+ if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_nonatomic;
+ if (Attributes & ObjCDeclSpec::DQ_PR_atomic)
+ attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_atomic;
+
+ PDecl->setPropertyAttributesAsWritten(
+ (ObjCPropertyDecl::PropertyAttributeKind)attributesAsWritten);
+
if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
@@ -371,11 +396,6 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
else if (Attributes & ObjCDeclSpec::DQ_PR_atomic)
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_atomic);
- // FIXME: Why do PropertyAttributesAsWritten get set from PropertyAttributes,
- // shouldn't PropertyAttributesAsWritten get set *only* through the attributes
- // of the ObjCDeclSpec ?
- PDecl->setPropertyAttributesAsWritten(PDecl->getPropertyAttributes());
-
// 'unsafe_unretained' is alias for 'assign'.
if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
@@ -565,6 +585,13 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
ObjCIvarDecl *Ivar = 0;
// Check that we have a valid, previously declared ivar for @synthesize
if (Synthesize) {
+ if (getLangOptions().ObjCAutoRefCount &&
+ !property->hasWrittenStorageAttribute() &&
+ property->getType()->isObjCRetainableType()) {
+ Diag(PropertyLoc, diag::err_arc_objc_property_default_assign_on_object);
+ Diag(property->getLocation(), diag::note_property_declare);
+ }
+
// @synthesize
if (!PropertyIvar)
PropertyIvar = PropertyId;
@@ -1672,17 +1699,13 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
ObjCDeclSpec::DQ_PR_weak)) &&
!(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
PropertyTy->isObjCObjectPointerType()) {
- if (getLangOptions().ObjCAutoRefCount)
- Diag(Loc, diag::err_arc_objc_property_default_assign_on_object);
- else {
- // Skip this warning in gc-only mode.
- if (getLangOptions().getGCMode() != LangOptions::GCOnly)
- Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
-
- // If non-gc code warn that this is likely inappropriate.
- if (getLangOptions().getGCMode() == LangOptions::NonGC)
- Diag(Loc, diag::warn_objc_property_default_assign_on_object);
- }
+ // Skip this warning in gc-only mode.
+ if (getLangOptions().getGCMode() != LangOptions::GCOnly)
+ Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
+
+ // If non-gc code warn that this is likely inappropriate.
+ if (getLangOptions().getGCMode() == LangOptions::NonGC)
+ Diag(Loc, diag::warn_objc_property_default_assign_on_object);
// FIXME: Implement warning dependent on NSCopying being
// implemented. See also:
diff --git a/clang/test/SemaObjC/arc.m b/clang/test/SemaObjC/arc.m
index 10df61e6009..61dc0e05254 100644
--- a/clang/test/SemaObjC/arc.m
+++ b/clang/test/SemaObjC/arc.m
@@ -484,10 +484,21 @@ void test26(id y) {
// rdar://9525555
@interface Test27
-@property id x; // expected-error {{ARC forbids properties of Objective-C objects with unspecified storage attribute}}
+@property id x; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}} \
+ // expected-warning {{default property attribute 'assign' not appropriate for non-gc object}} \
+ // expected-note {{declared here}}
+@property (readonly) id ro; // expected-note {{declared here}}
+@property (readonly) id custom_ro;
@property int y;
@end
+@implementation Test27
+@synthesize x; // expected-error {{ARC forbids synthesizing a property of an Objective-C object with unspecified storage attribute}}
+@synthesize ro; // expected-error {{ARC forbids synthesizing a property of an Objective-C object with unspecified storage attribute}}
+@synthesize y;
+-(id)custom_ro { return 0; }
+@end
+
// rdar://9569264
@interface Test28
@property (nonatomic, assign) __strong id a; // expected-error {{unsafe_unretained property 'a' may not also be declared __strong}}
OpenPOWER on IntegriCloud