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
This commit is contained in:
parent
28e44f4fe6
commit
05fb69e4c9
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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)
|
||||
|
||||
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);
|
||||
tree arg;
|
||||
call_expr_arg_iterator iter;
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue