aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordmaclach <dmaclach@gmail.com>2024-03-21 11:22:35 -0700
committerGitHub <noreply@github.com>2024-03-21 14:22:35 -0400
commit3fefeafa49299ef924414bfa1b678e0f656b3618 (patch)
tree81553d760856f2eba501e687d696ff2357f42953
parent999d4f840777bf8de26d45947192aa0728edc0fb (diff)
downloadllvm-3fefeafa49299ef924414bfa1b678e0f656b3618.zip
llvm-3fefeafa49299ef924414bfa1b678e0f656b3618.tar.gz
llvm-3fefeafa49299ef924414bfa1b678e0f656b3618.tar.bz2
[OBJC] Allow __attribute__((NSObject)) types be used as lightweight generic specifiers (#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
-rw-r--r--clang/lib/Sema/SemaType.cpp5
-rw-r--r--clang/test/SemaObjC/attr-objc-NSObject.m23
2 files changed, 28 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 7b14323..d7521a5 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 0000000..76a01dc
--- /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'}}
+}