objc: warn if NSObject attribute appears other than in a typedef.
// rdar://10453342


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145358 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 38a7c19..8a23134 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -181,6 +181,7 @@
 def Uninitialized  : DiagGroup<"uninitialized">;
 def UninitializedMaybe : DiagGroup<"conditional-uninitialized">;
 def UnknownPragmas : DiagGroup<"unknown-pragmas">;
+def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
 def UnknownAttributes : DiagGroup<"attributes">;
 def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args",
                                         [CXX98CompatUnnamedTypeTemplateArgs]>;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index f566e10..8bf377f 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1348,10 +1348,9 @@
 // Objective-C++
 def err_objc_decls_may_only_appear_in_global_scope : Error<
   "Objective-C declarations may only appear in global scope">;
+// Attributes
 def err_nsobject_attribute : Error<
   "__attribute ((NSObject)) is for pointer types only">;
-
-// Attributes
 def err_attribute_can_be_applied_only_to_symbol_declaration : Error<
   "%0 attribute can be applied only to symbol declaration">;
 def err_attributes_are_not_compatible : Error<
@@ -1463,6 +1462,9 @@
   "__weak attribute cannot be specified on a field declaration">;
 def warn_gc_attribute_weak_on_local : Warning<
   "Objective-C GC does not allow weak variables on the stack">;
+def warn_nsobject_attribute : Warning<
+  "__attribute ((NSObject)) may be put on a typedef only, "
+  "attribute is ignored">, InGroup<NSobjectAttribute>;
 def warn_attribute_weak_on_local : Warning<
   "__weak attribute cannot be specified on an automatic variable">;
 def warn_weak_identifier_undeclared : Warning<
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 74d22e7..e60cd63 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1746,6 +1746,10 @@
       return;
     }
   }
+  else {
+    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
+    return;
+  }
   D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
 }
 
diff --git a/test/SemaObjC/nsobject-attribute.m b/test/SemaObjC/nsobject-attribute.m
index 13a4929..99f332d 100644
--- a/test/SemaObjC/nsobject-attribute.m
+++ b/test/SemaObjC/nsobject-attribute.m
@@ -15,8 +15,8 @@
 
 @property(copy) CGColorRef x;
 // rdar: // 7809460
-typedef struct CGColor *CGColorRefNoNSObject;
-@property (nonatomic, retain) __attribute__((NSObject)) CGColorRefNoNSObject color;
+typedef struct CGColor * __attribute__((NSObject)) CGColorRefNoNSObject;
+@property (nonatomic, retain) CGColorRefNoNSObject color;
 @end
 
 void setProperty(id self, id value)  {
@@ -40,3 +40,15 @@
     return 0;
 }
 
+// rdar://10453342
+@interface I
+{
+   __attribute__((NSObject)) void * color; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}}
+}
+@property (nonatomic, retain) __attribute__((NSObject)) void * color; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}} \
+                                // expected-error {{property with 'retain (or strong)' attribute must be of object type}}
+@end
+void test_10453342() {
+    char* __attribute__((NSObject)) string2 = 0; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}}
+}
+