Mercurial > hg > CbC > CbC_gcc
comparison gcc/testsuite/gcc.dg/builtin-stringop-chk-2.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* This file was miscompiled by an earlier version of the object size | |
2 checking patch. Object size in one of the memcpy calls was | |
3 incorrectly determined to be 0 while it should be (size_t) -1 | |
4 (== unknown). */ | |
5 /* { dg-do compile } */ | |
6 /* { dg-options "-O2 -ftrack-macro-expansion=0" } */ | |
7 | |
8 #include "../gcc.c-torture/execute/builtins/chk.h" | |
9 | |
10 void *bar (int); | |
11 extern void *malloc (__SIZE_TYPE__); | |
12 | |
13 struct A | |
14 { | |
15 int i, j, k; | |
16 }; | |
17 | |
18 /* Here all object sizes are not known at compile time. There | |
19 should be no warning, nor any checker functions called. */ | |
20 | |
21 void | |
22 foo (const struct A *x, int y, const unsigned char *z) | |
23 { | |
24 unsigned int b; | |
25 unsigned char *c = 0; | |
26 | |
27 b = (x->i & 0xff) == 1 ? 3 : 4; | |
28 if (y) | |
29 c = bar (x->j * x->k); | |
30 | |
31 const unsigned char *d = z; | |
32 unsigned char *e = c; | |
33 unsigned char *f = c + x->j * x->k; | |
34 int g = 0; | |
35 | |
36 while (e < f) | |
37 { | |
38 unsigned int h = *d++; | |
39 | |
40 if (h & 128) | |
41 { | |
42 h = h - 128; | |
43 g = e + h * b > f; | |
44 if (g) | |
45 h = (f - e) / b; | |
46 if (b < 4) | |
47 do | |
48 { | |
49 memcpy (e, d, 3); | |
50 e += 3; | |
51 } | |
52 while (--h); | |
53 else | |
54 do | |
55 { | |
56 memcpy (e, d, 4); | |
57 e += 4; | |
58 } | |
59 while (--h); | |
60 d += b; | |
61 } | |
62 else | |
63 { | |
64 h *= b; | |
65 g = e + h > f; | |
66 if (g) | |
67 h = f - e; | |
68 memcpy (e, d, h); | |
69 e += h; | |
70 d += h; | |
71 } | |
72 } | |
73 } | |
74 | |
75 /* The same routine, slightly modified: | |
76 1) c has known size at compile time | |
77 2) e += h was changed into e += 16. | |
78 GCC could actually through VRP determine that | |
79 in e += h is (h >= 0 && h <= 127), thus know | |
80 it is pointer addition and not subtraction and | |
81 know e's __builtin_object_size (e, 0) is at 512, | |
82 but we are not there yet. */ | |
83 | |
84 unsigned char * | |
85 baz (const struct A *x, const unsigned char *z) | |
86 { | |
87 unsigned int b; | |
88 unsigned char *c = 0; | |
89 | |
90 b = (x->i & 0xff) == 1 ? 3 : 4; | |
91 c = malloc (512); | |
92 | |
93 const unsigned char *d = z; | |
94 unsigned char *e = c; | |
95 unsigned char *f = c + x->j * x->k; | |
96 int g = 0; | |
97 | |
98 while (e < f) | |
99 { | |
100 unsigned int h = *d++; | |
101 | |
102 if (h & 128) | |
103 { | |
104 h = h - 128; | |
105 g = e + h * b > f; | |
106 if (g) | |
107 h = (f - e) / b; | |
108 if (b < 4) | |
109 do | |
110 { | |
111 memcpy (e, d, 3); | |
112 e += 3; | |
113 } | |
114 while (--h); | |
115 else | |
116 do | |
117 { | |
118 memcpy (e, d, 513); /* { dg-warning "writing" "memcpy" } */ | |
119 e += 4; | |
120 } | |
121 while (--h); | |
122 d += b; | |
123 } | |
124 else | |
125 { | |
126 h *= b; | |
127 g = e + h > f; | |
128 if (g) | |
129 h = f - e; | |
130 memcpy (e, d, h); | |
131 /* e += h; */ | |
132 e += 16; | |
133 d += h; | |
134 } | |
135 } | |
136 return c; | |
137 } |