111
|
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 }
|