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