[proposed 4.9/4.8 fix for PR57748 ] List-Archive: Date: Fri, 2 Aug 2013 13:45:31 +0200 From: Martin Jambor Subject: [PATCH, PR 57748] Set mode of structures with zero sized arrays to be BLK Hi, while compute_record_mode in stor-layout.c makes sure it assigns BLK mode to structs with flexible arrays, it has no such provisions for zero length arrays (http://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/Zero-Length.html). I think that in order to avoid problems and surprises like PR 57748 (where this triggered code that was intended for small structures that fit into a scalar mode and ICEd), we should assign both variable array possibilities the same mode. Bootstrapped and tested on x86_64-linux without any problems. OK for trunk and the 4.8 branch? (I'm not sure about the 4.7, this PR does not happen there despite the wrong mode so I'd ignore it for now.) Thanks, Martin 2013-08-01 Martin Jambor PR middle-end/57748 * stor-layout.c (compute_record_mode): Treat zero-sized array fields like incomplete types. testsuite/ * gcc.dg/torture/pr57748.c: New test. --- gcc-4.8.1/gcc/stor-layout.c.~1~ 2013-04-28 19:29:18.000000000 +0200 +++ gcc-4.8.1/gcc/stor-layout.c 2013-08-03 12:04:38.669453016 +0200 @@ -1618,7 +1618,9 @@ compute_record_mode (tree type) && integer_zerop (TYPE_SIZE (TREE_TYPE (field))))) || ! host_integerp (bit_position (field), 1) || DECL_SIZE (field) == 0 - || ! host_integerp (DECL_SIZE (field), 1)) + || ! host_integerp (DECL_SIZE (field), 1) + || (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE + && tree_low_cst (DECL_SIZE (field), 1) == 0)) return; /* If this field is the whole struct, remember its mode so --- gcc-4.8.1/gcc/testsuite/gcc.dg/torture/pr57748.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.8.1/gcc/testsuite/gcc.dg/torture/pr57748.c 2013-08-03 12:04:38.669453016 +0200 @@ -0,0 +1,45 @@ +/* PR middle-end/57748 */ +/* { dg-do run } */ + +#include + +extern void abort (void); + +typedef long long V + __attribute__ ((vector_size (2 * sizeof (long long)), may_alias)); + +typedef struct S { V a; V b[0]; } P __attribute__((aligned (1))); + +struct __attribute__((packed)) T { char c; P s; }; + +void __attribute__((noinline, noclone)) +check (struct T *t) +{ + if (t->s.b[0][0] != 3 || t->s.b[0][1] != 4) + abort (); +} + +int __attribute__((noinline, noclone)) +get_i (void) +{ + return 0; +} + +void __attribute__((noinline, noclone)) +foo (P *p) +{ + V a = { 3, 4 }; + int i = get_i(); + p->b[i] = a; +} + +int +main () +{ + struct T *t = (struct T *) malloc (128); + + foo (&t->s); + check (t); + + return 0; +}