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);
+ }

Reply via email to