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