xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGen/object-size.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
2*f4a2713aSLionel Sambuc 
3*f4a2713aSLionel Sambuc #define strcpy(dest, src) \
4*f4a2713aSLionel Sambuc   ((__builtin_object_size(dest, 0) != -1ULL) \
5*f4a2713aSLionel Sambuc    ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \
6*f4a2713aSLionel Sambuc    : __inline_strcpy_chk(dest, src))
7*f4a2713aSLionel Sambuc 
__inline_strcpy_chk(char * dest,const char * src)8*f4a2713aSLionel Sambuc static char *__inline_strcpy_chk (char *dest, const char *src) {
9*f4a2713aSLionel Sambuc   return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1));
10*f4a2713aSLionel Sambuc }
11*f4a2713aSLionel Sambuc 
12*f4a2713aSLionel Sambuc char gbuf[63];
13*f4a2713aSLionel Sambuc char *gp;
14*f4a2713aSLionel Sambuc int gi, gj;
15*f4a2713aSLionel Sambuc 
16*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test1
test1()17*f4a2713aSLionel Sambuc void test1() {
18*f4a2713aSLionel Sambuc   // CHECK:     = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 4), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 59)
19*f4a2713aSLionel Sambuc   strcpy(&gbuf[4], "Hi there");
20*f4a2713aSLionel Sambuc }
21*f4a2713aSLionel Sambuc 
22*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test2
test2()23*f4a2713aSLionel Sambuc void test2() {
24*f4a2713aSLionel Sambuc   // CHECK:     = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 63)
25*f4a2713aSLionel Sambuc   strcpy(gbuf, "Hi there");
26*f4a2713aSLionel Sambuc }
27*f4a2713aSLionel Sambuc 
28*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test3
test3()29*f4a2713aSLionel Sambuc void test3() {
30*f4a2713aSLionel Sambuc   // CHECK:     = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i64 1, i64 37), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0)
31*f4a2713aSLionel Sambuc   strcpy(&gbuf[100], "Hi there");
32*f4a2713aSLionel Sambuc }
33*f4a2713aSLionel Sambuc 
34*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test4
test4()35*f4a2713aSLionel Sambuc void test4() {
36*f4a2713aSLionel Sambuc   // CHECK:     = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 -1), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0)
37*f4a2713aSLionel Sambuc   strcpy((char*)(void*)&gbuf[-1], "Hi there");
38*f4a2713aSLionel Sambuc }
39*f4a2713aSLionel Sambuc 
40*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test5
test5()41*f4a2713aSLionel Sambuc void test5() {
42*f4a2713aSLionel Sambuc   // CHECK:     = load i8** @gp
43*f4a2713aSLionel Sambuc   // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
44*f4a2713aSLionel Sambuc   strcpy(gp, "Hi there");
45*f4a2713aSLionel Sambuc }
46*f4a2713aSLionel Sambuc 
47*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test6
test6()48*f4a2713aSLionel Sambuc void test6() {
49*f4a2713aSLionel Sambuc   char buf[57];
50*f4a2713aSLionel Sambuc 
51*f4a2713aSLionel Sambuc   // CHECK:       = call i8* @__strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 53)
52*f4a2713aSLionel Sambuc   strcpy(&buf[4], "Hi there");
53*f4a2713aSLionel Sambuc }
54*f4a2713aSLionel Sambuc 
55*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test7
test7()56*f4a2713aSLionel Sambuc void test7() {
57*f4a2713aSLionel Sambuc   int i;
58*f4a2713aSLionel Sambuc   // Ensure we only evaluate the side-effect once.
59*f4a2713aSLionel Sambuc   // CHECK:     = add
60*f4a2713aSLionel Sambuc   // CHECK-NOT: = add
61*f4a2713aSLionel Sambuc   // CHECK:     = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 63)
62*f4a2713aSLionel Sambuc   strcpy((++i, gbuf), "Hi there");
63*f4a2713aSLionel Sambuc }
64*f4a2713aSLionel Sambuc 
65*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test8
test8()66*f4a2713aSLionel Sambuc void test8() {
67*f4a2713aSLionel Sambuc   char *buf[50];
68*f4a2713aSLionel Sambuc   // CHECK-NOT:   __strcpy_chk
69*f4a2713aSLionel Sambuc   // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
70*f4a2713aSLionel Sambuc   strcpy(buf[++gi], "Hi there");
71*f4a2713aSLionel Sambuc }
72*f4a2713aSLionel Sambuc 
73*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test9
test9()74*f4a2713aSLionel Sambuc void test9() {
75*f4a2713aSLionel Sambuc   // CHECK-NOT:   __strcpy_chk
76*f4a2713aSLionel Sambuc   // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
77*f4a2713aSLionel Sambuc   strcpy((char *)((++gi) + gj), "Hi there");
78*f4a2713aSLionel Sambuc }
79*f4a2713aSLionel Sambuc 
80*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test10
81*f4a2713aSLionel Sambuc char **p;
test10()82*f4a2713aSLionel Sambuc void test10() {
83*f4a2713aSLionel Sambuc   // CHECK-NOT:   __strcpy_chk
84*f4a2713aSLionel Sambuc   // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
85*f4a2713aSLionel Sambuc   strcpy(*(++p), "Hi there");
86*f4a2713aSLionel Sambuc }
87*f4a2713aSLionel Sambuc 
88*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test11
test11()89*f4a2713aSLionel Sambuc void test11() {
90*f4a2713aSLionel Sambuc   // CHECK-NOT:   __strcpy_chk
91*f4a2713aSLionel Sambuc   // CHECK:       = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
92*f4a2713aSLionel Sambuc   strcpy(gp = gbuf, "Hi there");
93*f4a2713aSLionel Sambuc }
94*f4a2713aSLionel Sambuc 
95*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test12
test12()96*f4a2713aSLionel Sambuc void test12() {
97*f4a2713aSLionel Sambuc   // CHECK-NOT:   __strcpy_chk
98*f4a2713aSLionel Sambuc   // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
99*f4a2713aSLionel Sambuc   strcpy(++gp, "Hi there");
100*f4a2713aSLionel Sambuc }
101*f4a2713aSLionel Sambuc 
102*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test13
test13()103*f4a2713aSLionel Sambuc void test13() {
104*f4a2713aSLionel Sambuc   // CHECK-NOT:   __strcpy_chk
105*f4a2713aSLionel Sambuc   // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
106*f4a2713aSLionel Sambuc   strcpy(gp++, "Hi there");
107*f4a2713aSLionel Sambuc }
108*f4a2713aSLionel Sambuc 
109*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test14
test14()110*f4a2713aSLionel Sambuc void test14() {
111*f4a2713aSLionel Sambuc   // CHECK-NOT:   __strcpy_chk
112*f4a2713aSLionel Sambuc   // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
113*f4a2713aSLionel Sambuc   strcpy(--gp, "Hi there");
114*f4a2713aSLionel Sambuc }
115*f4a2713aSLionel Sambuc 
116*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test15
test15()117*f4a2713aSLionel Sambuc void test15() {
118*f4a2713aSLionel Sambuc   // CHECK-NOT:   __strcpy_chk
119*f4a2713aSLionel Sambuc   // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{..*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
120*f4a2713aSLionel Sambuc   strcpy(gp--, "Hi there");
121*f4a2713aSLionel Sambuc }
122*f4a2713aSLionel Sambuc 
123*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test16
test16()124*f4a2713aSLionel Sambuc void test16() {
125*f4a2713aSLionel Sambuc   // CHECK-NOT:   __strcpy_chk
126*f4a2713aSLionel Sambuc   // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
127*f4a2713aSLionel Sambuc   strcpy(gp += 1, "Hi there");
128*f4a2713aSLionel Sambuc }
129*f4a2713aSLionel Sambuc 
130*f4a2713aSLionel Sambuc // CHECK: @test17
test17()131*f4a2713aSLionel Sambuc void test17() {
132*f4a2713aSLionel Sambuc   // CHECK: store i32 -1
133*f4a2713aSLionel Sambuc   gi = __builtin_object_size(gp++, 0);
134*f4a2713aSLionel Sambuc   // CHECK: store i32 -1
135*f4a2713aSLionel Sambuc   gi = __builtin_object_size(gp++, 1);
136*f4a2713aSLionel Sambuc   // CHECK: store i32 0
137*f4a2713aSLionel Sambuc   gi = __builtin_object_size(gp++, 2);
138*f4a2713aSLionel Sambuc   // CHECK: store i32 0
139*f4a2713aSLionel Sambuc   gi = __builtin_object_size(gp++, 3);
140*f4a2713aSLionel Sambuc }
141*f4a2713aSLionel Sambuc 
142*f4a2713aSLionel Sambuc // CHECK: @test18
test18(int cond)143*f4a2713aSLionel Sambuc unsigned test18(int cond) {
144*f4a2713aSLionel Sambuc   int a[4], b[4];
145*f4a2713aSLionel Sambuc   // CHECK: phi i32*
146*f4a2713aSLionel Sambuc   // CHECK: call i64 @llvm.objectsize.i64
147*f4a2713aSLionel Sambuc   return __builtin_object_size(cond ? a : b, 0);
148*f4a2713aSLionel Sambuc }
149