The following fixes a bogus Warray-bound warning by consolidating some (slightly bogus) duplicate code in tree-vrp.c
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2016-02-25 Richard Biener <rguent...@suse.de> PR tree-optimization/48795 * tree-vrp.c (check_array_ref): Use array_at_struct_end_p. * gcc.dg/Warray-bounds-18.c: New testcase. Index: gcc/tree-vrp.c =================================================================== *** gcc/tree-vrp.c (revision 233693) --- gcc/tree-vrp.c (working copy) *************** check_array_ref (location_t location, tr *** 6450,6456 **** value_range *vr = NULL; tree low_sub, up_sub; tree low_bound, up_bound, up_bound_p1; - tree base; if (TREE_NO_WARNING (ref)) return; --- 6450,6455 ---- *************** check_array_ref (location_t location, tr *** 6465,6491 **** /* Accesses to trailing arrays via pointers may access storage beyond the types array bounds. */ ! base = get_base_address (ref); ! if ((warn_array_bounds < 2) ! && base && TREE_CODE (base) == MEM_REF) ! { ! tree cref, next = NULL_TREE; ! ! if (TREE_CODE (TREE_OPERAND (ref, 0)) != COMPONENT_REF) ! return; ! ! cref = TREE_OPERAND (ref, 0); ! if (TREE_CODE (TREE_TYPE (TREE_OPERAND (cref, 0))) == RECORD_TYPE) ! for (next = DECL_CHAIN (TREE_OPERAND (cref, 1)); ! next && TREE_CODE (next) != FIELD_DECL; ! next = DECL_CHAIN (next)) ! ; ! ! /* If this is the last field in a struct type or a field in a ! union type do not warn. */ ! if (!next) ! return; ! } low_bound = array_ref_low_bound (ref); up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound, --- 6464,6472 ---- /* Accesses to trailing arrays via pointers may access storage beyond the types array bounds. */ ! if (warn_array_bounds < 2 ! && array_at_struct_end_p (ref)) ! return; low_bound = array_ref_low_bound (ref); up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound, Index: gcc/testsuite/gcc.dg/Warray-bounds-18.c =================================================================== *** gcc/testsuite/gcc.dg/Warray-bounds-18.c (revision 0) --- gcc/testsuite/gcc.dg/Warray-bounds-18.c (working copy) *************** *** 0 **** --- 1,25 ---- + /* { dg-do compile } */ + /* { dg-options "-O2 -Warray-bounds" } */ + + typedef struct + { + int len; + char data[1]; + } rec; + + int + p(rec *r, int len); + + int + f (char prm1, char prm2) + { + char buf[10]; + + rec *r1 = (rec *)&buf; + + r1->len = 10; + r1->data[0] = prm1; + r1->data[1] = prm2; /* { dg-bogus "above array bounds" } */ + + return p(r1, r1->len); + }