George Burgess IV | 08a4a8c | 2015-12-03 19:19:09 +0000 | [diff] [blame] | 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 | } |
George Burgess IV | 7204ed9 | 2016-01-07 02:26:57 +0000 | [diff] [blame] | 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 | } |
Richard Smith | 50f89da | 2016-06-14 00:48:35 +0000 | [diff] [blame] | 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 | } |
George Burgess IV | 419996c | 2016-06-16 23:06:04 +0000 | [diff] [blame] | 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 | } |