1// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s 2// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++1z %s 3 4typedef void (^BlockTy)(); 5 6struct S { 7 int i; 8 void m(); 9}; 10 11void escapingFunc0(BlockTy); 12void noescapeFunc0(id, __attribute__((noescape)) BlockTy); 13void noescapeFunc1(id, [[clang::noescape]] BlockTy); 14void noescapeFunc2(__attribute__((noescape)) int *); // expected-note {{previous declaration is here}} 15void noescapeFunc3(__attribute__((noescape)) id); 16void noescapeFunc4(__attribute__((noescape)) int &); 17void noescapeFunc2(int *); // expected-error {{conflicting types for 'noescapeFunc2'}} 18 19template <class T> 20void noescapeFunc5(__attribute__((noescape)) T); 21template <class T> 22void noescapeFunc6(__attribute__((noescape)) const T &); 23template <class T> 24void noescapeFunc7(__attribute__((noescape)) T &&); 25 26void invalidFunc0(int __attribute__((noescape))); // expected-warning {{'noescape' attribute only applies to pointer arguments}} 27void invalidFunc1(int __attribute__((noescape(0)))); // expected-error {{'noescape' attribute takes no arguments}} 28void invalidFunc2(int0 *__attribute__((noescape))); // expected-error {{use of undeclared identifier 'int0'; did you mean 'int'?}} 29void invalidFunc3(__attribute__((noescape)) int (S::*Ty)); // expected-warning {{'noescape' attribute only applies to pointer arguments}} 30void invalidFunc4(__attribute__((noescape)) void (S::*Ty)()); // expected-warning {{'noescape' attribute only applies to pointer arguments}} 31int __attribute__((noescape)) g; // expected-warning {{'noescape' attribute only applies to parameters}} 32 33struct S1 { 34 virtual void m0(int *__attribute__((noescape))); // expected-note {{parameter of overridden method is annotated with __attribute__((noescape))}} 35}; 36 37struct S2 : S1 { 38 void m0(int *__attribute__((noescape))) override; 39}; 40 41struct S3 : S1 { 42 void m0(int *) override; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}} 43}; 44 45__attribute__((objc_root_class)) 46@interface C0 47-(void) m0:(int*)__attribute__((noescape)) p; // expected-note {{parameter of overridden method is annotated with __attribute__((noescape))}} 48- (void)noescapeLValRefParam:(const BlockTy &)__attribute__((noescape))p; 49- (void)noescapeRValRefParam:(BlockTy &&)__attribute__((noescape))p; 50@end 51 52@implementation C0 53-(void) m0:(int*)__attribute__((noescape)) p {} 54- (void)noescapeLValRefParam:(const BlockTy &)__attribute__((noescape))p { 55} 56- (void)noescapeRValRefParam:(BlockTy &&)__attribute__((noescape))p { 57} 58@end 59 60@interface C1 : C0 61-(void) m0:(int*)__attribute__((noescape)) p; 62@end 63 64@implementation C1 : C0 65-(void) m0:(int*)__attribute__((noescape)) p {} 66@end 67 68@interface C2 : C0 69-(void) m0:(int*) p; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}} 70@end 71 72@implementation C2 : C0 73-(void) m0:(int*) p {} 74@end 75 76void func0(int *); 77void (*fnptr0)(int *); 78void (*fnptr1)(__attribute__((noescape)) int *); 79template<void (*fn)(int*)> struct S4 {}; 80#if __cplusplus < 201406 81// expected-note@-2 {{template parameter is declared here}} 82#endif 83template<void (*fn)(int* __attribute__((noescape)))> struct S5 {}; 84// expected-note@-1 {{template parameter is declared here}} 85 86void test0() { 87 fnptr0 = &func0; 88 fnptr0 = &noescapeFunc2; 89 fnptr1 = &func0; // expected-error {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *)' from 'void (*)(int *)'}} 90 fnptr1 = &noescapeFunc2; 91 S4<&func0> e0; 92 S4<&noescapeFunc2> e1; 93 S5<&func0> ne0; 94 95#if __cplusplus < 201406 96 // expected-error@-4 {{non-type template argument of type 'void (*)(__attribute__((noescape)) int *)' cannot be converted to a value of type 'void (*)(int *)'}} 97 // expected-error@-4 {{non-type template argument of type 'void (*)(int *)' cannot be converted to a value of type 'void (*)(__attribute__((noescape)) int *)'}} 98#else 99 // expected-error@-6 {{value of type 'void (*)(int *)' is not implicitly convertible to 'void (*)(__attribute__((noescape)) int *)'}} 100#endif 101 102 S5<&noescapeFunc2> ne1; 103} 104 105@protocol NoescapeProt 106-(void) m0:(int*)__attribute__((noescape)) p; // expected-note 2 {{parameter of overridden method is annotated with __attribute__((noescape))}} 107+(void) m1:(int*)__attribute__((noescape)) p; 108-(void) m1:(int*) p; 109@end 110 111__attribute__((objc_root_class)) 112@interface C3 113-(void) m0:(int*) p; 114+(void) m1:(int*)__attribute__((noescape)) p; 115-(void) m1:(int*) p; 116@end 117 118@interface C3 () <NoescapeProt> // expected-note {{class extension conforms to protocol 'NoescapeProt' which defines method 'm0:'}} 119@end 120 121@implementation C3 122-(void) m0:(int*) p { // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}} 123} 124+(void) m1:(int*)__attribute__((noescape)) p { 125} 126-(void) m1:(int*) p { 127} 128@end 129 130__attribute__((objc_root_class)) 131@interface C4 <NoescapeProt> 132-(void) m0:(int*) p; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}} 133@end 134 135@implementation C4 136-(void) m0:(int*) p { 137} 138+(void) m1:(int*)__attribute__((noescape)) p { 139} 140-(void) m1:(int*) p { 141} 142@end 143 144struct S6 { 145 S6(); 146 S6(const S6 &) = delete; // expected-note 11 {{'S6' has been explicitly marked deleted here}} 147 int f; 148}; 149 150void test1(C0 *c0) { 151 id a; 152 // __block variables that are not captured by escaping blocks don't 153 // necessitate having accessible copy constructors. 154 __block S6 b0; 155 __block S6 b1; // expected-error {{call to deleted constructor of 'S6'}} 156 __block S6 b2; // expected-error {{call to deleted constructor of 'S6'}} 157 __block S6 b3; // expected-error {{call to deleted constructor of 'S6'}} 158 __block S6 b4; // expected-error {{call to deleted constructor of 'S6'}} 159 __block S6 b5; // expected-error {{call to deleted constructor of 'S6'}} 160 __block S6 b6; // expected-error {{call to deleted constructor of 'S6'}} 161 __block S6 b7; // expected-error {{call to deleted constructor of 'S6'}} 162 __block S6 b8; // expected-error {{call to deleted constructor of 'S6'}} 163 __block S6 b9; 164 __block S6 b10; // expected-error {{call to deleted constructor of 'S6'}} 165 __block S6 b11; // expected-error {{call to deleted constructor of 'S6'}} 166 __block S6 b12; 167 __block S6 b13; 168 __block S6 b14; // expected-error {{call to deleted constructor of 'S6'}} 169 170 noescapeFunc0(a, ^{ (void)b0; }); 171 escapingFunc0(^{ (void)b1; }); 172 { 173 noescapeFunc0(a, ^{ (void)b0; (void)b1; }); 174 } 175 noescapeFunc0(a, ^{ escapingFunc0(^{ (void)b2; }); }); 176 escapingFunc0(^{ noescapeFunc0(a, ^{ (void)b3; }); }); 177 178 [c0 noescapeLValRefParam:^{ 179 (void)b4; 180 }]; 181 182 [c0 noescapeRValRefParam:^{ 183 (void)b5; 184 }]; 185 186 void noescape_id(__attribute__((noescape)) id); 187 noescape_id(^{ 188 (void)b6; 189 }); 190 191 void noescapeLValRefParam(__attribute__((noescape)) const BlockTy &); 192 noescapeLValRefParam(^{ 193 (void)b7; 194 }); 195 196 void noescapeRValRefParam(__attribute__((noescape)) BlockTy &&); 197 noescapeRValRefParam(^{ 198 (void)b8; 199 }); 200 201 noescapeFunc5(^{ 202 (void)b9; 203 }); 204 205 noescapeFunc6(^{ 206 (void)b10; 207 }); 208 209 noescapeFunc7(^{ 210 (void)b11; 211 }); 212 213 struct NoescapeCtor { 214 NoescapeCtor(__attribute__((noescape)) void (^)()); 215 }; 216 struct EscapeCtor { 217 EscapeCtor(void (^)()); 218 }; 219 220 void helper1(NoescapeCtor a); 221 helper1(^{ 222 (void)b12; 223 }); 224 225 void helper2(NoescapeCtor && a); 226 helper2(^{ 227 (void)b13; 228 }); 229 230 void helper3(__attribute__((noescape)) EscapeCtor && a); 231 helper3(^{ 232 (void)b14; 233 }); 234} 235