OBJC_PR_retain = 0x10,
OBJC_PR_copy = 0x20,
OBJC_PR_nonatomic = 0x40,
- OBJC_PR_setter = 0x80
+ OBJC_PR_setter = 0x80,
+ OBJC_PR_atomic = 0x100
};
enum SetterKind { Assign, Retain, Copy };
private:
SourceLocation AtLoc; // location of @property
TypeSourceInfo *DeclType;
- unsigned PropertyAttributes : 8;
- unsigned PropertyAttributesAsWritten : 8;
+ unsigned PropertyAttributes : 9;
+ unsigned PropertyAttributesAsWritten : 9;
// @required/@optional
unsigned PropertyImplementation : 2;
def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
def Reorder : DiagGroup<"reorder">;
def UndeclaredSelector : DiagGroup<"undeclared-selector">;
+def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">;
def Selector : DiagGroup<"selector">;
def NonfragileAbi2 : DiagGroup<"nonfragile-abi2">;
def Protocol : DiagGroup<"protocol">;
InGroup<ReadOnlySetterAttrs>, DefaultIgnore;
def warn_undeclared_selector : Warning<
"undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore;
+def warn_implicit_atomic_property : Warning<
+ "property is assumed atomic by default">, InGroup<ImplicitAtomic>, DefaultIgnore;
+def warn_auto_implicit_atomic_property : Warning<
+ "property is assumed atomic when auto-synthesizing the property">,
+ InGroup<ImplicitAtomic>, DefaultIgnore;
def warn_unimplemented_selector: Warning<
"unimplemented selector %0">, InGroup<Selector>, DefaultIgnore;
def warn_unimplemented_protocol_method : Warning<
DQ_PR_retain = 0x10,
DQ_PR_copy = 0x20,
DQ_PR_nonatomic = 0x40,
- DQ_PR_setter = 0x80
+ DQ_PR_setter = 0x80,
+ DQ_PR_atomic = 0x100
};
ObjCDeclQualifier objcDeclQualifier : 6;
// NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
- unsigned PropertyAttributes : 8;
+ unsigned PropertyAttributes : 9;
IdentifierInfo *GetterName; // getter name of NULL if no getter
IdentifierInfo *SetterName; // setter name of NULL if no setter
};
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy);
else if (II->isStr("nonatomic"))
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic);
+ else if (II->isStr("atomic"))
+ DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_atomic);
else if (II->isStr("getter") || II->isStr("setter")) {
bool IsSetter = II->getNameStart()[0] == 's';
if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
+ else if (Attributes & ObjCDeclSpec::DQ_PR_atomic)
+ PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_atomic);
PDecl->setPropertyAttributesAsWritten(PDecl->getPropertyAttributes());
Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
return 0;
}
+ unsigned PIkind = property->getPropertyAttributesAsWritten();
+ if ((PIkind & (ObjCPropertyDecl::OBJC_PR_atomic |
+ ObjCPropertyDecl::OBJC_PR_nonatomic) ) == 0) {
+ if (AtLoc.isValid())
+ Diag(AtLoc, diag::warn_implicit_atomic_property);
+ else
+ Diag(IC->getLocation(), diag::warn_auto_implicit_atomic_property);
+ Diag(property->getLocation(), diag::note_property_declare);
+ }
+
if (const ObjCCategoryDecl *CD =
dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
if (!CD->IsClassExtension()) {
--- /dev/null
+// RUN: %clang_cc1 -fsyntax-only -Wimplicit-atomic-properties -fobjc-nonfragile-abi2 -verify %s
+// rdar://8774580
+
+@interface Super
+@property (nonatomic, readwrite) int P; // OK
+@property (atomic, readwrite) int P1; // OK
+@property (readwrite) int P2; // expected-note {{property declared here}}
+@property int P3; // expected-note {{property declared here}}
+@end
+
+@implementation Super // expected-warning {{property is assumed atomic when auto-synthesizing the property [-Wimplicit-atomic-properties]}}
+@synthesize P,P1,P2; // expected-warning {{property is assumed atomic by default [-Wimplicit-atomic-properties]}}
+@end