aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-18.c25
-rw-r--r--gcc/tree-vrp.c25
4 files changed, 38 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 21d304d1..3a13f5f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9dc7f18..2e45a6a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..888fb80
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-18.c
@@ -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);
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 0ce7f1f..a11635d 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -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,