aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDirk Mueller <dmueller@suse.de>2007-04-18 20:09:21 +0000
committerDirk Mueller <mueller@gcc.gnu.org>2007-04-18 20:09:21 +0000
commit05fb69e4c9ce7e8767d36e5bfb5c0e6e67d3b905 (patch)
tree62909f2190eec0ab07088cbefcf865ed93cdca51
parent28e44f4fe6750b8e7389f496f2267dcf3bc2117c (diff)
downloadgcc-05fb69e4c9ce7e8767d36e5bfb5c0e6e67d3b905.zip
gcc-05fb69e4c9ce7e8767d36e5bfb5c0e6e67d3b905.tar.gz
gcc-05fb69e4c9ce7e8767d36e5bfb5c0e6e67d3b905.tar.bz2
re PR tree-optimization/31227 (-Warray-bounds doesn't play together with loop optimizations)
2007-04-18 Dirk Mueller <dmueller@suse.de> PR diagnostic/31227 * tree-vrp.c (search_for_addr_array): New. (check_array_bounds): Suppress warning about address taken of array refs if its not de-referenced. * gcc.dg/Warray-bounds-3.c: New. From-SVN: r123958
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-3.c108
-rw-r--r--gcc/tree-vrp.c76
4 files changed, 162 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b1671cf..db9ff5c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2007-04-18 Dirk Mueller <dmueller@suse.de>
+
+ PR diagnostic/31227
+ * tree-vrp.c (search_for_addr_array): New.
+ (check_array_bounds): Suppress warning about
+ address taken of array refs if its not de-referenced.
+
2007-04-18 Dorit Nuzman <dorit@il.ibm.com>
* tree-vectorizer.c (destroy_loop_vec_info): Set loop->aux to NULL.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bcea225..06c53cf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-04-18 Dirk Mueller <dmueller@suse.de>
+
+ PR diagnostic/31227
+ * gcc.dg/Warray-bounds-3.c: New.
+
2007-04-18 Richard Guenther <rguenther@suse.de>
PR tree-optimization/19431
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-3.c
new file mode 100644
index 0000000..19cdb8e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-3.c
@@ -0,0 +1,108 @@
+/* { 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;
+ }
+}
+
+typedef unsigned short WCHAR;
+typedef WCHAR *LPWSTR;
+
+static void g(LPWSTR dest, int len) {
+ dest[len-1] = 0;
+}
+
+void f() {
+ WCHAR szPathW[260];
+
+ g(szPathW, 260);
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 43cd0eb..e35a6e9 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4233,6 +4233,36 @@ check_array_ref (tree ref, location_t* locus, bool ignore_off_by_one)
}
}
+/* 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
@@ -4250,44 +4280,22 @@ check_array_bounds (tree *tp, int *walk_subtree, void *data)
if (TREE_CODE (t) == ARRAY_REF)
check_array_ref (t, location, false /*ignore_off_by_one*/);
- else if (TREE_CODE (t) == ADDR_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;
+ 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)
+ {
+ tree arg;
+ call_expr_arg_iterator iter;
- 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;
+ 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;
}