diff options
-rw-r--r-- | include/clang/AST/DeclObjC.h | 7 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticGroups.td | 1 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 5 | ||||
-rw-r--r-- | include/clang/Sema/DeclSpec.h | 5 | ||||
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaObjCProperty.cpp | 12 | ||||
-rw-r--r-- | test/SemaObjC/warn-implicit-atomic-property.m | 13 |
7 files changed, 40 insertions, 5 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 8282e0aab5..2112d537c3 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -1367,7 +1367,8 @@ public: 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 }; @@ -1375,8 +1376,8 @@ public: 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; diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 92b29b2c98..141770a942 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -148,6 +148,7 @@ def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">; 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">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 40029855dd..cfa2ab6d21 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -436,6 +436,11 @@ def warn_objc_property_attr_mutually_exclusive : Warning< 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< diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index aab63c0863..484204b1b2 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -539,7 +539,8 @@ public: DQ_PR_retain = 0x10, DQ_PR_copy = 0x20, DQ_PR_nonatomic = 0x40, - DQ_PR_setter = 0x80 + DQ_PR_setter = 0x80, + DQ_PR_atomic = 0x100 }; @@ -573,7 +574,7 @@ private: 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 }; diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 4324e0824d..f1c48a6a3a 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -509,6 +509,8 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl, 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'; diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index a1664d558e..65a447e2a1 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -299,6 +299,8 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *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()); @@ -349,6 +351,16 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, 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()) { diff --git a/test/SemaObjC/warn-implicit-atomic-property.m b/test/SemaObjC/warn-implicit-atomic-property.m new file mode 100644 index 0000000000..b0a6597989 --- /dev/null +++ b/test/SemaObjC/warn-implicit-atomic-property.m @@ -0,0 +1,13 @@ +// 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 |