llvm-project/clang/test/SemaObjC/unsafe-perform-selector.m
Mehdi Amini e0ac46e69d Revert "Remove rdar links; NFC"
This reverts commit d618f1c3b12effd0c2bdb7d02108d3551f389d3d.
This commit wasn't reviewed ahead of time and significant concerns were
raised immediately after it landed. According to our developer policy
this warrants immediate revert of the commit.

https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy

Differential Revision: https://reviews.llvm.org/D155509
2023-07-17 18:08:04 -07:00

128 lines
5.5 KiB
Objective-C

// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s
// rdar://12056271
@class Thread;
__attribute__((objc_root_class))
@interface NSObject
- (id)performSelector:(SEL)sel;
- (void)performSelectorInBackground:(SEL)sel withObject:(id)arg;
- (void)performSelectorOnMainThread:(SEL)sel;
- (void)performSelectorOnMainThread:(SEL)aSelector
onThread:(Thread *)thread
withObject:(id)arg
waitUntilDone:(int)wait
modes:(id *)array;
@end
typedef struct { int x; int y; int width; int height; } Rectangle;
struct Struct { Rectangle r; };
typedef union { int x; float f; } Union;
@interface Base : NSObject
- (struct Struct)returnsStruct2; // expected-note {{method 'returnsStruct2' that returns 'struct Struct' declared here}}
- (Union)returnsId;
@end
@protocol IP
- (Union)returnsUnion; // expected-note 2 {{method 'returnsUnion' that returns 'Union' declared here}}
@end
typedef __attribute__((__ext_vector_type__(3))) float float3;
typedef int int4 __attribute__ ((vector_size (16)));
@interface I : Base<IP>
- (Rectangle)returnsStruct; // expected-note 4 {{method 'returnsStruct' that returns 'Rectangle' declared here}}
- (id)returnsId; // shadows base 'returnsId'
- (int)returnsInt;
- (I *)returnPtr;
- (float3)returnsExtVector; // expected-note {{method 'returnsExtVector' that returns 'float3' (vector of 3 'float' values) declared here}}
- (int4)returnsVector; // expected-note {{method 'returnsVector' that returns 'int4' (vector of 4 'int' values) declared here}}
+ (Rectangle)returnsStructClass; // expected-note 2 {{method 'returnsStructClass' that returns 'Rectangle' declared here}}
+ (void)returnsUnion; // Not really
@end
void foo(I *i) {
[i performSelector: @selector(returnsStruct)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
[i performSelectorInBackground: @selector(returnsStruct) withObject:0]; // expected-warning {{'performSelectorInBackground:withObject:' is incompatible with selectors that return a struct type}}
[i performSelector: ((@selector(returnsUnion)))]; // expected-warning {{'performSelector:' is incompatible with selectors that return a union type}}
[i performSelectorOnMainThread: @selector(returnsStruct2)]; // expected-warning {{'performSelectorOnMainThread:' is incompatible with selectors that return a struct type}}
[I performSelector: (@selector(returnsStructClass))]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
[i performSelector: @selector(returnsId)];
[i performSelector: @selector(returnsInt)];
[i performSelector: @selector(returnsPtr)];
[I performSelector: @selector(returnsUnion)]; // No warning expected
id obj = i;
[obj performSelector: @selector(returnsId)];
[obj performSelector: @selector(returnsStruct)];
}
@interface SubClass: I
@end
@interface SubClass ()
- (struct Struct)returnsSubStructExt; // expected-note {{method 'returnsSubStructExt' that returns 'struct Struct' declared here}} expected-note {{method 'returnsSubStructExt' declared here}}
@end
@implementation SubClass // expected-warning {{method definition for 'returnsSubStructExt' not found}}
- (struct Struct)returnsSubStructImpl { // expected-note {{method 'returnsSubStructImpl' that returns 'struct Struct' declared here}}
struct Struct Result;
return Result;
}
- (void)checkPrivateCalls {
[self performSelector: @selector(returnsSubStructExt)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
[self performSelector: @selector(returnsSubStructImpl)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
}
- (void)checkSuperCalls {
[super performSelector: @selector(returnsStruct)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
[super performSelectorInBackground: @selector(returnsUnion) withObject: self]; // expected-warning {{'performSelectorInBackground:withObject:' is incompatible with selectors that return a union type}}
[super performSelector: @selector(returnsId)];
}
+ (struct Struct)returnsSubStructClassImpl { // expected-note {{method 'returnsSubStructClassImpl' that returns 'struct Struct' declared here}}
struct Struct Result;
return Result;
}
+ (void)checkClassPrivateCalls {
[self performSelector: @selector(returnsSubStructClassImpl)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
}
+ (void)checkClassSuperCalls {
[super performSelector: @selector(returnsStructClass)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
[super performSelector: @selector(returnsUnion)]; // No warning expected
}
@end
@implementation I (LongPerformSelectors)
- (void)checkLongCallsFromCategory {
[self performSelectorOnMainThread: @selector(returnsStruct) onThread:0 withObject:self waitUntilDone:1 modes:0]; // expected-warning {{'performSelectorOnMainThread:onThread:withObject:waitUntilDone:modes:' is incompatible with selectors that return a struct type}}
}
- (void)checkVectorReturn {
[self performSelector: @selector(returnsExtVector)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a vector type}}
[self performSelector: @selector(returnsVector)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a vector type}}
}
@end