Objective-C diagnostics: isObjCNSObjectType should check through AttributedType.
authorManman Ren <manman.ren@gmail.com>
Mon, 15 Aug 2016 21:05:00 +0000 (21:05 +0000)
committerManman Ren <manman.ren@gmail.com>
Mon, 15 Aug 2016 21:05:00 +0000 (21:05 +0000)
For the following example:
typedef __attribute__((NSObject)) CGColorRef ColorAttrRef;
@property (strong, nullable) ColorAttrRef color;
The property type should be ObjC NSObject type and the compiler should not emit
error: property with 'retain (or strong)' attribute must be of object type

rdar://problem/27747154

llvm-svn: 278742

clang/lib/AST/Type.cpp
clang/test/SemaObjC/nsobject-attribute.m

index 68e1fc0..4c1d4ec 100644 (file)
@@ -3686,10 +3686,18 @@ bool Type::isObjCARCImplicitlyUnretainedType() const {
 }
 
 bool Type::isObjCNSObjectType() const {
-  if (const TypedefType *typedefType = dyn_cast<TypedefType>(this))
-    return typedefType->getDecl()->hasAttr<ObjCNSObjectAttr>();
-  return false;
+  const Type *cur = this;
+  while (true) {
+    if (const TypedefType *typedefType = dyn_cast<TypedefType>(cur))
+      return typedefType->getDecl()->hasAttr<ObjCNSObjectAttr>();
+
+    // Single-step desugar until we run out of sugar.
+    QualType next = cur->getLocallyUnqualifiedSingleStepDesugaredType();
+    if (next.getTypePtr() == cur) return false;
+    cur = next.getTypePtr();
+  }
 }
+
 bool Type::isObjCIndependentClassType() const {
   if (const TypedefType *typedefType = dyn_cast<TypedefType>(this))
     return typedefType->getDecl()->hasAttr<ObjCIndependentClassAttr>();
index 6bd2d5d..7c8d75d 100644 (file)
@@ -21,6 +21,8 @@ typedef struct CGColor * __attribute__((NSObject)) CGColorRefNoNSObject; // no-w
 @property (nonatomic, retain) CGColorRefNoNSObject color;
 // rdar://problem/12197822
 @property (strong) __attribute__((NSObject)) CFTypeRef myObj; // no-warning
+//rdar://problem/27747154
+@property (strong, nullable) CGColorRefNoNSObject color2; // no-warning
 @end
 
 void setProperty(id self, id value)  {