This restricts BIT_FIELD_REF bound verification to non-aggegate typed bases - otherwise we have to look for trailing arrays and such (see the testcase), and Ada may even have more interesting cases.
Bootstrap / regtest running on x86_64-unknown-linux-gnu. Richard. 2013-11-29 Richard Biener <rguent...@suse.de> PR middle-end/59338 * tree-cfg.c (verify_expr): Restrict bounds verification of BIT_FIELD_REF arguments to non-aggregate typed base objects. * gcc.dg/torture/pr59338.c: New testcase. Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c.orig 2013-11-29 11:11:32.352851010 +0100 +++ gcc/tree-cfg.c 2013-11-29 11:10:08.035886415 +0100 @@ -2732,17 +2732,6 @@ verify_expr (tree *tp, int *walk_subtree tree t0 = TREE_OPERAND (t, 0); tree t1 = TREE_OPERAND (t, 1); tree t2 = TREE_OPERAND (t, 2); - tree t0_type = TREE_TYPE (t0); - unsigned HOST_WIDE_INT t0_size = 0; - - if (tree_fits_uhwi_p (TYPE_SIZE (t0_type))) - t0_size = tree_to_uhwi (TYPE_SIZE (t0_type)); - else - { - HOST_WIDE_INT t0_max_size = max_int_size_in_bytes (t0_type); - if (t0_max_size > 0) - t0_size = t0_max_size * BITS_PER_UNIT; - } if (!tree_fits_uhwi_p (t1) || !tree_fits_uhwi_p (t2)) { @@ -2766,8 +2755,9 @@ verify_expr (tree *tp, int *walk_subtree "match field size of BIT_FIELD_REF"); return t; } - if (t0_size != 0 - && tree_to_uhwi (t1) + tree_to_uhwi (t2) > t0_size) + if (!AGGREGATE_TYPE_P (TREE_TYPE (t0)) + && (tree_to_uhwi (t1) + tree_to_uhwi (t2) + > tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t0))))) { error ("position plus size exceeds size of referenced object in " "BIT_FIELD_REF"); Index: gcc/testsuite/gcc.dg/torture/pr59338.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr59338.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr59338.c (working copy) @@ -0,0 +1,27 @@ +/* { dg-do compile } */ + +typedef enum +{ + XYZZY, +} enumType; + +typedef struct +{ + unsigned char More : 1; +} tResp; + +typedef struct +{ + enumType QueryType; + union + { + tResp l[0]; + } u; +} tQResp; + +void test(void) +{ + tQResp *qResp = (0); + if (qResp->u.l[0].More == 0) + return; +}