From: jakub Date: Tue, 23 Jun 2009 14:27:04 +0000 (+0000) Subject: * tree-object-size.c (addr_object_size): Instead of checking X-Git-Tag: upstream/4.9.2~35263 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5dc67ab13b518c785e3a5b6e1c0465fecd731988;p=platform%2Fupstream%2Flinaro-gcc.git * tree-object-size.c (addr_object_size): Instead of checking for non-NULL TREE_CHAIN of the FIELD_DECL check that there are no FIELD_DECLs following it. * g++.dg/ext/builtin-object-size1.C: New test. * g++.dg/ext/builtin-object-size2.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@148851 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 73c0c36..bcb6209 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-06-23 Jakub Jelinek + + * tree-object-size.c (addr_object_size): Instead of checking + for non-NULL TREE_CHAIN of the FIELD_DECL check that there + are no FIELD_DECLs following it. + 2009-06-23 Andreas Krebbel * tree-ssa-math-opts.c (find_bswap): Increase the search depth in diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7158684..0425c18 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-06-23 Jakub Jelinek + + * g++.dg/ext/builtin-object-size1.C: New test. + * g++.dg/ext/builtin-object-size2.C: New test. + 2009-06-23 Andreas Krebbel * gcc.dg/optimize-bswapsi-1.c: Add new bswap implementation. diff --git a/gcc/testsuite/g++.dg/ext/builtin-object-size1.C b/gcc/testsuite/g++.dg/ext/builtin-object-size1.C new file mode 100644 index 0000000..8baed69 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin-object-size1.C @@ -0,0 +1,435 @@ +// { dg-do run } +// { dg-options "-O2" } + +typedef __SIZE_TYPE__ size_t; +extern "C" void abort (); +extern "C" void exit (int); +extern "C" void *malloc (size_t); +extern "C" void free (void *); + +struct A +{ + char a[10]; + int b; + char c[10]; +}; + +void +__attribute__ ((noinline)) +test1 (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 (A); + A *p = (A *) malloc (2 * sizeof (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 (A, b)) + abort (); + if (__builtin_object_size (&p->c, 0) != s - __builtin_offsetof (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 (A, b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 0) != s - __builtin_offsetof (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 (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 (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 (A, b)) + abort (); + if (__builtin_object_size (&p->c, 2) != s - __builtin_offsetof (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 (A, b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 2) != s - __builtin_offsetof (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 (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 (A, c)) + abort (); + free (p); +} + +void +__attribute__ ((noinline)) +test3 (void) +{ + char *c; + size_t s; + A *p = (A *) 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 (A, c) + 4; + p = (A *) 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 (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 +{ + 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) +{ + 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); +} diff --git a/gcc/testsuite/g++.dg/ext/builtin-object-size2.C b/gcc/testsuite/g++.dg/ext/builtin-object-size2.C new file mode 100644 index 0000000..e1fe6de --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin-object-size2.C @@ -0,0 +1,438 @@ +// { dg-do run } +// { dg-options "-O2" } + +typedef __SIZE_TYPE__ size_t; +extern "C" void abort (); +extern "C" void exit (int); +extern "C" void *malloc (size_t); +extern "C" void free (void *); + +typedef struct A +{ + char a[10]; + int b; + char c[10]; + static int d; +} AT; + +int A::d = 6; + +void +__attribute__ ((noinline)) +test1 (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 (A); + A *p = (A *) malloc (2 * sizeof (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 (A, b)) + abort (); + if (__builtin_object_size (&p->c, 0) != s - __builtin_offsetof (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 (A, b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 0) != s - __builtin_offsetof (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 (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 (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 (A, b)) + abort (); + if (__builtin_object_size (&p->c, 2) != s - __builtin_offsetof (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 (A, b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 2) != s - __builtin_offsetof (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 (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 (A, c)) + abort (); + free (p); +} + +void +__attribute__ ((noinline)) +test3 (void) +{ + char *c; + size_t s; + A *p = (A *) 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 (A, c) + 4; + p = (A *) 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 (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 +{ + 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) +{ + 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); +} diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index ebef69c..5c64b98 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -257,27 +257,39 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, 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 (v)) != ARRAY_TYPE) + { + v = NULL_TREE; + break; + } + if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) + == RECORD_TYPE) { - 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) + tree fld_chain = TREE_CHAIN (TREE_OPERAND (v, 1)); + for (; fld_chain; fld_chain = TREE_CHAIN (fld_chain)) + if (TREE_CODE (fld_chain) == FIELD_DECL) + break; + + if (fld_chain) + { + v = NULL_TREE; break; - else - v = TREE_OPERAND (v, 0); - if (v && v != pt_var) - v = NULL_TREE; - else - v = pt_var; + } } + + 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;