re PR tree-optimization/45982 (PTA does not track integers)
2010-10-13 Richard Guenther <rguenther@suse.de> PR tree-optimization/45982 * tree-ssa-structalias.c (make_constraints_to): New function. (make_constraint_to): Implement in terms of make_constraints_to. (find_func_aliases): Properly make return values of pure/const functions escape if they assign to sth that is not a pointer. * gcc.dg/torture/pr45982.c: New testcase. * gcc.dg/tree-ssa/pr24287.c: Adjust. * gcc.dg/tree-ssa/pta-callused.c: Likewise. * gcc.dg/torture/pr39074-2.c: Likewise. From-SVN: r165418
This commit is contained in:
parent
72351fa31f
commit
cb89b4b090
@ -1,3 +1,11 @@
|
||||
2010-10-13 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/45982
|
||||
* tree-ssa-structalias.c (make_constraints_to): New function.
|
||||
(make_constraint_to): Implement in terms of make_constraints_to.
|
||||
(find_func_aliases): Properly make return values of pure/const
|
||||
functions escape if they assign to sth that is not a pointer.
|
||||
|
||||
2010-10-13 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/45874
|
||||
|
@ -1,3 +1,11 @@
|
||||
2010-10-13 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/45982
|
||||
* gcc.dg/torture/pr45982.c: New testcase.
|
||||
* gcc.dg/tree-ssa/pr24287.c: Adjust.
|
||||
* gcc.dg/tree-ssa/pta-callused.c: Likewise.
|
||||
* gcc.dg/torture/pr39074-2.c: Likewise.
|
||||
|
||||
2010-10-13 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/45874
|
||||
|
@ -30,5 +30,5 @@ int main()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "y.._., points-to vars: { i }" "alias" } } */
|
||||
/* { dg-final { scan-tree-dump "y.._., points-to non-local, points-to escaped, points-to vars: { i }" "alias" } } */
|
||||
/* { dg-final { cleanup-tree-dump "alias" } } */
|
||||
|
27
gcc/testsuite/gcc.dg/torture/pr45982.c
Normal file
27
gcc/testsuite/gcc.dg/torture/pr45982.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
uintptr_t __attribute__((pure,noinline,noclone))
|
||||
foo (int *a)
|
||||
{
|
||||
return (uintptr_t) a;
|
||||
}
|
||||
|
||||
void __attribute__((noinline,noclone))
|
||||
bar (uintptr_t a)
|
||||
{
|
||||
int *p = (int *)a;
|
||||
*p = 1;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int t = 0;
|
||||
bar (foo (&t));
|
||||
if (t != 1)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
@ -9,11 +9,14 @@ void link_error();
|
||||
int g(void)
|
||||
{
|
||||
int t = 0, t1 = 2;
|
||||
/* ??? That's not true. The pointers escape to the integer return
|
||||
value which we do not track in PTA. */
|
||||
int t2 = h(&t, &t1);
|
||||
if (t != 0)
|
||||
link_error ();
|
||||
if (t1 != 2)
|
||||
link_error ();
|
||||
/* ??? And it would finally escape here even if we did. */
|
||||
g1(t2);
|
||||
if (t != 0)
|
||||
link_error ();
|
||||
@ -21,5 +24,6 @@ int g(void)
|
||||
link_error ();
|
||||
return t2 == 2;
|
||||
}
|
||||
/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" } } */
|
||||
/* We are allowed to optimize the first two link_error calls. */
|
||||
/* { dg-final { scan-tree-dump-times "link_error" 2 "optimized" } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
||||
|
@ -5,7 +5,7 @@ struct Foo {
|
||||
int *p, *q;
|
||||
};
|
||||
|
||||
int foo (int ***x) __attribute__((pure));
|
||||
int *foo (int ***x) __attribute__((pure));
|
||||
|
||||
int bar (int b)
|
||||
{
|
||||
@ -19,7 +19,7 @@ int bar (int b)
|
||||
q = &f.p;
|
||||
else
|
||||
q = &f.q;
|
||||
return foo (&q);
|
||||
return *foo (&q);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "CALLUSED = { f.* i q }" "alias" } } */
|
||||
|
@ -3563,12 +3563,11 @@ do_structure_copy (tree lhsop, tree rhsop)
|
||||
VEC_free (ce_s, heap, rhsc);
|
||||
}
|
||||
|
||||
/* Create a constraint ID = OP. */
|
||||
/* Create constraints ID = { rhsc }. */
|
||||
|
||||
static void
|
||||
make_constraint_to (unsigned id, tree op)
|
||||
make_constraints_to (unsigned id, VEC(ce_s, heap) *rhsc)
|
||||
{
|
||||
VEC(ce_s, heap) *rhsc = NULL;
|
||||
struct constraint_expr *c;
|
||||
struct constraint_expr includes;
|
||||
unsigned int j;
|
||||
@ -3577,9 +3576,18 @@ make_constraint_to (unsigned id, tree op)
|
||||
includes.offset = 0;
|
||||
includes.type = SCALAR;
|
||||
|
||||
get_constraint_for_rhs (op, &rhsc);
|
||||
FOR_EACH_VEC_ELT (ce_s, rhsc, j, c)
|
||||
process_constraint (new_constraint (includes, *c));
|
||||
}
|
||||
|
||||
/* Create a constraint ID = OP. */
|
||||
|
||||
static void
|
||||
make_constraint_to (unsigned id, tree op)
|
||||
{
|
||||
VEC(ce_s, heap) *rhsc = NULL;
|
||||
get_constraint_for_rhs (op, &rhsc);
|
||||
make_constraints_to (id, rhsc);
|
||||
VEC_free (ce_s, heap, rhsc);
|
||||
}
|
||||
|
||||
@ -4334,8 +4342,7 @@ find_func_aliases (gimple origt)
|
||||
of global memory but not of escaped memory. */
|
||||
if (flags & (ECF_CONST|ECF_NOVOPS))
|
||||
{
|
||||
if (gimple_call_lhs (t)
|
||||
&& could_have_pointers (gimple_call_lhs (t)))
|
||||
if (gimple_call_lhs (t))
|
||||
handle_const_call (t, &rhsc);
|
||||
}
|
||||
/* Pure functions can return addresses in and of memory
|
||||
@ -4345,9 +4352,17 @@ find_func_aliases (gimple origt)
|
||||
handle_pure_call (t, &rhsc);
|
||||
else
|
||||
handle_rhs_call (t, &rhsc);
|
||||
if (gimple_call_lhs (t)
|
||||
&& could_have_pointers (gimple_call_lhs (t)))
|
||||
handle_lhs_call (t, gimple_call_lhs (t), flags, rhsc, fndecl);
|
||||
if (gimple_call_lhs (t))
|
||||
{
|
||||
if (could_have_pointers (gimple_call_lhs (t)))
|
||||
handle_lhs_call (t, gimple_call_lhs (t), flags, rhsc, fndecl);
|
||||
/* Similar to conversions a result that is not a pointer
|
||||
is an escape point for any pointer the function might
|
||||
return. */
|
||||
else if (flags & (ECF_CONST|ECF_PURE
|
||||
|ECF_NOVOPS|ECF_LOOPING_CONST_OR_PURE))
|
||||
make_constraints_to (escaped_id, rhsc);
|
||||
}
|
||||
VEC_free (ce_s, heap, rhsc);
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user