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