1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -fblocks -o - %s | FileCheck %s 2 3 struct S { 4 int a[4]; 5 S(int *, int * __attribute__((noescape))); 6 S &operator=(int * __attribute__((noescape))); 7 void m0(int *, int * __attribute__((noescape))); 8 virtual void vm1(int *, int * __attribute__((noescape))); 9 }; 10 11 // CHECK: define{{.*}} void @_ZN1SC2EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} noundef captures(none) {{%.*}}) 12 // CHECK: define{{.*}} void @_ZN1SC1EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} noundef captures(none) {{%.*}}) {{.*}} { 13 // CHECK: call void @_ZN1SC2EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} captures(none) {{.*}}) 14 15 S::S(int *, int * __attribute__((noescape))) {} 16 17 // CHECK: define {{.*}} ptr @_ZN1SaSEPi(ptr {{.*}}, {{.*}} noundef captures(none) {{%.*}}) 18 S &S::operator=(int * __attribute__((noescape))) { return *this; } 19 20 // CHECK: define{{.*}} void @_ZN1S2m0EPiS0_(ptr {{.*}}, {{.*}} noundef captures(none) {{%.*}}) 21 void S::m0(int *, int * __attribute__((noescape))) {} 22 23 // CHECK: define{{.*}} void @_ZN1S3vm1EPiS0_(ptr {{.*}}, {{.*}} noundef captures(none) {{%.*}}) 24 void S::vm1(int *, int * __attribute__((noescape))) {} 25 26 // CHECK-LABEL: define{{.*}} void @_Z5test0P1SPiS1_( 27 // CHECK: call void @_ZN1SC1EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} noundef captures(none) {{.*}}) 28 // CHECK: call {{.*}} ptr @_ZN1SaSEPi(ptr {{.*}}, {{.*}} noundef captures(none) {{.*}}) 29 // CHECK: call void @_ZN1S2m0EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} noundef captures(none) {{.*}}) 30 // CHECK: call void {{.*}}(ptr {{.*}}, {{.*}}, {{.*}} noundef captures(none) {{.*}}) 31 void test0(S *s, int *p0, int *p1) { 32 S t(p0, p1); 33 t = p1; 34 s->m0(p0, p1); 35 s->vm1(p0, p1); 36 } 37 38 namespace std { 39 typedef decltype(sizeof(0)) size_t; 40 } 41 42 // CHECK: define {{.*}} @_ZnwmPv({{.*}}, {{.*}} captures(none) {{.*}}) 43 void *operator new(std::size_t, void * __attribute__((noescape)) p) { 44 return p; 45 } 46 47 // CHECK-LABEL: define{{.*}} ptr @_Z5test1Pv( 48 // CHECK: %call = call {{.*}} @_ZnwmPv({{.*}}, {{.*}} captures(none) {{.*}}) 49 void *test1(void *p0) { 50 return ::operator new(16, p0); 51 } 52 53 // CHECK-LABEL: define{{.*}} void @_Z5test2PiS_( 54 // CHECK: call void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} captures(none) {{.*}}) 55 // CHECK: define internal void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} noundef captures(none) {{%.*}}) 56 void test2(int *p0, int *p1) { 57 auto t = [](int *, int * __attribute__((noescape))){}; 58 t(p0, p1); 59 } 60 61 // CHECK-LABEL: define{{.*}} void @_Z5test3PFvU8noescapePiES_( 62 // CHECK: call void {{.*}}(ptr noundef captures(none) {{.*}}) 63 typedef void (*NoEscapeFunc)(__attribute__((noescape)) int *); 64 65 void test3(NoEscapeFunc f, int *p) { 66 f(p); 67 } 68 69 namespace TestByref { 70 71 struct S { 72 S(); 73 ~S(); 74 S(const S &); 75 int a; 76 }; 77 78 typedef void (^BlockTy)(void); 79 S &getS(); 80 void noescapefunc(__attribute__((noescape)) BlockTy); 81 82 // Check that __block variables with reference types are handled correctly. 83 84 // CHECK: define{{.*}} void @_ZN9TestByref4testEv( 85 // CHECK: %[[X:.*]] = alloca ptr, align 8 86 // CHECK: %[[BLOCK:.*]] = alloca <{ ptr, i32, i32, ptr, ptr, ptr }>, align 8 87 // CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 5 88 // CHECK: %[[V0:.*]] = load ptr, ptr %[[X]], align 8 89 // CHECK: store ptr %[[V0]], ptr %[[BLOCK_CAPTURED]], align 8 90 91 void test() { 92 __block S &x = getS(); 93 noescapefunc(^{ (void)x; }); 94 } 95 96 } 97