This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][committed] PR diagnostic/31227: Suppress some more -Warray-bounds warnings


On Tuesday, 17. April 2007, Richard Guenther wrote:

> Ok with that change if it bootstraps and tests ok.

I've committed the patch below after successful bootstrap and regtest with 
default languages on x86_64_suse-linux.


Dirk

2007-03-21  Dirk Mueller  <dmueller@suse.de>

        PR diagnostic/31227
        * tree-vrp.c (check_array_bounds): Suppress warning
        about address exprs of array refs if it is unused
        or has more than one uses.

        * gcc.dg/Warray-bounds-3.c: New testcase.

--- tree-vrp.c
+++ tree-vrp.c
@@ -4094,6 +4094,36 @@ check_array_ref (tree ref, location_t* l
     }
 }
 
+/* Searches if the expr T, located at LOCATION computes
+   address of an ARRAY_REF, and call check_array_ref on it.  */
+
+static void
+search_for_addr_array(tree t, location_t* location)
+{
+  while (TREE_CODE (t) == SSA_NAME)
+    {
+      t = SSA_NAME_DEF_STMT (t);
+      if (TREE_CODE (t) != GIMPLE_MODIFY_STMT)
+	return;
+      t = GIMPLE_STMT_OPERAND (t, 1);
+    }
+
+
+  /* We are only interested in addresses of ARRAY_REF's.  */
+  if (TREE_CODE (t) != ADDR_EXPR) 
+    return;
+
+  /* Check each ARRAY_REFs in the reference chain. */
+  do 
+    {
+      if (TREE_CODE (t) == ARRAY_REF)
+	check_array_ref (t, location, true /*ignore_off_by_one*/);
+
+      t = TREE_OPERAND(t,0);
+    }
+  while (handled_component_p (t));
+}
+
 /* walk_tree() callback that checks if *TP is
    an ARRAY_REF inside an ADDR_EXPR (in which an array
    subscript one outside the valid range is allowed). Call
@@ -4111,44 +4141,22 @@ check_array_bounds (tree *tp, int *walk_
 
   if (TREE_CODE (t) == ARRAY_REF)
     check_array_ref (t, location, false /*ignore_off_by_one*/);
-  else if (TREE_CODE (t) == ADDR_EXPR)
+
+  if (TREE_CODE (t) == INDIRECT_REF
+      || (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0)))
+    search_for_addr_array (TREE_OPERAND (t, 0), location);
+  else if (TREE_CODE (t) == CALL_EXPR)
     {
-       use_operand_p op;
-       tree use_stmt;
-       t = TREE_OPERAND (t, 0);
-
-       /* Don't warn on statements like
-
-          ssa_name = 500 + &array[-200]
-
-          or
-
-          ssa_name = &array[-200]
-          other_name = ssa_name + 300;
-
-          which are sometimes
-          produced by other optimizing passes.  */
-
-       if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
-           && BINARY_CLASS_P (GIMPLE_STMT_OPERAND (stmt, 1)))
-         *walk_subtree = FALSE;
-
-       if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
-           && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
-           && single_imm_use (GIMPLE_STMT_OPERAND (stmt, 0), &op, &use_stmt)
-           && TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
-           && BINARY_CLASS_P (GIMPLE_STMT_OPERAND (use_stmt, 1)))
-         *walk_subtree = FALSE;
-
-       while (*walk_subtree && handled_component_p (t))
-         {
-           if (TREE_CODE (t) == ARRAY_REF)
-             check_array_ref (t, location, true /*ignore_off_by_one*/);
-           t = TREE_OPERAND (t, 0);
-         }
-       *walk_subtree = FALSE;
+      tree arg;
+      call_expr_arg_iterator iter;
+
+      FOR_EACH_CALL_EXPR_ARG (arg, iter, t) 
+	search_for_addr_array (arg, location);
     }
 
+  if (TREE_CODE (t) == ADDR_EXPR)
+    *walk_subtree = FALSE;
+
   return NULL_TREE;
 }
 
--- testsuite/gcc.dg/Warray-bounds-3.c
+++ testsuite/gcc.dg/Warray-bounds-3.c
@@ -0,0 +1,95 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Warray-bounds" } */
+/* based on PR 31227 */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern size_t strlen (const char *);
+
+struct iovec
+{
+  void *iov_base;
+  size_t iov_len;
+};
+
+struct S
+{
+  const char *abday[7];
+  const char *day[7];
+  const char *abmon[12];
+  const char *mon[12];
+  const char *am_pm[2];
+};
+
+extern void foo (size_t, struct iovec *);
+
+void
+bar (struct S *time)
+{
+  struct iovec iov[43];
+  size_t cnt;
+  iov[0].iov_base = (void *) "abc";
+  iov[0].iov_len = 3;
+
+  iov[1].iov_base = (void *) "def";
+  iov[1].iov_len = 3;
+
+  for (cnt = 0; cnt <= 7; ++cnt)
+    {
+      iov[2 + cnt].iov_base = (void *) (time->abday[cnt] ?: "");
+      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
+    }
+
+  for (; cnt <= 14; ++cnt)
+    {
+      iov[2 + cnt].iov_base = (void *) (time->day[cnt - 7] ?: "");
+      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
+    }
+
+  for (; cnt <= 26; ++cnt)
+    {
+      iov[2 + cnt].iov_base = (void *) (time->abmon[cnt - 14] ?: "");
+      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
+    }
+
+  for (; cnt <= 38; ++cnt)
+    {
+      iov[2 + cnt].iov_base = (void *) (time->mon[cnt - 26] ?: "");
+      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
+    }
+
+  for (; cnt <= 40; ++cnt)
+    {
+      iov[2 + cnt].iov_base =  (void *) (time->am_pm[cnt - 38] ?: "");
+      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
+    }
+
+  foo (2 + cnt, iov);
+}
+
+struct malloc_chunk {
+  long prev_size;
+  long size;
+  struct malloc_chunk* fd;
+  struct malloc_chunk* bk;
+};
+typedef struct malloc_chunk* mchunkptr;
+struct malloc_state {
+  mchunkptr        top;
+  mchunkptr        last_remainder;
+  mchunkptr        bins[128 * 2 - 2];
+};
+#define bin_at(m, i) \
+  (mchunkptr) (((char *) &((m)->bins[((i) - 1) * 2]))                         
\
+             - __builtin_offsetof (struct malloc_chunk, fd))
+
+void malloc_init_state(struct malloc_state *av)
+{
+  int     i;
+  mchunkptr bin;
+
+  for (i = 1; i < 128; ++i) {
+    bin = bin_at(av,i);
+    bin->fd = bin->bk = bin;
+  }
+}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]