tree-object-size.c (addr_object_size): Add OSI argument.
* tree-object-size.c (addr_object_size): Add OSI argument. Handle also INDIRECT_REF with SSA_NAME inside of it as base address. (compute_builtin_object_size, expr_object_size): Adjust callers. (plus_stmt_object_size): Call addr_object_size instead of compute_builtin_object_size. * gcc.dg/builtin-object-size-2.c (test1): Adjust expected results. * gcc.dg/builtin-object-size-4.c (test1): Adjust expected results. * gcc.dg/builtin-object-size-6.c: New test. From-SVN: r148279
This commit is contained in:
parent
85a988d14e
commit
eb9ed98a95
6 changed files with 620 additions and 60 deletions
|
@ -1,3 +1,11 @@
|
|||
2009-06-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* tree-object-size.c (addr_object_size): Add OSI argument.
|
||||
Handle also INDIRECT_REF with SSA_NAME inside of it as base address.
|
||||
(compute_builtin_object_size, expr_object_size): Adjust callers.
|
||||
(plus_stmt_object_size): Call addr_object_size instead of
|
||||
compute_builtin_object_size.
|
||||
|
||||
2009-06-08 Ghassan Shobaki <ghassan.shobaki@amd.com>
|
||||
Dwarakanath Rajagopal <dwarak.rajagopal@amd.com>
|
||||
|
||||
|
@ -20,7 +28,6 @@
|
|||
2009-06-08 Michael Matz <matz@suse.de>
|
||||
|
||||
PR debug/40012
|
||||
|
||||
* cfgexpand.c (set_rtl): Store place also in DECL_RTL, if all
|
||||
partitions use the same.
|
||||
(expand_one_var): Deal with DECL_RTL sometimes begin set also
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
2009-06-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.dg/builtin-object-size-2.c (test1): Adjust expected results.
|
||||
* gcc.dg/builtin-object-size-4.c (test1): Adjust expected results.
|
||||
* gcc.dg/builtin-object-size-6.c: New test.
|
||||
|
||||
PR c++/40370
|
||||
PR c++/40372
|
||||
* g++.dg/template/error41.C: New test.
|
||||
|
|
|
@ -130,15 +130,15 @@ test1 (void *q, int x)
|
|||
abort ();
|
||||
if (__builtin_object_size (&vara[5], 1) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&vara[0].a, 1) != (size_t) -1)
|
||||
if (__builtin_object_size (&vara[0].a, 1) != sizeof (vara[0].a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&vara[10].a[0], 1) != (size_t) -1)
|
||||
if (__builtin_object_size (&vara[10].a[0], 1) != sizeof (vara[0].a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&vara[5].a[4], 1) != (size_t) -1)
|
||||
if (__builtin_object_size (&vara[5].a[4], 1) != sizeof (vara[0].a) - 4)
|
||||
abort ();
|
||||
if (__builtin_object_size (&vara[5].b, 1) != (size_t) -1)
|
||||
if (__builtin_object_size (&vara[5].b, 1) != sizeof (vara[0].b))
|
||||
abort ();
|
||||
if (__builtin_object_size (&vara[7].c[7], 1) != (size_t) -1)
|
||||
if (__builtin_object_size (&vara[7].c[7], 1) != sizeof (vara[0].c) - 7)
|
||||
abort ();
|
||||
if (__builtin_object_size (zerol, 1) != 0)
|
||||
abort ();
|
||||
|
|
|
@ -130,15 +130,15 @@ test1 (void *q, int x)
|
|||
abort ();
|
||||
if (__builtin_object_size (&vara[5], 3) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&vara[0].a, 3) != 0)
|
||||
if (__builtin_object_size (&vara[0].a, 3) != sizeof (vara[0].a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&vara[10].a[0], 3) != 0)
|
||||
if (__builtin_object_size (&vara[10].a[0], 3) != sizeof (vara[0].a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&vara[5].a[4], 3) != 0)
|
||||
if (__builtin_object_size (&vara[5].a[4], 3) != sizeof (vara[0].a) - 4)
|
||||
abort ();
|
||||
if (__builtin_object_size (&vara[5].b, 3) != 0)
|
||||
if (__builtin_object_size (&vara[5].b, 3) != sizeof (vara[0].b))
|
||||
abort ();
|
||||
if (__builtin_object_size (&vara[7].c[7], 3) != 0)
|
||||
if (__builtin_object_size (&vara[7].c[7], 3) != sizeof (vara[0].c) - 7)
|
||||
abort ();
|
||||
if (__builtin_object_size (zerol, 3) != 0)
|
||||
abort ();
|
||||
|
|
435
gcc/testsuite/gcc.dg/builtin-object-size-6.c
Normal file
435
gcc/testsuite/gcc.dg/builtin-object-size-6.c
Normal file
|
@ -0,0 +1,435 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
extern void abort (void);
|
||||
extern void exit (int);
|
||||
extern void *malloc (size_t);
|
||||
extern void free (void *);
|
||||
|
||||
struct A
|
||||
{
|
||||
char a[10];
|
||||
int b;
|
||||
char c[10];
|
||||
};
|
||||
|
||||
void
|
||||
__attribute__ ((noinline))
|
||||
test1 (struct A *p)
|
||||
{
|
||||
char *c;
|
||||
if (__builtin_object_size (&p->a, 0) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 0) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 0) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 0) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 0) != (size_t) -1)
|
||||
abort ();
|
||||
c = p->a;
|
||||
if (__builtin_object_size (c, 0) != (size_t) -1)
|
||||
abort ();
|
||||
c = &p->a[0];
|
||||
if (__builtin_object_size (c, 0) != (size_t) -1)
|
||||
abort ();
|
||||
c = &p->a[3];
|
||||
if (__builtin_object_size (c, 0) != (size_t) -1)
|
||||
abort ();
|
||||
c = (char *) &p->b;
|
||||
if (__builtin_object_size (c, 0) != (size_t) -1)
|
||||
abort ();
|
||||
c = (char *) &p->c;
|
||||
if (__builtin_object_size (c, 0) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 1) != (size_t) -1)
|
||||
abort ();
|
||||
c = p->a;
|
||||
if (__builtin_object_size (c, 1) != sizeof (p->a))
|
||||
abort ();
|
||||
c = &p->a[0];
|
||||
if (__builtin_object_size (c, 1) != sizeof (p->a))
|
||||
abort ();
|
||||
c = &p->a[3];
|
||||
if (__builtin_object_size (c, 1) != sizeof (p->a) - 3)
|
||||
abort ();
|
||||
c = (char *) &p->b;
|
||||
if (__builtin_object_size (c, 1) != sizeof (p->b))
|
||||
abort ();
|
||||
c = (char *) &p->c;
|
||||
if (__builtin_object_size (c, 1) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a, 2) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 2) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 2) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 2) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 2) != 0)
|
||||
abort ();
|
||||
c = p->a;
|
||||
if (__builtin_object_size (c, 2) != 0)
|
||||
abort ();
|
||||
c = &p->a[0];
|
||||
if (__builtin_object_size (c, 2) != 0)
|
||||
abort ();
|
||||
c = &p->a[3];
|
||||
if (__builtin_object_size (c, 2) != 0)
|
||||
abort ();
|
||||
c = (char *) &p->b;
|
||||
if (__builtin_object_size (c, 2) != 0)
|
||||
abort ();
|
||||
c = (char *) &p->c;
|
||||
if (__builtin_object_size (c, 2) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a, 3) != sizeof (p->a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 3) != sizeof (p->b))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 3) != 0)
|
||||
abort ();
|
||||
c = p->a;
|
||||
if (__builtin_object_size (c, 3) != sizeof (p->a))
|
||||
abort ();
|
||||
c = &p->a[0];
|
||||
if (__builtin_object_size (c, 3) != sizeof (p->a))
|
||||
abort ();
|
||||
c = &p->a[3];
|
||||
if (__builtin_object_size (c, 3) != sizeof (p->a) - 3)
|
||||
abort ();
|
||||
c = (char *) &p->b;
|
||||
if (__builtin_object_size (c, 3) != sizeof (p->b))
|
||||
abort ();
|
||||
c = (char *) &p->c;
|
||||
if (__builtin_object_size (c, 3) != 0)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
__attribute__ ((noinline))
|
||||
test2 (void)
|
||||
{
|
||||
char *c;
|
||||
size_t s = 2 * sizeof (struct A);
|
||||
struct A *p = malloc (2 * sizeof (struct A));
|
||||
if (__builtin_object_size (&p->a, 0) != s)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 0) != s)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 0) != s - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (struct A, b))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 0) != s - __builtin_offsetof (struct A, c))
|
||||
abort ();
|
||||
c = p->a;
|
||||
if (__builtin_object_size (c, 0) != s)
|
||||
abort ();
|
||||
c = &p->a[0];
|
||||
if (__builtin_object_size (c, 0) != s)
|
||||
abort ();
|
||||
c = &p->a[3];
|
||||
if (__builtin_object_size (c, 0) != s - 3)
|
||||
abort ();
|
||||
c = (char *) &p->b;
|
||||
if (__builtin_object_size (c, 0) != s - __builtin_offsetof (struct A, b))
|
||||
abort ();
|
||||
c = (char *) &p->c;
|
||||
if (__builtin_object_size (c, 0) != s - __builtin_offsetof (struct A, c))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 1) != s - __builtin_offsetof (struct A, c))
|
||||
abort ();
|
||||
c = p->a;
|
||||
if (__builtin_object_size (c, 1) != sizeof (p->a))
|
||||
abort ();
|
||||
c = &p->a[0];
|
||||
if (__builtin_object_size (c, 1) != sizeof (p->a))
|
||||
abort ();
|
||||
c = &p->a[3];
|
||||
if (__builtin_object_size (c, 1) != sizeof (p->a) - 3)
|
||||
abort ();
|
||||
c = (char *) &p->b;
|
||||
if (__builtin_object_size (c, 1) != sizeof (p->b))
|
||||
abort ();
|
||||
c = (char *) &p->c;
|
||||
if (__builtin_object_size (c, 1) != s - __builtin_offsetof (struct A, c))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a, 2) != s)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 2) != s)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 2) != s - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 2) != s - __builtin_offsetof (struct A, b))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 2) != s - __builtin_offsetof (struct A, c))
|
||||
abort ();
|
||||
c = p->a;
|
||||
if (__builtin_object_size (c, 2) != s)
|
||||
abort ();
|
||||
c = &p->a[0];
|
||||
if (__builtin_object_size (c, 2) != s)
|
||||
abort ();
|
||||
c = &p->a[3];
|
||||
if (__builtin_object_size (c, 2) != s - 3)
|
||||
abort ();
|
||||
c = (char *) &p->b;
|
||||
if (__builtin_object_size (c, 2) != s - __builtin_offsetof (struct A, b))
|
||||
abort ();
|
||||
c = (char *) &p->c;
|
||||
if (__builtin_object_size (c, 2) != s - __builtin_offsetof (struct A, c))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a, 3) != sizeof (p->a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 3) != sizeof (p->b))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 3) != s - __builtin_offsetof (struct A, c))
|
||||
abort ();
|
||||
c = p->a;
|
||||
if (__builtin_object_size (c, 3) != sizeof (p->a))
|
||||
abort ();
|
||||
c = &p->a[0];
|
||||
if (__builtin_object_size (c, 3) != sizeof (p->a))
|
||||
abort ();
|
||||
c = &p->a[3];
|
||||
if (__builtin_object_size (c, 3) != sizeof (p->a) - 3)
|
||||
abort ();
|
||||
c = (char *) &p->b;
|
||||
if (__builtin_object_size (c, 3) != sizeof (p->b))
|
||||
abort ();
|
||||
c = (char *) &p->c;
|
||||
if (__builtin_object_size (c, 3) != s - __builtin_offsetof (struct A, c))
|
||||
abort ();
|
||||
free (p);
|
||||
}
|
||||
|
||||
void
|
||||
__attribute__ ((noinline))
|
||||
test3 (void)
|
||||
{
|
||||
char *c;
|
||||
size_t s;
|
||||
struct A *p = malloc (4);
|
||||
if (__builtin_object_size (&p->a, 0) != 4)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 0) != 4)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 0) != 1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 0) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 0) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a, 1) != 4)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 1) != 4)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 1) != 1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 1) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 1) != 0)
|
||||
abort ();
|
||||
free (p);
|
||||
s = __builtin_offsetof (struct A, c) + 4;
|
||||
p = malloc (s);
|
||||
if (__builtin_object_size (&p->a, 0) != s)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 0) != s)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 0) != s - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (struct A, b))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 0) != 4)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
|
||||
abort ();
|
||||
if (__builtin_object_size (&p->c, 1) != 4)
|
||||
abort ();
|
||||
free (p);
|
||||
}
|
||||
|
||||
struct B
|
||||
{
|
||||
struct A a[4];
|
||||
};
|
||||
|
||||
void
|
||||
__attribute__ ((noinline))
|
||||
test4 (struct B *q, int i)
|
||||
{
|
||||
if (__builtin_object_size (&q->a[2].a[2], 1) != sizeof (q->a[0].a) - 2)
|
||||
abort ();
|
||||
if (__builtin_object_size (&q->a[2].c[2], 1) != sizeof (q->a[0].c) - 2)
|
||||
abort ();
|
||||
if (__builtin_object_size (&q->a[3].a[2], 1) != sizeof (q->a[0].a) - 2)
|
||||
abort ();
|
||||
if (__builtin_object_size (&q->a[3].c[2], 1) != sizeof (q->a[0].c) - 2)
|
||||
abort ();
|
||||
if (__builtin_object_size (&q->a[i].a[2], 1) != sizeof (q->a[0].a) - 2)
|
||||
abort ();
|
||||
if (__builtin_object_size (&q->a[i].c[2], 1) != sizeof (q->a[0].c) - 2)
|
||||
abort ();
|
||||
}
|
||||
|
||||
struct C
|
||||
{
|
||||
char a[10];
|
||||
char b;
|
||||
};
|
||||
|
||||
void
|
||||
__attribute__ ((noinline))
|
||||
test5 (struct C *c)
|
||||
{
|
||||
if (__builtin_object_size (&c->b, 0) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&c->b, 1) != 1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&c->b, 2) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&c->b, 3) != 1)
|
||||
abort ();
|
||||
}
|
||||
|
||||
struct D
|
||||
{
|
||||
int i;
|
||||
struct D1
|
||||
{
|
||||
char b;
|
||||
char a[10];
|
||||
} j;
|
||||
};
|
||||
|
||||
void
|
||||
__attribute__ ((noinline))
|
||||
test6 (struct D *d)
|
||||
{
|
||||
if (__builtin_object_size (&d->j.a[3], 0) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&d->j.a[3], 1) != sizeof (d->j.a) - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size (&d->j.a[3], 2) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&d->j.a[3], 3) != sizeof (d->j.a) - 3)
|
||||
abort ();
|
||||
}
|
||||
|
||||
struct E
|
||||
{
|
||||
int i;
|
||||
struct E1
|
||||
{
|
||||
char b;
|
||||
char a[10];
|
||||
} j[1];
|
||||
};
|
||||
|
||||
void
|
||||
__attribute__ ((noinline))
|
||||
test7 (struct E *e)
|
||||
{
|
||||
if (__builtin_object_size (&e->j[0].a[3], 0) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&e->j[0].a[3], 1) != sizeof (e->j[0].a) - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size (&e->j[0].a[3], 2) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&e->j[0].a[3], 3) != sizeof (e->j[0].a) - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size ((char *) &e->j[0], 0) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size ((char *) &e->j[0], 1) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size ((char *) &e->j[0], 2) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size ((char *) &e->j[0], 3) != 0)
|
||||
abort ();
|
||||
}
|
||||
|
||||
union F
|
||||
{
|
||||
char a[1];
|
||||
struct F1
|
||||
{
|
||||
char b;
|
||||
char c[10];
|
||||
} d;
|
||||
};
|
||||
|
||||
void
|
||||
__attribute__ ((noinline))
|
||||
test8 (union F *f)
|
||||
{
|
||||
if (__builtin_object_size (&f->d.c[3], 0) != (size_t) -1)
|
||||
abort ();
|
||||
if (__builtin_object_size (&f->d.c[3], 1) != sizeof (f->d.c) - 3)
|
||||
abort ();
|
||||
if (__builtin_object_size (&f->d.c[3], 2) != 0)
|
||||
abort ();
|
||||
if (__builtin_object_size (&f->d.c[3], 3) != sizeof (f->d.c) - 3)
|
||||
abort ();
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
struct A a, *p = &a;
|
||||
int i = 1;
|
||||
__asm ("" : "+r" (p));
|
||||
test1 (p);
|
||||
test2 ();
|
||||
test3 ();
|
||||
struct B b, *q = &b;
|
||||
__asm ("" : "+r" (q), "+r" (i));
|
||||
test4 (q, i);
|
||||
struct C c, *cp = &c;
|
||||
__asm ("" : "+r" (cp));
|
||||
test5 (cp);
|
||||
struct D d, *dp = &d;
|
||||
__asm ("" : "+r" (dp));
|
||||
test6 (dp);
|
||||
struct E e, *ep = &e;
|
||||
__asm ("" : "+r" (ep));
|
||||
test7 (ep);
|
||||
union F f, *fp = &f;
|
||||
__asm ("" : "+r" (fp));
|
||||
test8 (fp);
|
||||
exit (0);
|
||||
}
|
|
@ -43,7 +43,8 @@ struct object_size_info
|
|||
static unsigned HOST_WIDE_INT unknown[4] = { -1, -1, 0, 0 };
|
||||
|
||||
static tree compute_object_offset (const_tree, const_tree);
|
||||
static unsigned HOST_WIDE_INT addr_object_size (const_tree, int);
|
||||
static unsigned HOST_WIDE_INT addr_object_size (struct object_size_info *,
|
||||
const_tree, int);
|
||||
static unsigned HOST_WIDE_INT alloc_object_size (const_gimple, int);
|
||||
static tree pass_through_call (const_gimple);
|
||||
static void collect_object_sizes_for (struct object_size_info *, tree);
|
||||
|
@ -152,9 +153,10 @@ compute_object_offset (const_tree expr, const_tree var)
|
|||
If unknown, return unknown[object_size_type]. */
|
||||
|
||||
static unsigned HOST_WIDE_INT
|
||||
addr_object_size (const_tree ptr, int object_size_type)
|
||||
addr_object_size (struct object_size_info *osi, const_tree ptr,
|
||||
int object_size_type)
|
||||
{
|
||||
tree pt_var;
|
||||
tree pt_var, pt_var_size = NULL_TREE, var_size, bytes;
|
||||
|
||||
gcc_assert (TREE_CODE (ptr) == ADDR_EXPR);
|
||||
|
||||
|
@ -163,58 +165,170 @@ addr_object_size (const_tree ptr, int object_size_type)
|
|||
pt_var = get_base_address (pt_var);
|
||||
|
||||
if (pt_var
|
||||
&& (SSA_VAR_P (pt_var) || TREE_CODE (pt_var) == STRING_CST)
|
||||
&& TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
|
||||
&& host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
|
||||
&& (unsigned HOST_WIDE_INT)
|
||||
tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1) < offset_limit)
|
||||
&& TREE_CODE (pt_var) == INDIRECT_REF
|
||||
&& TREE_CODE (TREE_OPERAND (pt_var, 0)) == SSA_NAME
|
||||
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (pt_var, 0))))
|
||||
{
|
||||
tree bytes;
|
||||
unsigned HOST_WIDE_INT sz;
|
||||
|
||||
if (pt_var != TREE_OPERAND (ptr, 0))
|
||||
if (!osi)
|
||||
sz = compute_builtin_object_size (TREE_OPERAND (pt_var, 0),
|
||||
object_size_type);
|
||||
else
|
||||
{
|
||||
tree var;
|
||||
|
||||
if (object_size_type & 1)
|
||||
{
|
||||
var = TREE_OPERAND (ptr, 0);
|
||||
|
||||
while (var != pt_var
|
||||
&& TREE_CODE (var) != BIT_FIELD_REF
|
||||
&& TREE_CODE (var) != COMPONENT_REF
|
||||
&& TREE_CODE (var) != ARRAY_REF
|
||||
&& TREE_CODE (var) != ARRAY_RANGE_REF
|
||||
&& TREE_CODE (var) != REALPART_EXPR
|
||||
&& TREE_CODE (var) != IMAGPART_EXPR)
|
||||
var = TREE_OPERAND (var, 0);
|
||||
if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
|
||||
var = TREE_OPERAND (var, 0);
|
||||
if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
|
||||
|| ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1)
|
||||
|| tree_int_cst_lt (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)),
|
||||
TYPE_SIZE_UNIT (TREE_TYPE (var))))
|
||||
var = pt_var;
|
||||
}
|
||||
tree var = TREE_OPERAND (pt_var, 0);
|
||||
if (osi->pass == 0)
|
||||
collect_object_sizes_for (osi, var);
|
||||
if (bitmap_bit_p (computed[object_size_type],
|
||||
SSA_NAME_VERSION (var)))
|
||||
sz = object_sizes[object_size_type][SSA_NAME_VERSION (var)];
|
||||
else
|
||||
var = pt_var;
|
||||
sz = unknown[object_size_type];
|
||||
}
|
||||
|
||||
bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var);
|
||||
if (bytes != error_mark_node)
|
||||
if (sz != unknown[object_size_type] && sz < offset_limit)
|
||||
pt_var_size = size_int (sz);
|
||||
}
|
||||
else if (pt_var
|
||||
&& (SSA_VAR_P (pt_var) || TREE_CODE (pt_var) == STRING_CST)
|
||||
&& TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
|
||||
&& host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
|
||||
&& (unsigned HOST_WIDE_INT)
|
||||
tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
|
||||
< offset_limit)
|
||||
pt_var_size = TYPE_SIZE_UNIT (TREE_TYPE (pt_var));
|
||||
else
|
||||
return unknown[object_size_type];
|
||||
|
||||
if (pt_var != TREE_OPERAND (ptr, 0))
|
||||
{
|
||||
tree var;
|
||||
|
||||
if (object_size_type & 1)
|
||||
{
|
||||
var = TREE_OPERAND (ptr, 0);
|
||||
|
||||
while (var != pt_var
|
||||
&& TREE_CODE (var) != BIT_FIELD_REF
|
||||
&& TREE_CODE (var) != COMPONENT_REF
|
||||
&& TREE_CODE (var) != ARRAY_REF
|
||||
&& TREE_CODE (var) != ARRAY_RANGE_REF
|
||||
&& TREE_CODE (var) != REALPART_EXPR
|
||||
&& TREE_CODE (var) != IMAGPART_EXPR)
|
||||
var = TREE_OPERAND (var, 0);
|
||||
if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
|
||||
var = TREE_OPERAND (var, 0);
|
||||
if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
|
||||
|| ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1)
|
||||
|| (pt_var_size
|
||||
&& tree_int_cst_lt (pt_var_size,
|
||||
TYPE_SIZE_UNIT (TREE_TYPE (var)))))
|
||||
var = pt_var;
|
||||
else if (var != pt_var && TREE_CODE (pt_var) == INDIRECT_REF)
|
||||
{
|
||||
if (TREE_CODE (bytes) == INTEGER_CST
|
||||
&& tree_int_cst_lt (TYPE_SIZE_UNIT (TREE_TYPE (var)), bytes))
|
||||
bytes = size_zero_node;
|
||||
else
|
||||
bytes = size_binop (MINUS_EXPR,
|
||||
TYPE_SIZE_UNIT (TREE_TYPE (var)), bytes);
|
||||
tree v = var;
|
||||
/* For &X->fld, compute object size only if fld isn't the last
|
||||
field, as struct { int i; char c[1]; } is often used instead
|
||||
of flexible array member. */
|
||||
while (v && v != pt_var)
|
||||
switch (TREE_CODE (v))
|
||||
{
|
||||
case ARRAY_REF:
|
||||
if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (v, 0)))
|
||||
&& TREE_CODE (TREE_OPERAND (v, 1)) == INTEGER_CST)
|
||||
{
|
||||
tree domain
|
||||
= TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (v, 0)));
|
||||
if (domain
|
||||
&& TYPE_MAX_VALUE (domain)
|
||||
&& TREE_CODE (TYPE_MAX_VALUE (domain))
|
||||
== INTEGER_CST
|
||||
&& tree_int_cst_lt (TREE_OPERAND (v, 1),
|
||||
TYPE_MAX_VALUE (domain)))
|
||||
{
|
||||
v = NULL_TREE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
v = TREE_OPERAND (v, 0);
|
||||
break;
|
||||
case REALPART_EXPR:
|
||||
case IMAGPART_EXPR:
|
||||
v = NULL_TREE;
|
||||
break;
|
||||
case COMPONENT_REF:
|
||||
if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
|
||||
== RECORD_TYPE
|
||||
&& TREE_CHAIN (TREE_OPERAND (v, 1)))
|
||||
|| TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE)
|
||||
v = NULL_TREE;
|
||||
else
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
|
||||
== RECORD_TYPE)
|
||||
v = TREE_OPERAND (v, 0);
|
||||
while (v && v != pt_var && TREE_CODE (v) == COMPONENT_REF)
|
||||
if (TREE_CODE (TREE_TYPE (v)) != UNION_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (v)) != QUAL_UNION_TYPE)
|
||||
break;
|
||||
else
|
||||
v = TREE_OPERAND (v, 0);
|
||||
if (v && v != pt_var)
|
||||
v = NULL_TREE;
|
||||
else
|
||||
v = pt_var;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
v = pt_var;
|
||||
break;
|
||||
}
|
||||
if (v == pt_var)
|
||||
var = pt_var;
|
||||
}
|
||||
}
|
||||
else
|
||||
bytes = TYPE_SIZE_UNIT (TREE_TYPE (pt_var));
|
||||
var = pt_var;
|
||||
|
||||
if (host_integerp (bytes, 1))
|
||||
return tree_low_cst (bytes, 1);
|
||||
if (var != pt_var)
|
||||
var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
|
||||
else if (!pt_var_size)
|
||||
return unknown[object_size_type];
|
||||
else
|
||||
var_size = pt_var_size;
|
||||
bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var);
|
||||
if (bytes != error_mark_node)
|
||||
{
|
||||
if (TREE_CODE (bytes) == INTEGER_CST
|
||||
&& tree_int_cst_lt (var_size, bytes))
|
||||
bytes = size_zero_node;
|
||||
else
|
||||
bytes = size_binop (MINUS_EXPR, var_size, bytes);
|
||||
}
|
||||
if (var != pt_var
|
||||
&& pt_var_size
|
||||
&& TREE_CODE (pt_var) == INDIRECT_REF
|
||||
&& bytes != error_mark_node)
|
||||
{
|
||||
tree bytes2 = compute_object_offset (TREE_OPERAND (ptr, 0), pt_var);
|
||||
if (bytes2 != error_mark_node)
|
||||
{
|
||||
if (TREE_CODE (bytes2) == INTEGER_CST
|
||||
&& tree_int_cst_lt (pt_var_size, bytes2))
|
||||
bytes2 = size_zero_node;
|
||||
else
|
||||
bytes2 = size_binop (MINUS_EXPR, var_size, bytes2);
|
||||
bytes = size_binop (MIN_EXPR, bytes, bytes2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!pt_var_size)
|
||||
return unknown[object_size_type];
|
||||
else
|
||||
bytes = pt_var_size;
|
||||
|
||||
if (host_integerp (bytes, 1))
|
||||
return tree_low_cst (bytes, 1);
|
||||
|
||||
return unknown[object_size_type];
|
||||
}
|
||||
|
@ -332,11 +446,11 @@ compute_builtin_object_size (tree ptr, int object_size_type)
|
|||
init_offset_limit ();
|
||||
|
||||
if (TREE_CODE (ptr) == ADDR_EXPR)
|
||||
return addr_object_size (ptr, object_size_type);
|
||||
return addr_object_size (NULL, ptr, object_size_type);
|
||||
|
||||
if (TREE_CODE (ptr) == SSA_NAME
|
||||
&& POINTER_TYPE_P (TREE_TYPE (ptr))
|
||||
&& object_sizes[object_size_type] != NULL)
|
||||
&& POINTER_TYPE_P (TREE_TYPE (ptr))
|
||||
&& object_sizes[object_size_type] != NULL)
|
||||
{
|
||||
if (!bitmap_bit_p (computed[object_size_type], SSA_NAME_VERSION (ptr)))
|
||||
{
|
||||
|
@ -477,7 +591,7 @@ expr_object_size (struct object_size_info *osi, tree ptr, tree value)
|
|||
|| !POINTER_TYPE_P (TREE_TYPE (value)));
|
||||
|
||||
if (TREE_CODE (value) == ADDR_EXPR)
|
||||
bytes = addr_object_size (value, object_size_type);
|
||||
bytes = addr_object_size (osi, value, object_size_type);
|
||||
else
|
||||
bytes = unknown[object_size_type];
|
||||
|
||||
|
@ -633,7 +747,7 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple stmt)
|
|||
unsigned HOST_WIDE_INT off = tree_low_cst (op1, 1);
|
||||
|
||||
/* op0 will be ADDR_EXPR here. */
|
||||
bytes = compute_builtin_object_size (op0, object_size_type);
|
||||
bytes = addr_object_size (osi, op0, object_size_type);
|
||||
if (bytes == unknown[object_size_type])
|
||||
;
|
||||
else if (off > offset_limit)
|
||||
|
|
Loading…
Add table
Reference in a new issue