Skip to content

Commit 3fefeaf

Browse files
authored
[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
1 parent 999d4f8 commit 3fefeaf

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

clang/lib/Sema/SemaType.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,11 @@ static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type,
10181018
return type;
10191019
}
10201020

1021+
// Types that have __attribute__((NSObject)) are permitted.
1022+
if (typeArg->isObjCNSObjectType()) {
1023+
continue;
1024+
}
1025+
10211026
// Dependent types will be checked at instantiation time.
10221027
if (typeArg->isDependentType()) {
10231028
continue;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 -verify -Wno-objc-root-class -fsyntax-only %s
2+
3+
@interface NSArray<__covariant ObjectType>
4+
- (void)containsObject:(ObjectType)anObject; // expected-note {{passing argument to parameter 'anObject' here}}
5+
- (void)description;
6+
@end
7+
8+
typedef __attribute__((NSObject)) struct Foo *FooRef;
9+
typedef struct Bar *BarRef;
10+
11+
void good() {
12+
FooRef object;
13+
NSArray<FooRef> *array;
14+
[array containsObject:object];
15+
[object description];
16+
}
17+
18+
void bad() {
19+
BarRef object;
20+
NSArray<BarRef> *array; // expected-error {{type argument 'BarRef' (aka 'struct Bar *') is neither an Objective-C object nor a block type}}
21+
[array containsObject:object]; // expected-warning {{incompatible pointer types sending 'BarRef' (aka 'struct Bar *') to parameter of type 'id'}}
22+
[object description]; // expected-warning {{receiver type 'BarRef' (aka 'struct Bar *') is not 'id' or interface pointer, consider casting it to 'id'}}
23+
}

0 commit comments

Comments
 (0)