https://github.com/dmaclach created 
https://github.com/llvm/llvm-project/pull/84593

As per 
https://clang.llvm.org/docs/AutomaticReferenceCounting.html#retainable-object-pointers,
 types with `__attribute__((NSObject))` are retainable, and thus should be 
eligible to be used as lightweight generic specifiers.

Fix for #84592 84592

>From fe3ac2146f6fb969975848a9137b38eb2eb1d918 Mon Sep 17 00:00:00 2001
From: Dave MacLachlan <dmacl...@gmail.com>
Date: Fri, 8 Mar 2024 15:14:56 -0800
Subject: [PATCH] Allow __attribute__((NSObject)) types be used as lightweight
 generic specifiers

As per 
https://clang.llvm.org/docs/AutomaticReferenceCounting.html#retainable-object-pointers,
types with `__attribute__((NSObject))` are retainable, and thus should be 
eligible to be
used as lightweight generic specifiers.
---
 clang/lib/Sema/SemaType.cpp              |  5 +++++
 clang/test/SemaObjC/attr-objc-NSObject.m | 23 +++++++++++++++++++++++
 2 files changed, 28 insertions(+)
 create mode 100644 clang/test/SemaObjC/attr-objc-NSObject.m

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 3148299f6467af..87173a52af8143 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1018,6 +1018,11 @@ static QualType applyObjCTypeArgs(Sema &S, 
SourceLocation loc, QualType type,
       return type;
     }
 
+    // Types that have __attribute__((NSObject)) are permitted.
+    if (typeArg->isObjCNSObjectType()) {
+      continue;
+    }
+
     // Dependent types will be checked at instantiation time.
     if (typeArg->isDependentType()) {
       continue;
diff --git a/clang/test/SemaObjC/attr-objc-NSObject.m 
b/clang/test/SemaObjC/attr-objc-NSObject.m
new file mode 100644
index 00000000000000..76a01dcef01637
--- /dev/null
+++ b/clang/test/SemaObjC/attr-objc-NSObject.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -verify -Wno-objc-root-class -fsyntax-only %s
+
+@interface NSArray<__covariant ObjectType>
+- (void)containsObject:(ObjectType)anObject; // expected-note {{passing 
argument to parameter 'anObject' here}}
+- (void)description;
+@end
+
+typedef __attribute__((NSObject)) struct Foo *FooRef;
+typedef struct Bar *BarRef;
+
+void good() {
+  FooRef object;
+  NSArray<FooRef> *array;
+  [array containsObject:object];
+  [object description];
+}
+
+void bad() {
+  BarRef object;
+  NSArray<BarRef> *array; // expected-error {{type argument 'BarRef' (aka 
'struct Bar *') is neither an Objective-C object nor a block type}}
+  [array containsObject:object]; // expected-warning {{incompatible pointer 
types sending 'BarRef' (aka 'struct Bar *') to parameter of type 'id'}}
+  [object description]; // expected-warning {{receiver type 'BarRef' (aka 
'struct Bar *') is not 'id' or interface pointer, consider casting it to 'id'}}
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to