This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Some cleanups after the PTA patches
On Sun, 29 Jun 2008, H.J. Lu wrote:
Hi Richard,
I think it caused:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36671
And this fixes the uncovered latent problem. We certainly didn't expect
arbitrary functions being marked with the malloc attribute.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to
mainline.
Richard.
2008-06-30 Richard Guenther <rguenther@suse.de>
PR middle-end/36671
* tree-ssa-structalias.c (handle_lhs_call): Add flags argument,
handle calls from ECF_MALLOC functions.
(handle_pure_call): ECF_MALLOC functions do not return
call-used memory.
(find_func_aliases): Handle all calls, adjust calls to handle_lhs_call.
Index: tree-ssa-structalias.c
===================================================================
*** tree-ssa-structalias.c (revision 137268)
--- tree-ssa-structalias.c (working copy)
*************** handle_rhs_call (tree rhs)
*** 3381,3387 ****
the LHS point to global and escaped variables. */
static void
! handle_lhs_call (tree lhs)
{
VEC(ce_s, heap) *lhsc = NULL;
struct constraint_expr rhsc;
--- 3381,3387 ----
the LHS point to global and escaped variables. */
static void
! handle_lhs_call (tree lhs, int flags)
{
VEC(ce_s, heap) *lhsc = NULL;
struct constraint_expr rhsc;
*************** handle_lhs_call (tree lhs)
*** 3389,3397 ****
struct constraint_expr *lhsp;
get_constraint_for (lhs, &lhsc);
! rhsc.var = escaped_id;
! rhsc.offset = 0;
! rhsc.type = ADDRESSOF;
for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp); j++)
process_constraint (new_constraint (*lhsp, rhsc));
VEC_free (ce_s, heap, lhsc);
--- 3389,3424 ----
struct constraint_expr *lhsp;
get_constraint_for (lhs, &lhsc);
!
! if (flags & ECF_MALLOC)
! {
! tree heapvar = heapvar_lookup (lhs);
! varinfo_t vi;
!
! if (heapvar == NULL)
! {
! heapvar = create_tmp_var_raw (ptr_type_node, "HEAP");
! DECL_EXTERNAL (heapvar) = 1;
! get_var_ann (heapvar)->is_heapvar = 1;
! if (gimple_referenced_vars (cfun))
! add_referenced_var (heapvar);
! heapvar_insert (lhs, heapvar);
! }
!
! rhsc.var = create_variable_info_for (heapvar,
! alias_get_name (heapvar));
! vi = get_varinfo (rhsc.var);
! vi->is_artificial_var = 1;
! vi->is_heap_var = 1;
! rhsc.type = ADDRESSOF;
! rhsc.offset = 0;
! }
! else
! {
! rhsc.var = escaped_id;
! rhsc.offset = 0;
! rhsc.type = ADDRESSOF;
! }
for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp); j++)
process_constraint (new_constraint (*lhsp, rhsc));
VEC_free (ce_s, heap, lhsc);
*************** handle_pure_call (tree stmt)
*** 3470,3478 ****
make_constraint_to (callused_id, CALL_EXPR_STATIC_CHAIN (call));
/* If the call returns a pointer it may point to reachable memory
! from the arguments. */
if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
! && could_have_pointers (GIMPLE_STMT_OPERAND (stmt, 0)))
{
tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
VEC(ce_s, heap) *lhsc = NULL;
--- 3497,3506 ----
make_constraint_to (callused_id, CALL_EXPR_STATIC_CHAIN (call));
/* If the call returns a pointer it may point to reachable memory
! from the arguments. Not so for malloc functions though. */
if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
! && could_have_pointers (GIMPLE_STMT_OPERAND (stmt, 0))
! && !(call_expr_flags (call) & ECF_MALLOC))
{
tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
VEC(ce_s, heap) *lhsc = NULL;
*************** find_func_aliases (tree origt)
*** 3518,3524 ****
VEC(ce_s, heap) *rhsc = NULL;
struct constraint_expr *c;
enum escape_type stmt_escape_type;
- int flags;
if (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0))
t = TREE_OPERAND (t, 0);
--- 3546,3551 ----
*************** find_func_aliases (tree origt)
*** 3567,3576 ****
In non-ipa mode, we need to generate constraints for each
pointer passed by address. */
! else if ((call = get_call_expr_in (t)) != NULL_TREE
! && !((flags = call_expr_flags (call))
! & (ECF_MALLOC | ECF_MAY_BE_ALLOCA)))
{
if (!in_ipa_mode)
{
/* Const functions can return their arguments and addresses
--- 3594,3602 ----
In non-ipa mode, we need to generate constraints for each
pointer passed by address. */
! else if ((call = get_call_expr_in (t)) != NULL_TREE)
{
+ int flags = call_expr_flags (call);
if (!in_ipa_mode)
{
/* Const functions can return their arguments and addresses
*************** find_func_aliases (tree origt)
*** 3586,3592 ****
handle_pure_call (t);
if (TREE_CODE (t) == GIMPLE_MODIFY_STMT
&& could_have_pointers (GIMPLE_STMT_OPERAND (t, 1)))
! handle_lhs_call (GIMPLE_STMT_OPERAND (t, 0));
}
/* Pure functions can return addresses in and of memory
reachable from their arguments, but they are not an escape
--- 3612,3618 ----
handle_pure_call (t);
if (TREE_CODE (t) == GIMPLE_MODIFY_STMT
&& could_have_pointers (GIMPLE_STMT_OPERAND (t, 1)))
! handle_lhs_call (GIMPLE_STMT_OPERAND (t, 0), flags);
}
/* Pure functions can return addresses in and of memory
reachable from their arguments, but they are not an escape
*************** find_func_aliases (tree origt)
*** 3597,3603 ****
{
handle_rhs_call (GIMPLE_STMT_OPERAND (t, 1));
if (could_have_pointers (GIMPLE_STMT_OPERAND (t, 1)))
! handle_lhs_call (GIMPLE_STMT_OPERAND (t, 0));
}
else
handle_rhs_call (t);
--- 3623,3629 ----
{
handle_rhs_call (GIMPLE_STMT_OPERAND (t, 1));
if (could_have_pointers (GIMPLE_STMT_OPERAND (t, 1)))
! handle_lhs_call (GIMPLE_STMT_OPERAND (t, 0), flags);
}
else
handle_rhs_call (t);