]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/32135 (bogus array-ref fold triggering array overflow warning)
authorJan Hubicka <jh@suse.cz>
Sun, 13 Jan 2008 11:18:08 +0000 (12:18 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 13 Jan 2008 11:18:08 +0000 (11:18 +0000)
PR middle-end/32135
* tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Do not construct
references above array bounds.  This might trigger bounds checks for
pointers to arrays.

From-SVN: r131502

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr32135.c [new file with mode: 0644]
gcc/tree-ssa-ccp.c

index 045118afb49eb052280d18630e1e3413ad3e56aa..6cd0af8b53239495976ca0ac4f982403ede7ab6d 100644 (file)
@@ -1,3 +1,10 @@
+2008-01-12  Jan Hubicka  <jh@suse.cz>
+
+       PR middle-end/32135
+       * tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Do not construct
+       references above array bounds.  This might trigger bounds checks for
+       pointers to arrays.
+
 2008-01-12  Sebastian Pop  <sebastian.pop@amd.com>
 
        * tree-ssa-ter.c (free_temp_expr_table): Free num_in_part and
index 34b4ec1158026170f7b03bac9cc9006b1324f2e1..b067970ec88dc3ae2b7dd04ab0a84ac0f81615dd 100644 (file)
@@ -1,3 +1,8 @@
+2008-01-13  Jan Hubicka  <jh@suse.cz>
+
+       PR middle-end/32135
+       * gcc.dg/pr32135.c: new.
+
 2008-01-12  Doug Kwan  <dougkwan@google.com>
 
        * gcc.dg/qual-return-1.c: Add -Wignored-qualifiers.
diff --git a/gcc/testsuite/gcc.dg/pr32135.c b/gcc/testsuite/gcc.dg/pr32135.c
new file mode 100644 (file)
index 0000000..4459656
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-Warray-bounds -O2" } */
+struct PhaseEntryType
+{
+  char raw_field[50 + 1];
+};
+int
+ParsePhase (char in_cols[15][250], struct PhaseEntryType *P)
+{
+  __builtin_strncpy (P->raw_field, in_cols[2], 50);
+}
index 15f14c4c6085acd1fd3d3be189d111ddc47f0a99..f9f1217c5fc0e7113d25888aec44b1f81b099779 100644 (file)
@@ -1588,6 +1588,7 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
 {
   tree min_idx, idx, idx_type, elt_offset = integer_zero_node;
   tree array_type, elt_type, elt_size;
+  tree domain_type;
 
   /* If BASE is an ARRAY_REF, we can pick up another offset (this time
      measured in units of the size of elements type) from that ARRAY_REF).
@@ -1659,9 +1660,10 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
      low bound, if any, convert the index into that type, and add the
      low bound.  */
   min_idx = build_int_cst (idx_type, 0);
-  if (TYPE_DOMAIN (array_type))
+  domain_type = TYPE_DOMAIN (array_type);
+  if (domain_type)
     {
-      idx_type = TYPE_DOMAIN (array_type);
+      idx_type = domain_type;
       if (TYPE_MIN_VALUE (idx_type))
        min_idx = TYPE_MIN_VALUE (idx_type);
       else
@@ -1681,6 +1683,24 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
   /* Make sure to possibly truncate late after offsetting.  */
   idx = fold_convert (idx_type, idx);
 
+  /* We don't want to construct access past array bounds. For example
+     char *(c[4]);
+
+     c[3][2]; should not be simplified into (*c)[14] or tree-vrp will give false
+     warning.  */
+  if (domain_type && TYPE_MAX_VALUE (domain_type) 
+      && TREE_CODE (TYPE_MAX_VALUE (domain_type)) == INTEGER_CST)
+    {
+      tree up_bound = TYPE_MAX_VALUE (domain_type);
+
+      if (tree_int_cst_lt (up_bound, idx)
+         /* Accesses after the end of arrays of size 0 (gcc
+            extension) and 1 are likely intentional ("struct
+            hack").  */
+         && compare_tree_int (up_bound, 1) > 0)
+       return NULL_TREE;
+    }
+
   return build4 (ARRAY_REF, elt_type, base, idx, NULL_TREE, NULL_TREE);
 }