235 lines · plain
1// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s2// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++1z %s3 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 C047-(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@end51 52@implementation C053-(void) m0:(int*)__attribute__((noescape)) p {}54- (void)noescapeLValRefParam:(const BlockTy &)__attribute__((noescape))p {55}56- (void)noescapeRValRefParam:(BlockTy &&)__attribute__((noescape))p {57}58@end59 60@interface C1 : C061-(void) m0:(int*)__attribute__((noescape)) p;62@end63 64@implementation C1 : C065-(void) m0:(int*)__attribute__((noescape)) p {}66@end67 68@interface C2 : C069-(void) m0:(int*) p; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}}70@end71 72@implementation C2 : C073-(void) m0:(int*) p {}74@end75 76void func0(int *);77void (*fnptr0)(int *);78void (*fnptr1)(__attribute__((noescape)) int *);79template<void (*fn)(int*)> struct S4 {};80#if __cplusplus < 20140681// expected-note@-2 {{template parameter is declared here}}82#endif83template<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 < 20140696 // 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#else99 // expected-error@-6 {{value of type 'void (*)(int *)' is not implicitly convertible to 'void (*)(__attribute__((noescape)) int *)'}}100#endif101 102 S5<&noescapeFunc2> ne1;103}104 105@protocol NoescapeProt106-(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@end110 111__attribute__((objc_root_class))112@interface C3113-(void) m0:(int*) p;114+(void) m1:(int*)__attribute__((noescape)) p;115-(void) m1:(int*) p;116@end117 118@interface C3 () <NoescapeProt> // expected-note {{class extension conforms to protocol 'NoescapeProt' which defines method 'm0:'}}119@end120 121@implementation C3122-(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@end129 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@end134 135@implementation C4136-(void) m0:(int*) p {137}138+(void) m1:(int*)__attribute__((noescape)) p {139}140-(void) m1:(int*) p {141}142@end143 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't153 // 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