Add copy for va_list parameter
---
gcc/function.c | 29 +++++++++++++++++++++++++++++
gcc/gimplify.c | 16 ----------------
2 files changed, 29 insertions(+), 16 deletions(-)
@@ -3855,6 +3855,24 @@ gimplify_parm_type (tree *tp, int *walk_subtrees, void *data)
return NULL;
}
+static inline bool
+is_va_list_type (tree type)
+{
+ tree id = TYPE_IDENTIFIER (type);
+ if (id == NULL_TREE)
+ return false;
+ const char *s = IDENTIFIER_POINTER (id);
+ if (s == NULL)
+ return false;
+ if (strcmp (s, "va_list") == 0)
+ return true;
+ if (strcmp (s, "__builtin_sysv_va_list") == 0)
+ return true;
+ if (strcmp (s, "__builtin_ms_va_list") == 0)
+ return true;
+ return false;
+}
+
/* Gimplify the parameter list for current_function_decl. This involves
evaluating SAVE_EXPRs of variable sized parameters and generating code
to implement callee-copies reference parameters. Returns a sequence of
@@ -3953,6 +3971,17 @@ gimplify_parameters (void)
DECL_HAS_VALUE_EXPR_P (parm) = 1;
}
}
+ else if (is_va_list_type (TREE_TYPE (parm)))
+ {
+ tree cp = create_tmp_reg (data.nominal_type, get_name (parm));
+ DECL_IGNORED_P (cp) = 0;
+ TREE_ADDRESSABLE (cp) = 1;
+ tree t = build2 (MODIFY_EXPR, TREE_TYPE (cp), cp, parm);
+ gimplify_and_add (t, &stmts);
+
+ SET_DECL_VALUE_EXPR (parm, cp);
+ DECL_HAS_VALUE_EXPR_P (parm) = 1;
+ }
}
fnargs.release ();
@@ -4569,7 +4569,6 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
gimple assign;
location_t loc = EXPR_LOCATION (*expr_p);
gimple_stmt_iterator gsi;
- tree ap = NULL_TREE, ap_copy = NULL_TREE;
gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
|| TREE_CODE (*expr_p) == INIT_EXPR);
@@ -4730,16 +4729,12 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
auto_vec<tree> vargs (nargs);
- if (ifn == IFN_VA_ARG)
- ap = unshare_expr (CALL_EXPR_ARG (*from_p, 0));
for (i = 0; i < nargs; i++)
{
gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
EXPR_LOCATION (*from_p));
vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
}
- if (ifn == IFN_VA_ARG)
- ap_copy = CALL_EXPR_ARG (*from_p, 0);
call_stmt = gimple_build_call_internal_vec (ifn, vargs);
gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
}
@@ -4784,17 +4779,6 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
gsi = gsi_last (*pre_p);
maybe_fold_stmt (&gsi);
- /* When gimplifying the &ap argument of va_arg, we might end up with
- ap.1 = ap
- va_arg (&ap.1, 0B)
- We need to assign ap.1 back to ap, otherwise va_arg has no effect on
- ap. */
- if (ap != NULL_TREE
- && TREE_CODE (ap) == ADDR_EXPR
- && TREE_CODE (ap_copy) == ADDR_EXPR
- && !operand_equal_p (TREE_OPERAND (ap, 0), TREE_OPERAND (ap_copy, 0), 0))
- gimplify_assign (TREE_OPERAND (ap, 0), TREE_OPERAND (ap_copy, 0), pre_p);
-
if (want_value)
{
*expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
--
1.9.1