Add the IR attribute 'sspstrong'.
[oota-llvm.git] / test / CodeGen / X86 / stack-protector.ll
1 ; RUN: llc -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-I386 %s
2 ; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-X64 %s
3 ; RUN: llc -code-model=kernel -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-KERNEL-X64 %s
4 ; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | FileCheck --check-prefix=DARWIN-X64 %s
5 ; FIXME: Update and expand test when strong heuristic is implemented.
6
7 %struct.foo = type { [16 x i8] }
8 %struct.foo.0 = type { [4 x i8] }
9
10 @.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
11
12 ; test1a: array of [16 x i8] 
13 ;         no ssp attribute
14 ; Requires no protector.
15 define void @test1a(i8* %a) nounwind uwtable {
16 entry:
17 ; LINUX-I386: test1a:
18 ; LINUX-I386-NOT: calll __stack_chk_fail
19 ; LINUX-I386: .cfi_endproc
20
21 ; LINUX-X64: test1a:
22 ; LINUX-X64-NOT: callq __stack_chk_fail
23 ; LINUX-X64: .cfi_endproc
24
25 ; LINUX-KERNEL-X64: test1a:
26 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
27 ; LINUX-KERNEL-X64: .cfi_endproc
28
29 ; DARWIN-X64: test1a:
30 ; DARWIN-X64-NOT: callq ___stack_chk_fail
31 ; DARWIN-X64: .cfi_endproc
32   %a.addr = alloca i8*, align 8
33   %buf = alloca [16 x i8], align 16
34   store i8* %a, i8** %a.addr, align 8
35   %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
36   %0 = load i8** %a.addr, align 8
37   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
38   %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
39   %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
40   ret void
41 }
42
43 ; test1b: array of [16 x i8] 
44 ;         ssp attribute
45 ; Requires protector.
46 define void @test1b(i8* %a) nounwind uwtable ssp {
47 entry:
48 ; LINUX-I386: test1b:
49 ; LINUX-I386: mov{{l|q}} %gs:
50 ; LINUX-I386: calll __stack_chk_fail
51
52 ; LINUX-X64: test1b:
53 ; LINUX-X64: mov{{l|q}} %fs:
54 ; LINUX-X64: callq __stack_chk_fail
55
56 ; LINUX-KERNEL-X64: test1b:
57 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
58 ; LINUX-KERNEL-X64: callq __stack_chk_fail
59
60 ; DARWIN-X64: test1b:
61 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
62 ; DARWIN-X64: callq ___stack_chk_fail
63   %a.addr = alloca i8*, align 8
64   %buf = alloca [16 x i8], align 16
65   store i8* %a, i8** %a.addr, align 8
66   %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
67   %0 = load i8** %a.addr, align 8
68   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
69   %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
70   %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
71   ret void
72 }
73
74 ; test1c: array of [16 x i8] 
75 ;         sspstrong attribute
76 ; Requires protector.
77 define void @test1c(i8* %a) nounwind uwtable sspstrong {
78 entry:
79 ; LINUX-I386: test1c:
80 ; LINUX-I386: mov{{l|q}} %gs:
81 ; LINUX-I386: calll __stack_chk_fail
82
83 ; LINUX-X64: test1c:
84 ; LINUX-X64: mov{{l|q}} %fs:
85 ; LINUX-X64: callq __stack_chk_fail
86
87 ; LINUX-KERNEL-X64: test1c:
88 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
89 ; LINUX-KERNEL-X64: callq __stack_chk_fail
90
91 ; DARWIN-X64: test1c:
92 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
93 ; DARWIN-X64: callq ___stack_chk_fail
94   %a.addr = alloca i8*, align 8
95   %buf = alloca [16 x i8], align 16
96   store i8* %a, i8** %a.addr, align 8
97   %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
98   %0 = load i8** %a.addr, align 8
99   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
100   %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
101   %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
102   ret void
103 }
104
105 ; test1d: array of [16 x i8] 
106 ;         sspreq attribute
107 ; Requires protector.
108 define void @test1d(i8* %a) nounwind uwtable sspreq {
109 entry:
110 ; LINUX-I386: test1d:
111 ; LINUX-I386: mov{{l|q}} %gs:
112 ; LINUX-I386: calll __stack_chk_fail
113
114 ; LINUX-X64: test1d:
115 ; LINUX-X64: mov{{l|q}} %fs:
116 ; LINUX-X64: callq __stack_chk_fail
117
118 ; LINUX-KERNEL-X64: test1d:
119 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
120 ; LINUX-KERNEL-X64: callq __stack_chk_fail
121
122 ; DARWIN-X64: test1d:
123 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
124 ; DARWIN-X64: callq ___stack_chk_fail
125   %a.addr = alloca i8*, align 8
126   %buf = alloca [16 x i8], align 16
127   store i8* %a, i8** %a.addr, align 8
128   %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
129   %0 = load i8** %a.addr, align 8
130   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
131   %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
132   %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
133   ret void
134 }
135
136 ; test2a: struct { [16 x i8] }
137 ;         no ssp attribute
138 ; Requires no protector.
139 define void @test2a(i8* %a) nounwind uwtable {
140 entry:
141 ; LINUX-I386: test2a:
142 ; LINUX-I386-NOT: calll __stack_chk_fail
143 ; LINUX-I386: .cfi_endproc
144
145 ; LINUX-X64: test2a:
146 ; LINUX-X64-NOT: callq __stack_chk_fail
147 ; LINUX-X64: .cfi_endproc
148
149 ; LINUX-KERNEL-X64: test2a:
150 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
151 ; LINUX-KERNEL-X64: .cfi_endproc
152
153 ; DARWIN-X64: test2a:
154 ; DARWIN-X64-NOT: callq ___stack_chk_fail
155 ; DARWIN-X64: .cfi_endproc
156   %a.addr = alloca i8*, align 8
157   %b = alloca %struct.foo, align 1
158   store i8* %a, i8** %a.addr, align 8
159   %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
160   %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
161   %0 = load i8** %a.addr, align 8
162   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
163   %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
164   %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0
165   %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
166   ret void
167 }
168
169 ; test2b: struct { [16 x i8] }
170 ;          ssp attribute
171 ; Requires protector.
172 define void @test2b(i8* %a) nounwind uwtable ssp {
173 entry:
174 ; LINUX-I386: test2b:
175 ; LINUX-I386: mov{{l|q}} %gs:
176 ; LINUX-I386: calll __stack_chk_fail
177
178 ; LINUX-X64: test2b:
179 ; LINUX-X64: mov{{l|q}} %fs:
180 ; LINUX-X64: callq __stack_chk_fail
181
182 ; LINUX-KERNEL-X64: test2b:
183 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
184 ; LINUX-KERNEL-X64: callq __stack_chk_fail
185
186 ; DARWIN-X64: test2b:
187 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
188 ; DARWIN-X64: callq ___stack_chk_fail
189   %a.addr = alloca i8*, align 8
190   %b = alloca %struct.foo, align 1
191   store i8* %a, i8** %a.addr, align 8
192   %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
193   %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
194   %0 = load i8** %a.addr, align 8
195   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
196   %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
197   %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0
198   %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
199   ret void
200 }
201
202 ; test2c: struct { [16 x i8] }
203 ;          sspstrong attribute
204 ; Requires protector.
205 define void @test2c(i8* %a) nounwind uwtable sspstrong {
206 entry:
207 ; LINUX-I386: test2c:
208 ; LINUX-I386: mov{{l|q}} %gs:
209 ; LINUX-I386: calll __stack_chk_fail
210
211 ; LINUX-X64: test2c:
212 ; LINUX-X64: mov{{l|q}} %fs:
213 ; LINUX-X64: callq __stack_chk_fail
214
215 ; LINUX-KERNEL-X64: test2c:
216 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
217 ; LINUX-KERNEL-X64: callq __stack_chk_fail
218
219 ; DARWIN-X64: test2c:
220 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
221 ; DARWIN-X64: callq ___stack_chk_fail
222   %a.addr = alloca i8*, align 8
223   %b = alloca %struct.foo, align 1
224   store i8* %a, i8** %a.addr, align 8
225   %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
226   %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
227   %0 = load i8** %a.addr, align 8
228   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
229   %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
230   %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0
231   %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
232   ret void
233 }
234
235 ; test2d: struct { [16 x i8] }
236 ;          sspreq attribute
237 ; Requires protector.
238 define void @test2d(i8* %a) nounwind uwtable sspreq {
239 entry:
240 ; LINUX-I386: test2d:
241 ; LINUX-I386: mov{{l|q}} %gs:
242 ; LINUX-I386: calll __stack_chk_fail
243
244 ; LINUX-X64: test2d:
245 ; LINUX-X64: mov{{l|q}} %fs:
246 ; LINUX-X64: callq __stack_chk_fail
247
248 ; LINUX-KERNEL-X64: test2d:
249 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
250 ; LINUX-KERNEL-X64: callq __stack_chk_fail
251
252 ; DARWIN-X64: test2d:
253 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
254 ; DARWIN-X64: callq ___stack_chk_fail
255   %a.addr = alloca i8*, align 8
256   %b = alloca %struct.foo, align 1
257   store i8* %a, i8** %a.addr, align 8
258   %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
259   %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
260   %0 = load i8** %a.addr, align 8
261   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
262   %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
263   %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0
264   %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
265   ret void
266 }
267
268 ; test3a:  array of [4 x i8]
269 ;          no ssp attribute
270 ; Requires no protector.
271 define void @test3a(i8* %a) nounwind uwtable {
272 entry:
273 ; LINUX-I386: test3a:
274 ; LINUX-I386-NOT: calll __stack_chk_fail
275 ; LINUX-I386: .cfi_endproc
276
277 ; LINUX-X64: test3a:
278 ; LINUX-X64-NOT: callq __stack_chk_fail
279 ; LINUX-X64: .cfi_endproc
280
281 ; LINUX-KERNEL-X64: test3a:
282 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
283 ; LINUX-KERNEL-X64: .cfi_endproc
284
285 ; DARWIN-X64: test3a:
286 ; DARWIN-X64-NOT: callq ___stack_chk_fail
287 ; DARWIN-X64: .cfi_endproc
288   %a.addr = alloca i8*, align 8
289   %buf = alloca [4 x i8], align 1
290   store i8* %a, i8** %a.addr, align 8
291   %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
292   %0 = load i8** %a.addr, align 8
293   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
294   %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
295   %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
296   ret void
297 }
298
299 ; test3b:  array [4 x i8]
300 ;          ssp attribute
301 ; Requires no protector.
302 define void @test3b(i8* %a) nounwind uwtable ssp {
303 entry:
304 ; LINUX-I386: test3b:
305 ; LINUX-I386-NOT: calll __stack_chk_fail
306 ; LINUX-I386: .cfi_endproc
307
308 ; LINUX-X64: test3b:
309 ; LINUX-X64-NOT: callq __stack_chk_fail
310 ; LINUX-X64: .cfi_endproc
311
312 ; LINUX-KERNEL-X64: test3b:
313 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
314 ; LINUX-KERNEL-X64: .cfi_endproc
315
316 ; DARWIN-X64: test3b:
317 ; DARWIN-X64-NOT: callq ___stack_chk_fail
318 ; DARWIN-X64: .cfi_endproc
319   %a.addr = alloca i8*, align 8
320   %buf = alloca [4 x i8], align 1
321   store i8* %a, i8** %a.addr, align 8
322   %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
323   %0 = load i8** %a.addr, align 8
324   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
325   %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
326   %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
327   ret void
328 }
329
330 ; test3c:  array of [4 x i8]
331 ;          sspstrong attribute
332 ; Requires protector.
333 define void @test3c(i8* %a) nounwind uwtable sspstrong {
334 entry:
335 ; LINUX-I386: test3c:
336 ; LINUX-I386: mov{{l|q}} %gs:
337 ; LINUX-I386: calll __stack_chk_fail
338
339 ; LINUX-X64: test3c:
340 ; LINUX-X64: mov{{l|q}} %fs:
341 ; LINUX-X64: callq __stack_chk_fail
342
343 ; LINUX-KERNEL-X64: test3c:
344 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
345 ; LINUX-KERNEL-X64: callq __stack_chk_fail
346
347 ; DARWIN-X64: test3c:
348 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
349 ; DARWIN-X64: callq ___stack_chk_fail
350   %a.addr = alloca i8*, align 8
351   %buf = alloca [4 x i8], align 1
352   store i8* %a, i8** %a.addr, align 8
353   %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
354   %0 = load i8** %a.addr, align 8
355   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
356   %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
357   %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
358   ret void
359 }
360
361 ; test3d:  array of [4 x i8]
362 ;          sspreq attribute
363 ; Requires protector.
364 define void @test3d(i8* %a) nounwind uwtable sspreq {
365 entry:
366 ; LINUX-I386: test3d:
367 ; LINUX-I386: mov{{l|q}} %gs:
368 ; LINUX-I386: calll __stack_chk_fail
369
370 ; LINUX-X64: test3d:
371 ; LINUX-X64: mov{{l|q}} %fs:
372 ; LINUX-X64: callq __stack_chk_fail
373
374 ; LINUX-KERNEL-X64: test3d:
375 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
376 ; LINUX-KERNEL-X64: callq __stack_chk_fail
377
378 ; DARWIN-X64: test3d:
379 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
380 ; DARWIN-X64: callq ___stack_chk_fail
381   %a.addr = alloca i8*, align 8
382   %buf = alloca [4 x i8], align 1
383   store i8* %a, i8** %a.addr, align 8
384   %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
385   %0 = load i8** %a.addr, align 8
386   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
387   %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
388   %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
389   ret void
390 }
391
392 ; test4a:  struct { [4 x i8] }
393 ;          no ssp attribute
394 ; Requires no protector.
395 define void @test4a(i8* %a) nounwind uwtable {
396 entry:
397 ; LINUX-I386: test4a:
398 ; LINUX-I386-NOT: calll __stack_chk_fail
399 ; LINUX-I386: .cfi_endproc
400
401 ; LINUX-X64: test4a:
402 ; LINUX-X64-NOT: callq __stack_chk_fail
403 ; LINUX-X64: .cfi_endproc
404
405 ; LINUX-KERNEL-X64: test4a:
406 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
407 ; LINUX-KERNEL-X64: .cfi_endproc
408
409 ; DARWIN-X64: test4a:
410 ; DARWIN-X64-NOT: callq ___stack_chk_fail
411 ; DARWIN-X64: .cfi_endproc
412   %a.addr = alloca i8*, align 8
413   %b = alloca %struct.foo.0, align 1
414   store i8* %a, i8** %a.addr, align 8
415   %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
416   %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
417   %0 = load i8** %a.addr, align 8
418   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
419   %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
420   %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0
421   %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
422   ret void
423 }
424
425 ; test4b:  struct { [4 x i8] }
426 ;          ssp attribute
427 ; Requires no protector.
428 define void @test4b(i8* %a) nounwind uwtable ssp {
429 entry:
430 ; LINUX-I386: test4b:
431 ; LINUX-I386-NOT: calll __stack_chk_fail
432 ; LINUX-I386: .cfi_endproc
433
434 ; LINUX-X64: test4b:
435 ; LINUX-X64-NOT: callq __stack_chk_fail
436 ; LINUX-X64: .cfi_endproc
437
438 ; LINUX-KERNEL-X64: test4b:
439 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
440 ; LINUX-KERNEL-X64: .cfi_endproc
441
442 ; DARWIN-X64: test4b:
443 ; DARWIN-X64-NOT: callq ___stack_chk_fail
444 ; DARWIN-X64: .cfi_endproc
445   %a.addr = alloca i8*, align 8
446   %b = alloca %struct.foo.0, align 1
447   store i8* %a, i8** %a.addr, align 8
448   %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
449   %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
450   %0 = load i8** %a.addr, align 8
451   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
452   %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
453   %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0
454   %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
455   ret void
456 }
457
458 ; test4c:  struct { [4 x i8] }
459 ;          sspstrong attribute
460 ; Requires protector.
461 define void @test4c(i8* %a) nounwind uwtable sspstrong {
462 entry:
463 ; LINUX-I386: test4c:
464 ; LINUX-I386: mov{{l|q}} %gs:
465 ; LINUX-I386: calll __stack_chk_fail
466
467 ; LINUX-X64: test4c:
468 ; LINUX-X64: mov{{l|q}} %fs:
469 ; LINUX-X64: callq __stack_chk_fail
470
471 ; LINUX-KERNEL-X64: test4c:
472 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
473 ; LINUX-KERNEL-X64: callq __stack_chk_fail
474
475 ; DARWIN-X64: test4c:
476 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
477 ; DARWIN-X64: callq ___stack_chk_fail
478   %a.addr = alloca i8*, align 8
479   %b = alloca %struct.foo.0, align 1
480   store i8* %a, i8** %a.addr, align 8
481   %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
482   %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
483   %0 = load i8** %a.addr, align 8
484   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
485   %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
486   %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0
487   %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
488   ret void
489 }
490
491 ; test4d:  struct { [4 x i8] }
492 ;          sspreq attribute
493 ; Requires protector.
494 define void @test4d(i8* %a) nounwind uwtable sspreq {
495 entry:
496 ; LINUX-I386: test4d:
497 ; LINUX-I386: mov{{l|q}} %gs:
498 ; LINUX-I386: calll __stack_chk_fail
499
500 ; LINUX-X64: test4d:
501 ; LINUX-X64: mov{{l|q}} %fs:
502 ; LINUX-X64: callq __stack_chk_fail
503
504 ; LINUX-KERNEL-X64: test4d:
505 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
506 ; LINUX-KERNEL-X64: callq __stack_chk_fail
507
508 ; DARWIN-X64: test4d:
509 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
510 ; DARWIN-X64: callq ___stack_chk_fail
511   %a.addr = alloca i8*, align 8
512   %b = alloca %struct.foo.0, align 1
513   store i8* %a, i8** %a.addr, align 8
514   %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
515   %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
516   %0 = load i8** %a.addr, align 8
517   %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
518   %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
519   %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0
520   %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
521   ret void
522 }
523
524 ; test5a:  no arrays / no nested arrays
525 ;          no ssp attribute
526 ; Requires no protector.
527 define void @test5a(i8* %a) nounwind uwtable {
528 entry:
529 ; LINUX-I386: test5a:
530 ; LINUX-I386-NOT: calll __stack_chk_fail
531 ; LINUX-I386: .cfi_endproc
532
533 ; LINUX-X64: test5a:
534 ; LINUX-X64-NOT: callq __stack_chk_fail
535 ; LINUX-X64: .cfi_endproc
536
537 ; LINUX-KERNEL-X64: test5a:
538 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
539 ; LINUX-KERNEL-X64: .cfi_endproc
540
541 ; DARWIN-X64: test5a:
542 ; DARWIN-X64-NOT: callq ___stack_chk_fail
543 ; DARWIN-X64: .cfi_endproc
544   %a.addr = alloca i8*, align 8
545   store i8* %a, i8** %a.addr, align 8
546   %0 = load i8** %a.addr, align 8
547   %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0)
548   ret void
549 }
550
551 ; test5b:  no arrays / no nested arrays
552 ;          ssp attribute
553 ; Requires no protector.
554 define void @test5b(i8* %a) nounwind uwtable ssp {
555 entry:
556 ; LINUX-I386: test5b:
557 ; LINUX-I386-NOT: calll __stack_chk_fail
558 ; LINUX-I386: .cfi_endproc
559
560 ; LINUX-X64: test5b:
561 ; LINUX-X64-NOT: callq __stack_chk_fail
562 ; LINUX-X64: .cfi_endproc
563
564 ; LINUX-KERNEL-X64: test5b:
565 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
566 ; LINUX-KERNEL-X64: .cfi_endproc
567
568 ; DARWIN-X64: test5b:
569 ; DARWIN-X64-NOT: callq ___stack_chk_fail
570 ; DARWIN-X64: .cfi_endproc
571   %a.addr = alloca i8*, align 8
572   store i8* %a, i8** %a.addr, align 8
573   %0 = load i8** %a.addr, align 8
574   %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0)
575   ret void
576 }
577
578 ; test5c:  no arrays / no nested arrays
579 ;          sspstrong attribute
580 ; Requires protector.
581 ; FIXME: Once strong heuristic is implemented, this should _not_ require
582 ;        a protector
583 define void @test5c(i8* %a) nounwind uwtable sspstrong {
584 entry:
585 ; LINUX-I386: test5c:
586 ; LINUX-I386: mov{{l|q}} %gs:
587 ; LINUX-I386: calll __stack_chk_fail
588
589 ; LINUX-X64: test5c:
590 ; LINUX-X64: mov{{l|q}} %fs:
591 ; LINUX-X64: callq __stack_chk_fail
592
593 ; LINUX-KERNEL-X64: test5c:
594 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
595 ; LINUX-KERNEL-X64: callq __stack_chk_fail
596
597 ; DARWIN-X64: test5c:
598 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
599 ; DARWIN-X64: callq ___stack_chk_fail
600   %a.addr = alloca i8*, align 8
601   store i8* %a, i8** %a.addr, align 8
602   %0 = load i8** %a.addr, align 8
603   %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0)
604   ret void
605 }
606
607 ; test5d:  no arrays / no nested arrays
608 ;          sspreq attribute
609 ; Requires protector.
610 define void @test5d(i8* %a) nounwind uwtable sspreq {
611 entry:
612 ; LINUX-I386: test5d:
613 ; LINUX-I386: mov{{l|q}} %gs:
614 ; LINUX-I386: calll __stack_chk_fail
615
616 ; LINUX-X64: test5d:
617 ; LINUX-X64: mov{{l|q}} %fs:
618 ; LINUX-X64: callq __stack_chk_fail
619
620 ; LINUX-KERNEL-X64: test5d:
621 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
622 ; LINUX-KERNEL-X64: callq __stack_chk_fail
623
624 ; DARWIN-X64: test5d:
625 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
626 ; DARWIN-X64: callq ___stack_chk_fail
627   %a.addr = alloca i8*, align 8
628   store i8* %a, i8** %a.addr, align 8
629   %0 = load i8** %a.addr, align 8
630   %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0)
631   ret void
632 }
633
634 declare i8* @strcpy(i8*, i8*)
635 declare i32 @printf(i8*, ...)