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