re PR tree-optimization/48795 (-Warray-bounds false positive)
authorRichard Biener <rguenther@suse.de>
Thu, 25 Feb 2016 13:20:25 +0000 (13:20 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 25 Feb 2016 13:20:25 +0000 (13:20 +0000)
2016-02-25  Richard Biener  <rguenther@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.

From-SVN: r233714

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Warray-bounds-18.c [new file with mode: 0644]
gcc/tree-vrp.c

index 21d304d..3a13f5f 100644 (file)
@@ -1,3 +1,8 @@
+2016-02-25  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/48795
+       * tree-vrp.c (check_array_ref): Use array_at_struct_end_p.
+
 2016-02-25  Ilya Verbin  <ilya.verbin@intel.com>
 
        PR driver/68463
index 9dc7f18..2e45a6a 100644 (file)
@@ -1,3 +1,8 @@
+2016-02-25  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/48795
+       * gcc.dg/Warray-bounds-18.c: New testcase.
+
 2016-02-25  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * g++.dg/ext/attr-constructor1.C: Require init_priority support.
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-18.c b/gcc/testsuite/gcc.dg/Warray-bounds-18.c
new file mode 100644 (file)
index 0000000..888fb80
--- /dev/null
@@ -0,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);
+}
index 0ce7f1f..a11635d 100644 (file)
@@ -6450,7 +6450,6 @@ check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
   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;
@@ -6465,27 +6464,9 @@ check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
 
   /* 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;
-    }
+  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,