diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/builtin-object-size1.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/builtin-object-size2.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-object-size-6.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-object-size-8.c | 200 | ||||
-rw-r--r-- | gcc/tree-object-size.c | 30 |
7 files changed, 233 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c24dbe3..6b658f3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,8 @@ 2009-07-20 Jakub Jelinek <jakub@redhat.com> + * tree-object-size.c (addr_object_size): Handle unions with + array in it as last field of structs in __bos (, 1) as __bos (, 0). + PR tree-optimization/40792 * tree.c (build_function_type_skip_args): Remove bogus assert. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2e778c6..0a473c5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2009-07-20 Jakub Jelinek <jakub@redhat.com> + * gcc.dg/builtin-object-size-6.c: Adjust expected values. + * gcc.dg/builtin-object-size-8.c: New test. + * g++.dg/ext/builtin-object-size1.C: Adjust expected values. + * g++.dg/ext/builtin-object-size2.C: Likewise. + PR tree-optimization/40792 * gcc.dg/pr40792.c: New test. diff --git a/gcc/testsuite/g++.dg/ext/builtin-object-size1.C b/gcc/testsuite/g++.dg/ext/builtin-object-size1.C index 8baed69..8590a0bb 100644 --- a/gcc/testsuite/g++.dg/ext/builtin-object-size1.C +++ b/gcc/testsuite/g++.dg/ext/builtin-object-size1.C @@ -399,11 +399,11 @@ 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) + if (__builtin_object_size (&f->d.c[3], 1) != (size_t) -1) 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) + if (__builtin_object_size (&f->d.c[3], 3) != 0) abort (); } diff --git a/gcc/testsuite/g++.dg/ext/builtin-object-size2.C b/gcc/testsuite/g++.dg/ext/builtin-object-size2.C index e1fe6de..d79b1b8 100644 --- a/gcc/testsuite/g++.dg/ext/builtin-object-size2.C +++ b/gcc/testsuite/g++.dg/ext/builtin-object-size2.C @@ -402,11 +402,11 @@ 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) + if (__builtin_object_size (&f->d.c[3], 1) != (size_t) -1) 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) + if (__builtin_object_size (&f->d.c[3], 3) != 0) abort (); } diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-6.c b/gcc/testsuite/gcc.dg/builtin-object-size-6.c index 9a285df..c6887b8 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-6.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-6.c @@ -399,11 +399,11 @@ 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) + if (__builtin_object_size (&f->d.c[3], 1) != (size_t) -1) 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) + if (__builtin_object_size (&f->d.c[3], 3) != 0) abort (); } diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-8.c b/gcc/testsuite/gcc.dg/builtin-object-size-8.c new file mode 100644 index 0000000..f2d88f9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-object-size-8.c @@ -0,0 +1,200 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +typedef __SIZE_TYPE__ size_t; +extern void *malloc (size_t); +extern void free (void *); +extern void abort (void); + +union A +{ + int a1; + char a2[3]; +}; + +union B +{ + long long b1; + union A b2; +}; + +struct C +{ + int c1; + union A c2; +}; + +struct D +{ + int d1; + union B d2; +}; + +union E +{ + struct C e1; + char e2[3]; +}; + +union F +{ + int f1; + struct D f2; +}; + +struct G +{ + union A g1; + char g2; +}; + +struct H +{ + int h1; + union E h2; +}; + +#define T(X, S0, S1) \ + if (__builtin_object_size (X, 0) != (S0)) \ + abort (); \ + if (__builtin_object_size (X, 1) != (S1)) \ + abort (); \ + if (__builtin_object_size (X, 2) != (S0)) \ + abort (); \ + if (__builtin_object_size (X, 3) != (S1)) \ + abort () +#define TS(X, S0) T(&X, S0, sizeof (X)) +#define TA(X, S0, S1) \ + T(X, S0, S1); T(&X[0], S0, S1); T(&X[1], (S0) - 1, (S1) - 1) +#define TF(X, S0) TA(X, S0, S0) + +int +main (void) +{ + size_t s, o, o2; + + s = sizeof (union A); + o = 0; + union A *a1 = malloc (s); + union A *a2 = malloc (o + 212); + TS (a1->a1, s); + TF (a1->a2, s); + s = o + 212; + TS (a2->a1, s); + TF (a2->a2, s); + free (a2); + free (a1); + + s = sizeof (union B); + o = 0; + union B *b1 = malloc (s); + union B *b2 = malloc (o + 212); + TS (b1->b1, s); + TS (b1->b2.a1, s); + TF (b1->b2.a2, s); + s = o + 212; + TS (b2->b1, s); + TS (b2->b2.a1, s); + TF (b2->b2.a2, s); + free (b2); + free (b1); + + s = sizeof (struct C); + o = __builtin_offsetof (struct C, c2); + struct C *c1 = malloc (s); + struct C *c2 = malloc (o + 212); + TS (c1->c1, s); + TS (c1->c2.a1, s - o); + TF (c1->c2.a2, s - o); + s = o + 212; + TS (c2->c1, s); + TS (c2->c2.a1, s - o); + TF (c2->c2.a2, s - o); + free (c2); + free (c1); + + s = sizeof (struct D); + o = __builtin_offsetof (struct D, d2); + struct D *d1 = malloc (s); + struct D *d2 = malloc (o + 212); + TS (d1->d1, s); + TS (d1->d2.b1, s - o); + TS (d1->d2.b2.a1, s - o); + TF (d1->d2.b2.a2, s - o); + s = o + 212; + TS (d2->d1, s); + TS (d2->d2.b1, s - o); + TS (d2->d2.b2.a1, s - o); + TF (d2->d2.b2.a2, s - o); + free (d2); + free (d1); + + s = sizeof (union E); + o = __builtin_offsetof (union E, e1.c2); + union E *e1 = malloc (s); + union E *e2 = malloc (o + 212); + TS (e1->e1.c1, s); + TS (e1->e1.c2.a1, s - o); + TF (e1->e1.c2.a2, s - o); + TF (e1->e2, s); + s = o + 212; + TS (e2->e1.c1, s); + TS (e2->e1.c2.a1, s - o); + TF (e2->e1.c2.a2, s - o); + TF (e2->e2, s); + free (e2); + free (e1); + + s = sizeof (union F); + o = __builtin_offsetof (union F, f2.d2); + union F *f1 = malloc (s); + union F *f2 = malloc (o + 212); + TS (f1->f1, s); + TS (f1->f2.d1, s); + TS (f1->f2.d2.b1, s - o); + TS (f1->f2.d2.b2.a1, s - o); + TF (f1->f2.d2.b2.a2, s - o); + s = o + 212; + TS (f2->f1, s); + TS (f2->f2.d1, s); + TS (f2->f2.d2.b1, s - o); + TS (f2->f2.d2.b2.a1, s - o); + TF (f2->f2.d2.b2.a2, s - o); + free (f2); + free (f1); + + s = sizeof (struct G); + o = __builtin_offsetof (struct G, g2); + struct G *g1 = malloc (s); + struct G *g2 = malloc (o + 212); + TS (g1->g1.a1, s); + TA (g1->g1.a2, s, sizeof (g1->g1.a2)); + TS (g1->g2, s - o); + s = o + 212; + TS (g2->g1.a1, s); + TA (g2->g1.a2, s, sizeof (g1->g1.a2)); + TS (g2->g2, s - o); + free (g2); + free (g1); + + s = sizeof (struct H); + o = __builtin_offsetof (struct H, h2); + o2 = __builtin_offsetof (struct H, h2.e1.c2); + struct H *h1 = malloc (s); + struct H *h2 = malloc (o2 + 212); + TS (h1->h1, s); + TS (h1->h2.e1.c1, s - o); + TS (h1->h2.e1.c2.a1, s - o2); + TA (h1->h2.e1.c2.a2, s - o2, sizeof (h1->h2.e1.c2.a2)); + TF (h1->h2.e2, s - o); + s = o2 + 212; + TS (h2->h1, s); + TS (h2->h2.e1.c1, s - o); + TS (h2->h2.e1.c2.a1, s - o2); + TA (h2->h2.e1.c2.a2, s - o2, sizeof (h2->h2.e1.c2.a2)); + TF (h2->h2.e2, s - o); + free (h2); + free (h1); + + return 0; +} diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 5c64b98..5b9fe38 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -217,7 +217,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, && TREE_CODE (var) != IMAGPART_EXPR) var = TREE_OPERAND (var, 0); if (var != pt_var && TREE_CODE (var) == ARRAY_REF) - var = TREE_OPERAND (var, 0); + var = TREE_OPERAND (var, 0); if (! TYPE_SIZE_UNIT (TREE_TYPE (var)) || ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1) || (pt_var_size @@ -262,8 +262,17 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, v = NULL_TREE; break; } - if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) - == RECORD_TYPE) + while (v != pt_var && TREE_CODE (v) == COMPONENT_REF) + if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) + != UNION_TYPE + && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) + != QUAL_UNION_TYPE) + break; + else + v = TREE_OPERAND (v, 0); + if (TREE_CODE (v) == COMPONENT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) + == RECORD_TYPE) { tree fld_chain = TREE_CHAIN (TREE_OPERAND (v, 1)); for (; fld_chain; fld_chain = TREE_CHAIN (fld_chain)) @@ -275,18 +284,17 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, v = NULL_TREE; break; } + v = TREE_OPERAND (v, 0); } - - 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) + while (v != pt_var && TREE_CODE (v) == COMPONENT_REF) + if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) + != UNION_TYPE + && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) + != QUAL_UNION_TYPE) break; else v = TREE_OPERAND (v, 0); - if (v && v != pt_var) + if (v != pt_var) v = NULL_TREE; else v = pt_var; |