From 05fb69e4c9ce7e8767d36e5bfb5c0e6e67d3b905 Mon Sep 17 00:00:00 2001 From: Dirk Mueller Date: Wed, 18 Apr 2007 20:09:21 +0000 Subject: [PATCH] re PR tree-optimization/31227 (-Warray-bounds doesn't play together with loop optimizations) 2007-04-18 Dirk Mueller 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 --- gcc/ChangeLog | 7 ++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/Warray-bounds-3.c | 108 +++++++++++++++++++++++++ gcc/tree-vrp.c | 76 +++++++++-------- 4 files changed, 162 insertions(+), 34 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1671cf1359..db9ff5cf837 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-04-18 Dirk Mueller + + 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 * tree-vectorizer.c (destroy_loop_vec_info): Set loop->aux to NULL. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bcea2252ec5..06c53cf2104 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-04-18 Dirk Mueller + + PR diagnostic/31227 + * gcc.dg/Warray-bounds-3.c: New. + 2007-04-18 Richard Guenther 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 00000000000..19cdb8e5fe1 --- /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 43cd0eb967f..e35a6e9008d 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; } -- 2.30.2