aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>2004-06-10 11:49:49 -0400
committerJason Merrill <jason@gcc.gnu.org>2004-06-10 11:49:49 -0400
commit23a60a0436f48f1de4e5bf124f29f0e4a32e7d4e (patch)
tree97aaa6402c26723b11a9196283dc0e2e9dd4e5dc /gcc/builtins.c
parent339586c817ea6e5481d1d10f604f50c81ead3645 (diff)
downloadgcc-23a60a0436f48f1de4e5bf124f29f0e4a32e7d4e.zip
gcc-23a60a0436f48f1de4e5bf124f29f0e4a32e7d4e.tar.gz
gcc-23a60a0436f48f1de4e5bf124f29f0e4a32e7d4e.tar.bz2
target.h (struct gcc_target): Change gimplify_va_arg_expr hook signature.
* target.h (struct gcc_target): Change gimplify_va_arg_expr hook signature. * tree-gimple.h: Adjust. * config/alpha/alpha.c (alpha_gimplify_va_arg): Adjust. * config/i386/i386.c (ix86_gimplify_va_arg): Adjust. Use fold_convert. * config/ia64/ia64.c (ia64_gimplify_va_arg): Adjust. * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Adjust. Use COMPLEX_EXPR for complex numbers. Use fold_convert. * builtins.c (std_gimplify_va_arg_expr): Adjust. Use fold_convert. (gimplify_va_arg_expr): Return GS_ERROR in error case. Gimplify valist rather than calling stabilize_va_list. From-SVN: r82925
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 793d7bc..384173f 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -4364,24 +4364,19 @@ expand_builtin_va_arg (tree valist, tree type)
/* Like std_expand_builtin_va_arg, but gimplify instead of expanding. */
-void
-std_gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
+tree
+std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
{
tree addr, t, type_size = NULL;
tree align, alignm1;
tree rounded_size;
HOST_WIDE_INT boundary;
- tree valist = TREE_OPERAND (*expr_p, 0);
- tree type = TREE_TYPE (*expr_p);
/* Compute the rounded size of the type. */
align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
- /* Reduce valist it so it's sharable with the postqueue. */
- gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
-
/* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
requires greater alignment, we must perform dynamic alignment. */
@@ -4434,9 +4429,6 @@ std_gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
type_size))))));
}
- addr = convert (build_pointer_type (type), addr);
- *expr_p = build1 (INDIRECT_REF, type, addr);
-
/* Compute new value for AP. */
if (! integer_zerop (rounded_size))
{
@@ -4446,6 +4438,9 @@ std_gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
gimplify_stmt (&t);
append_to_statement_list (t, post_p);
}
+
+ addr = fold_convert (build_pointer_type (type), addr);
+ return build_fold_indirect_ref (addr);
}
/* Return a dummy expression of type TYPE in order to keep going after an
@@ -4489,8 +4484,7 @@ gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
{
error ("first argument to `va_arg' not of type `va_list'");
- *expr_p = dummy_object (type);
- return GS_ALL_DONE;
+ return GS_ERROR;
}
/* Generate a diagnostic for requesting data of a type that cannot
@@ -4528,14 +4522,27 @@ gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
{
/* Make it easier for the backends by protecting the valist argument
from multiple evaluations. */
- valist = stabilize_va_list (valist, 0);
- TREE_OPERAND (*expr_p, 0) = valist;
+ if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
+ {
+ /* For this case, the backends will be expecting a pointer to
+ TREE_TYPE (va_list_type_node), but it's possible we've
+ actually been given an array (an actual va_list_type_node).
+ So fix it. */
+ if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
+ {
+ tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
+ valist = build_fold_addr_expr_with_type (valist, p1);
+ }
+ gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
+ }
+ else
+ gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
if (!targetm.calls.gimplify_va_arg_expr)
/* Once most targets are converted this should abort. */
return GS_ALL_DONE;
- targetm.calls.gimplify_va_arg_expr (expr_p, pre_p, post_p);
+ *expr_p = targetm.calls.gimplify_va_arg_expr (valist, type, pre_p, post_p);
return GS_OK;
}
}