1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 -std=c++11 | FileCheck %s 2 3 int gi; 4 5 namespace lambdas { 6 // CHECK-LABEL: define void @_ZN7lambdas7LambdasEPc 7 void Lambdas(char *ptr) { 8 auto L1 = [](void *const p __attribute__((pass_object_size(0)))) { 9 return __builtin_object_size(p, 0); 10 }; 11 12 int i = 0; 13 auto L2 = [&i](void *const p __attribute__((pass_object_size(0)))) { 14 return __builtin_object_size(p, 0) + i; 15 }; 16 17 // CHECK: @llvm.objectsize 18 gi = L1(ptr); 19 // CHECK: @llvm.objectsize 20 gi = L2(ptr); 21 } 22 23 // CHECK-DAG: define internal i64 @"_ZZN7lambdas7LambdasEPcENK3$_0clEPvU17pass_object_size0" 24 // CHECK-NOT: call i64 @llvm.objectsize 25 // CHECK-DAG: define internal i64 @"_ZZN7lambdas7LambdasEPcENK3$_1clEPvU17pass_object_size0" 26 // CHECK-NOT: call i64 @llvm.objectsize 27 } 28 29 // This is here instead of in Sema/ because we need to check to make sure the 30 // proper function is called. If it's not, we'll end up with assertion errors. 31 namespace addrof { 32 void OvlFoo(void *const __attribute__((pass_object_size(0)))) {} 33 void OvlFoo(int *const) {} 34 35 // CHECK: define void @_ZN6addrof4TestEv 36 void Test() { 37 // Treating parens-only calls as though they were direct is consistent with 38 // how we handle other implicitly unaddressable functions (e.g. builtins). 39 // CHECK: call void @_ZN6addrof6OvlFooEPvU17pass_object_size0 40 (OvlFoo)(nullptr); 41 42 // CHECK: call void @_ZN6addrof6OvlFooEPi 43 (&OvlFoo)(nullptr); 44 } 45 } 46 47 namespace delegate { 48 struct A { 49 A(void *const p __attribute__((pass_object_size(0)))); 50 }; 51 A::A(void *const p __attribute__((pass_object_size(0)))) {} 52 // Ensure that we forward the size through a delegating constructor call. 53 // CHECK: define void @_ZN8delegate1AC1EPvU17pass_object_size0({{[^,]*}}, i8*{{[^,]*}}, i64{{[^,]*}}) 54 // CHECK: call void @_ZN8delegate1AC2EPvU17pass_object_size0({{[^,]*}}, i8*{{[^,]*}}, i64{{[^,]*}}) 55 } 56 57 namespace variadic { 58 // We had an issue where variadic member/operator calls with pass_object_size 59 // would cause crashes. 60 61 struct AsCtor { 62 AsCtor(const char *const c __attribute__((pass_object_size(0))), double a, 63 ...) {} 64 }; 65 66 struct AsMember { 67 void bar(const char *const c __attribute__((pass_object_size(0))), double a, 68 ...) {} 69 void operator()(const char *const c __attribute__((pass_object_size(0))), 70 double a, ...) {} 71 }; 72 73 // CHECK-LABEL: define void @_ZN8variadic4testEv() 74 void test() { 75 // CHECK-RE: call{{[^@]+}}@_ZN8variadic6AsCtorC1EPKcU17pass_object_size0dz 76 AsCtor("a", 1.0); 77 // CHECK-RE: call{{[^@]+}}@_ZN8variadic8AsMember3barEPKcU17pass_object_size0dz 78 AsMember{}.bar("a", 1.0); 79 // CHECK-RE: call{{[^@]+}}@_ZN8variadic8AsMemberclEPKcU17pass_object_size0dz 80 AsMember{}("a", 1.0); 81 } 82 } 83