xref: /aosp_15_r20/external/clang/test/SemaObjCXX/arc-unbridged-cast.mm (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s
2*67e74705SXin Li
3*67e74705SXin Litypedef const struct __CFString * CFStringRef;
4*67e74705SXin Litypedef const void * CFTypeRef;
5*67e74705SXin Liextern "C" CFTypeRef CFBridgingRetain(id X);
6*67e74705SXin Liextern "C" id CFBridgingRelease(CFTypeRef);
7*67e74705SXin Li
8*67e74705SXin Li
9*67e74705SXin Li@interface Object
10*67e74705SXin Li@property CFStringRef property;
11*67e74705SXin Li- (CFStringRef) implicitProperty;
12*67e74705SXin Li- (CFStringRef) newString;
13*67e74705SXin Li- (CFStringRef) makeString;
14*67e74705SXin Li@end
15*67e74705SXin Li
16*67e74705SXin Liextern Object *object;
17*67e74705SXin Li
18*67e74705SXin Li// rdar://9744349
19*67e74705SXin Liid test0(void) {
20*67e74705SXin Li  id p1 = (id)[object property];
21*67e74705SXin Li  id p2 = (__bridge_transfer id)[object property];
22*67e74705SXin Li  id p3 = (__bridge id)[object property];
23*67e74705SXin Li  return (id) object.property;
24*67e74705SXin Li}
25*67e74705SXin Li
26*67e74705SXin Li// rdar://10140692
27*67e74705SXin LiCFStringRef unauditedString(void);
28*67e74705SXin LiCFStringRef plusOneString(void) __attribute__((cf_returns_retained));
29*67e74705SXin Li
30*67e74705SXin Li#pragma clang arc_cf_code_audited begin
31*67e74705SXin LiCFStringRef auditedString(void);
32*67e74705SXin LiCFStringRef auditedCreateString(void);
33*67e74705SXin Li#pragma clang arc_cf_code_audited end
34*67e74705SXin Li
35*67e74705SXin Livoid test1(int cond) {
36*67e74705SXin Li  id x;
37*67e74705SXin Li  x = (id) auditedString();
38*67e74705SXin Li  x = (id) (cond ? auditedString() : (void*) 0);
39*67e74705SXin Li  x = (id) (cond ? (void*) 0 : auditedString());
40*67e74705SXin Li  x = (id) (cond ? (CFStringRef) @"help" : auditedString());
41*67e74705SXin Li
42*67e74705SXin Li  x = (id) unauditedString(); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
43*67e74705SXin Li  x = (id) (cond ? unauditedString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
44*67e74705SXin Li  x = (id) (cond ? (void*) 0 : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
45*67e74705SXin Li  x = (id) (cond ? (CFStringRef) @"help" : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
46*67e74705SXin Li
47*67e74705SXin Li  x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
48*67e74705SXin Li  x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
49*67e74705SXin Li  x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
50*67e74705SXin Li  x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
51*67e74705SXin Li
52*67e74705SXin Li  x = (id) [object property];
53*67e74705SXin Li  x = (id) (cond ? [object property] : (void*) 0);
54*67e74705SXin Li  x = (id) (cond ? (void*) 0 : [object property]);
55*67e74705SXin Li  x = (id) (cond ? (CFStringRef) @"help" : [object property]);
56*67e74705SXin Li
57*67e74705SXin Li  x = (id) object.property;
58*67e74705SXin Li  x = (id) (cond ? object.property : (void*) 0);
59*67e74705SXin Li  x = (id) (cond ? (void*) 0 : object.property);
60*67e74705SXin Li  x = (id) (cond ? (CFStringRef) @"help" : object.property);
61*67e74705SXin Li
62*67e74705SXin Li  x = (id) object.implicitProperty;
63*67e74705SXin Li  x = (id) (cond ? object.implicitProperty : (void*) 0);
64*67e74705SXin Li  x = (id) (cond ? (void*) 0 : object.implicitProperty);
65*67e74705SXin Li  x = (id) (cond ? (CFStringRef) @"help" : object.implicitProperty);
66*67e74705SXin Li
67*67e74705SXin Li  x = (id) [object makeString];
68*67e74705SXin Li  x = (id) (cond ? [object makeString] : (void*) 0);
69*67e74705SXin Li  x = (id) (cond ? (void*) 0 : [object makeString]);
70*67e74705SXin Li  x = (id) (cond ? (CFStringRef) @"help" : [object makeString]);
71*67e74705SXin Li
72*67e74705SXin Li  x = (id) [object newString];
73*67e74705SXin Li  x = (id) (cond ? [object newString] : (void*) 0);
74*67e74705SXin Li  x = (id) (cond ? (void*) 0 : [object newString]);
75*67e74705SXin Li  x = (id) (cond ? (CFStringRef) @"help" : [object newString]); // a bit questionable
76*67e74705SXin Li}
77*67e74705SXin Li
78*67e74705SXin Li// rdar://problem/10246264
79*67e74705SXin Li@interface CFTaker
80*67e74705SXin Li- (void) takeOrdinary: (CFStringRef) arg;
81*67e74705SXin Li- (void) takeVariadic: (int) n, ...;
82*67e74705SXin Li- (void) takeConsumed: (CFStringRef __attribute__((cf_consumed))) arg;
83*67e74705SXin Li@end
84*67e74705SXin Livoid testCFTaker(CFTaker *taker, id string) {
85*67e74705SXin Li  [taker takeOrdinary: (CFStringRef) string];
86*67e74705SXin Li  [taker takeVariadic: 1, (CFStringRef) string];
87*67e74705SXin Li  [taker takeConsumed: (CFStringRef) string]; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
88*67e74705SXin Li}
89*67e74705SXin Li
90*67e74705SXin Livoid takeCFOrdinaryUnaudited(CFStringRef arg);
91*67e74705SXin Livoid takeCFVariadicUnaudited(int n, ...);
92*67e74705SXin Livoid takeCFConsumedUnaudited(CFStringRef __attribute__((cf_consumed)) arg);
93*67e74705SXin Li#pragma clang arc_cf_code_audited begin
94*67e74705SXin Livoid takeCFOrdinaryAudited(CFStringRef arg);
95*67e74705SXin Livoid takeCFVariadicAudited(int n, ...);
96*67e74705SXin Livoid takeCFConsumedAudited(CFStringRef __attribute__((cf_consumed)) arg);
97*67e74705SXin Li#pragma clang arc_cf_code_audited end
98*67e74705SXin Li
99*67e74705SXin Livoid testTakerFunctions(id string) {
100*67e74705SXin Li  takeCFOrdinaryUnaudited((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
101*67e74705SXin Li  takeCFVariadicUnaudited(1, (CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
102*67e74705SXin Li  takeCFConsumedUnaudited((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
103*67e74705SXin Li
104*67e74705SXin Li  void (*taker)(CFStringRef) = 0;
105*67e74705SXin Li  taker((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
106*67e74705SXin Li
107*67e74705SXin Li  takeCFOrdinaryAudited((CFStringRef) string);
108*67e74705SXin Li  takeCFVariadicAudited(1, (CFStringRef) string);
109*67e74705SXin Li  takeCFConsumedAudited((CFStringRef) string); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef'}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRetain call to}}
110*67e74705SXin Li}
111*67e74705SXin Li
112*67e74705SXin Li// rdar://12788838
113*67e74705SXin Liid obj;
114*67e74705SXin Li
115*67e74705SXin Livoid rdar12788838() {
116*67e74705SXin Li  void *foo = reinterpret_cast<void *>(obj); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} \
117*67e74705SXin Li		// expected-note {{use __bridge with C-style cast to convert directly}} \
118*67e74705SXin Li		// expected-note {{use CFBridgingRetain call to make an ARC object available as a +1 'void *'}}
119*67e74705SXin Li}
120