1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - | FileCheck %s
2*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 %s -std=c++11 -emit-pch -o %t
3*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 %s -std=c++11 -include-pch %t -emit-llvm -o - | FileCheck %s
4*0a6a1f1dSLionel Sambuc
5*0a6a1f1dSLionel Sambuc #ifndef HEADER
6*0a6a1f1dSLionel Sambuc #define HEADER
7*0a6a1f1dSLionel Sambuc
8*0a6a1f1dSLionel Sambuc typedef __INTPTR_TYPE__ intptr_t;
9*0a6a1f1dSLionel Sambuc
10*0a6a1f1dSLionel Sambuc // CHECK-DAG: [[CAP_TYPE1:%.+]] = type { [[INTPTR_T:i.+]], [[INTPTR_T]]*, [[INTPTR_T]]* }
11*0a6a1f1dSLionel Sambuc // CHECK-DAG: [[CAP_TYPE2:%.+]] = type { [[INTPTR_T]], [[INTPTR_T]]* }
12*0a6a1f1dSLionel Sambuc // CHECK-DAG: [[CAP_TYPE3:%.+]] = type { [[INTPTR_T]]*, [[INTPTR_T]], [[INTPTR_T]], [[INTPTR_T]]*, [[INTPTR_T]]* }
13*0a6a1f1dSLionel Sambuc // CHECK-DAG: [[CAP_TYPE4:%.+]] = type { [[INTPTR_T]]*, [[INTPTR_T]], [[INTPTR_T]]*, [[INTPTR_T]], [[INTPTR_T]]* }
14*0a6a1f1dSLionel Sambuc
15*0a6a1f1dSLionel Sambuc // CHECK: define void [[G:@.+]](
16*0a6a1f1dSLionel Sambuc // CHECK: [[N_ADDR:%.+]] = alloca [[INTPTR_T]]
17*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]] %{{.+}}, [[INTPTR_T]]* [[N_ADDR]]
18*0a6a1f1dSLionel Sambuc // CHECK: [[N_VAL:%.+]] = load [[INTPTR_T]]* [[N_ADDR]]
19*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_EXPR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE1]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0
20*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]] [[N_VAL]], [[INTPTR_T]]* [[CAP_EXPR_REF]]
21*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_BUFFER_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1
22*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]]* %{{.+}}, [[INTPTR_T]]** [[CAP_BUFFER_ADDR]]
23*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_N_REF:%.+]] = getelementptr inbounds [[CAP_TYPE1]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 2
24*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]]* [[N_ADDR]], [[INTPTR_T]]** [[CAP_N_REF]]
25*0a6a1f1dSLionel Sambuc // CHECK: call void [[G_LAMBDA:@.+]]([[CAP_TYPE1]]* [[CAP_ARG]])
26*0a6a1f1dSLionel Sambuc // CHECK: ret void
g(intptr_t n)27*0a6a1f1dSLionel Sambuc void g(intptr_t n) {
28*0a6a1f1dSLionel Sambuc intptr_t buffer[n];
29*0a6a1f1dSLionel Sambuc [&buffer, &n]() {
30*0a6a1f1dSLionel Sambuc __typeof(buffer) x;
31*0a6a1f1dSLionel Sambuc }();
32*0a6a1f1dSLionel Sambuc }
33*0a6a1f1dSLionel Sambuc
34*0a6a1f1dSLionel Sambuc // CHECK: void [[G_LAMBDA]]([[CAP_TYPE1]]*
35*0a6a1f1dSLionel Sambuc // CHECK: [[THIS:%.+]] = load [[CAP_TYPE1]]**
36*0a6a1f1dSLionel Sambuc // CHECK: [[N_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]]* [[THIS]], i{{.+}} 0, i{{.+}} 0
37*0a6a1f1dSLionel Sambuc // CHECK: [[N:%.+]] = load [[INTPTR_T]]* [[N_ADDR]]
38*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]]* [[THIS]], i{{.+}} 0, i{{.+}} 1
39*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER:%.+]] = load [[INTPTR_T]]** [[BUFFER_ADDR]]
40*0a6a1f1dSLionel Sambuc // CHECK: call i{{.+}}* @llvm.stacksave()
41*0a6a1f1dSLionel Sambuc // CHECK: alloca [[INTPTR_T]], [[INTPTR_T]] [[N]]
42*0a6a1f1dSLionel Sambuc // CHECK: call void @llvm.stackrestore(
43*0a6a1f1dSLionel Sambuc // CHECK: ret void
44*0a6a1f1dSLionel Sambuc
45*0a6a1f1dSLionel Sambuc template <typename T>
f(T n,T m)46*0a6a1f1dSLionel Sambuc void f(T n, T m) {
47*0a6a1f1dSLionel Sambuc intptr_t buffer[n + m];
48*0a6a1f1dSLionel Sambuc [&buffer]() {
49*0a6a1f1dSLionel Sambuc __typeof(buffer) x;
50*0a6a1f1dSLionel Sambuc }();
51*0a6a1f1dSLionel Sambuc }
52*0a6a1f1dSLionel Sambuc
53*0a6a1f1dSLionel Sambuc template <typename T>
54*0a6a1f1dSLionel Sambuc intptr_t getSize(T);
55*0a6a1f1dSLionel Sambuc
56*0a6a1f1dSLionel Sambuc template <typename T>
b(intptr_t n,T arg)57*0a6a1f1dSLionel Sambuc void b(intptr_t n, T arg) {
58*0a6a1f1dSLionel Sambuc typedef intptr_t ArrTy[getSize(arg)];
59*0a6a1f1dSLionel Sambuc ArrTy buffer2;
60*0a6a1f1dSLionel Sambuc ArrTy buffer1[n + arg];
61*0a6a1f1dSLionel Sambuc intptr_t a;
62*0a6a1f1dSLionel Sambuc [&]() {
63*0a6a1f1dSLionel Sambuc n = sizeof(buffer1[n]);
64*0a6a1f1dSLionel Sambuc [&](){
65*0a6a1f1dSLionel Sambuc n = sizeof(buffer2);
66*0a6a1f1dSLionel Sambuc n = sizeof(buffer1);
67*0a6a1f1dSLionel Sambuc }();
68*0a6a1f1dSLionel Sambuc }();
69*0a6a1f1dSLionel Sambuc }
70*0a6a1f1dSLionel Sambuc
71*0a6a1f1dSLionel Sambuc // CHECK-LABEL: @main
main()72*0a6a1f1dSLionel Sambuc int main() {
73*0a6a1f1dSLionel Sambuc // CHECK: call void [[G]]([[INTPTR_T]] [[INTPTR_T_ATTR:(signext )?]]1)
74*0a6a1f1dSLionel Sambuc g((intptr_t)1);
75*0a6a1f1dSLionel Sambuc // CHECK: call void [[F_INT:@.+]]([[INTPTR_T]] [[INTPTR_T_ATTR]]1, [[INTPTR_T]] [[INTPTR_T_ATTR]]2)
76*0a6a1f1dSLionel Sambuc f((intptr_t)1, (intptr_t)2);
77*0a6a1f1dSLionel Sambuc // CHECK: call void [[B_INT:@.+]]([[INTPTR_T]] [[INTPTR_T_ATTR]]12, [[INTPTR_T]] [[INTPTR_T_ATTR]]13)
78*0a6a1f1dSLionel Sambuc b((intptr_t)12, (intptr_t)13);
79*0a6a1f1dSLionel Sambuc // CHECK: ret i32 0
80*0a6a1f1dSLionel Sambuc return 0;
81*0a6a1f1dSLionel Sambuc }
82*0a6a1f1dSLionel Sambuc
83*0a6a1f1dSLionel Sambuc // CHECK: void [[F_INT]]([[INTPTR_T]]
84*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE:%.+]] = add
85*0a6a1f1dSLionel Sambuc // CHECK: call i{{.+}}* @llvm.stacksave()
86*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER_ADDR:%.+]] = alloca [[INTPTR_T]], [[INTPTR_T]] [[SIZE]]
87*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_SIZE_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0
88*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]] [[SIZE]], [[INTPTR_T]]* [[CAP_SIZE_REF]]
89*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_BUFFER_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1
90*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]]* [[BUFFER_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER_ADDR_REF]]
91*0a6a1f1dSLionel Sambuc // CHECK: call void [[F_INT_LAMBDA:@.+]]([[CAP_TYPE2]]* [[CAP_ARG]])
92*0a6a1f1dSLionel Sambuc // CHECK: call void @llvm.stackrestore(
93*0a6a1f1dSLionel Sambuc // CHECK: ret void
94*0a6a1f1dSLionel Sambuc // CHECK: void [[B_INT]]([[INTPTR_T]]
95*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE1:%.+]] = call [[INTPTR_T]]
96*0a6a1f1dSLionel Sambuc // CHECK: call i{{.+}}* @llvm.stacksave()
97*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER2_ADDR:%.+]] = alloca [[INTPTR_T]], [[INTPTR_T]] [[SIZE1]]
98*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE2:%.+]] = add
99*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER1_ADDR:%.+]] = alloca [[INTPTR_T]], [[INTPTR_T]]
100*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0
101*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]]* {{%.+}}, [[INTPTR_T]]** [[CAP_N_ADDR_REF]]
102*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1
103*0a6a1f1dSLionel Sambuc // CHECK: store i{{[0-9]+}} [[SIZE2]], i{{[0-9]+}}* [[CAP_SIZE2_REF]]
104*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 2
105*0a6a1f1dSLionel Sambuc // CHECK: store i{{[0-9]+}} [[SIZE1]], i{{[0-9]+}}* [[CAP_SIZE1_REF]]
106*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 3
107*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]]* [[BUFFER1_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER1_ADDR_REF]]
108*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 4
109*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]]* [[BUFFER2_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER2_ADDR_REF]]
110*0a6a1f1dSLionel Sambuc // CHECK: call void [[B_INT_LAMBDA:@.+]]([[CAP_TYPE3]]* [[CAP_ARG]])
111*0a6a1f1dSLionel Sambuc // CHECK: call void @llvm.stackrestore(
112*0a6a1f1dSLionel Sambuc // CHECK: ret void
113*0a6a1f1dSLionel Sambuc
114*0a6a1f1dSLionel Sambuc // CHECK: define {{.*}} void [[B_INT_LAMBDA]]([[CAP_TYPE3]]*
115*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
116*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE2:%.+]] = load i{{[0-9]+}}* [[SIZE2_REF]]
117*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
118*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE1:%.+]] = load i{{[0-9]+}}* [[SIZE1_REF]]
119*0a6a1f1dSLionel Sambuc // CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
120*0a6a1f1dSLionel Sambuc // CHECK: [[N_ADDR:%.+]] = load [[INTPTR_T]]** [[N_ADDR_REF]]
121*0a6a1f1dSLionel Sambuc // CHECK: [[N:%.+]] = load [[INTPTR_T]]* [[N_ADDR]]
122*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
123*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]** [[BUFFER1_ADDR_REF]]
124*0a6a1f1dSLionel Sambuc // CHECK: [[ELEM_OFFSET:%.+]] = mul {{.*}} i{{[0-9]+}} [[N]], [[SIZE1]]
125*0a6a1f1dSLionel Sambuc // CHECK: [[ELEM_ADDR:%.+]] = getelementptr inbounds [[INTPTR_T]]* [[BUFFER1_ADDR]], i{{[0-9]+}} [[ELEM_OFFSET]]
126*0a6a1f1dSLionel Sambuc // CHECK: [[SIZEOF:%.+]] = mul {{.*}} i{{[0-9]+}} {{[0-9]+}}, [[SIZE1]]
127*0a6a1f1dSLionel Sambuc // CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
128*0a6a1f1dSLionel Sambuc // CHECK: [[N_ADDR:%.+]] = load [[INTPTR_T]]** [[N_ADDR_REF]]
129*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]] {{%.+}}, [[INTPTR_T]]* [[N_ADDR]]
130*0a6a1f1dSLionel Sambuc // CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[CAP:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
131*0a6a1f1dSLionel Sambuc // CHECK: [[N_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
132*0a6a1f1dSLionel Sambuc // CHECK: [[N_ADDR_ORIG:%.+]] = load [[INTPTR_T]]** [[N_ADDR_REF_ORIG]]
133*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]]* [[N_ADDR_ORIG]], [[INTPTR_T]]** [[N_ADDR_REF]]
134*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
135*0a6a1f1dSLionel Sambuc // CHECK: store i{{[0-9]+}} [[SIZE1]], i{{[0-9]+}}* [[SIZE1_REF]]
136*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
137*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER2_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
138*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER2_ADDR_ORIG:%.+]] = load [[INTPTR_T]]** [[BUFFER2_ADDR_REF_ORIG]]
139*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]]* [[BUFFER2_ADDR_ORIG]], [[INTPTR_T]]** [[BUFFER2_ADDR_REF]]
140*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
141*0a6a1f1dSLionel Sambuc // CHECK: store i{{[0-9]+}} [[SIZE2]], i{{[0-9]+}}* [[SIZE2_REF]]
142*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
143*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER1_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
144*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER1_ADDR_ORIG:%.+]] = load [[INTPTR_T]]** [[BUFFER1_ADDR_REF_ORIG]]
145*0a6a1f1dSLionel Sambuc // CHECK: store [[INTPTR_T]]* [[BUFFER1_ADDR_ORIG]], [[INTPTR_T]]** [[BUFFER1_ADDR_REF]]
146*0a6a1f1dSLionel Sambuc // CHECK: call void [[B_INT_LAMBDA_LAMBDA:@.+]]([[CAP_TYPE4]]* [[CAP]])
147*0a6a1f1dSLionel Sambuc // CHECK: ret void
148*0a6a1f1dSLionel Sambuc
149*0a6a1f1dSLionel Sambuc // CHECK: define {{.*}} void [[B_INT_LAMBDA_LAMBDA]]([[CAP_TYPE4]]*
150*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[THIS:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
151*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE1:%.+]] = load i{{[0-9]+}}* [[SIZE1_REF]]
152*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
153*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE2:%.+]] = load i{{[0-9]+}}* [[SIZE2_REF]]
154*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
155*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER2_ADDR:%.+]] = load [[INTPTR_T]]** [[BUFFER2_ADDR_REF]]
156*0a6a1f1dSLionel Sambuc // CHECK: [[SIZEOF_BUFFER2:%.+]] = mul {{.*}} i{{[0-9]+}} {{[0-9]+}}, [[SIZE1]]
157*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
158*0a6a1f1dSLionel Sambuc // CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]** [[BUFFER1_ADDR_REF]]
159*0a6a1f1dSLionel Sambuc // CHECK: [[MUL:%.+]] = mul {{.*}} i{{[0-9]+}} [[SIZE2]], [[SIZE1]]
160*0a6a1f1dSLionel Sambuc // CHECK: mul {{.*}} i{{[0-9]+}} {{[0-9]+}}, [[MUL]]
161*0a6a1f1dSLionel Sambuc // CHECK: ret void
162*0a6a1f1dSLionel Sambuc
163*0a6a1f1dSLionel Sambuc // CHECK: void [[F_INT_LAMBDA]]([[CAP_TYPE2]]*
164*0a6a1f1dSLionel Sambuc // CHECK: [[THIS:%.+]] = load [[CAP_TYPE2]]**
165*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]]* [[THIS]], i{{.+}} 0, i{{.+}} 0
166*0a6a1f1dSLionel Sambuc // CHECK: [[SIZE:%.+]] = load [[INTPTR_T]]* [[SIZE_REF]]
167*0a6a1f1dSLionel Sambuc // CHECK: call i{{.+}}* @llvm.stacksave()
168*0a6a1f1dSLionel Sambuc // CHECK: alloca [[INTPTR_T]], [[INTPTR_T]] [[SIZE]]
169*0a6a1f1dSLionel Sambuc // CHECK: call void @llvm.stackrestore(
170*0a6a1f1dSLionel Sambuc // CHECK: ret void
171*0a6a1f1dSLionel Sambuc #endif
172