Commit 8ebecc3b by Richard Henderson Committed by Richard Henderson

builtins.c (stabilize_va_list): Stabilize array type va_list to a pointer type,…

builtins.c (stabilize_va_list): Stabilize array type va_list to a pointer type, not the base record type.

        * builtins.c (stabilize_va_list): Stabilize array type va_list
        to a pointer type, not the base record type.
        (expand_builtin_va_copy): Dereference the pointers explicitly;
        use the correct size for the copy.

        * rs6000.c (rs6000_va_start): Dereference valist to get to the record.
        (rs6000_va_arg): Likewise.

From-SVN: r29690
parent 5e49cb95
Tue Sep 28 01:11:05 1999 Richard Henderson <rth@cygnus.com>
* builtins.c (stabilize_va_list): Stabilize array type va_list
to a pointer type, not the base record type.
(expand_builtin_va_copy): Dereference the pointers explicitly;
use the correct size for the copy.
* rs6000.c (rs6000_va_start): Dereference valist to get to the record.
(rs6000_va_arg): Likewise.
Mon Sep 27 23:27:21 1999 Richard Henderson <rth@cygnus.com> Mon Sep 27 23:27:21 1999 Richard Henderson <rth@cygnus.com>
* rtl.h (struct rtx_def): Move gc_mark to align mode field. * rtl.h (struct rtx_def): Move gc_mark to align mode field.
......
...@@ -1826,40 +1826,64 @@ stabilize_va_list (valist, was_ptr) ...@@ -1826,40 +1826,64 @@ stabilize_va_list (valist, was_ptr)
tree valist; tree valist;
int was_ptr; int was_ptr;
{ {
int is_array = TREE_CODE (va_list_type_node) == ARRAY_TYPE; if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
if (was_ptr)
{ {
/* If stdarg.h took the address of an array-type valist that was passed /* If stdarg.h took the address of an array-type valist that was passed
as a parameter, we'll have taken the address of the parameter itself as a parameter, we'll have taken the address of the parameter itself
rather than the array as we'd intended. Undo this mistake. */ rather than the array as we'd intended. Undo this mistake. */
if (is_array
&& TREE_CODE (valist) == ADDR_EXPR if (was_ptr)
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (valist, 0))) == POINTER_TYPE)
{ {
STRIP_NOPS (valist);
/* Two cases: either &array, which decomposed to
<ptr <array <record> valist>>
or &ptr, which turned into
<ptr <ptr <record>>>
In the first case we'll need to put the ADDR_EXPR back
after frobbing the types as if &array[0]. */
if (TREE_CODE (valist) != ADDR_EXPR)
abort ();
valist = TREE_OPERAND (valist, 0); valist = TREE_OPERAND (valist, 0);
if (TREE_SIDE_EFFECTS (valist)) }
valist = save_expr (valist);
if (TYPE_MAIN_VARIANT (TREE_TYPE (valist))
== TYPE_MAIN_VARIANT (va_list_type_node))
{
tree pt = build_pointer_type (TREE_TYPE (va_list_type_node));
valist = build1 (ADDR_EXPR, pt, valist);
TREE_SIDE_EFFECTS (valist)
= TREE_SIDE_EFFECTS (TREE_OPERAND (valist, 0));
} }
else else
{ {
if (TREE_SIDE_EFFECTS (valist)) if (! POINTER_TYPE_P (TREE_TYPE (valist))
valist = save_expr (valist); || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (valist)))
valist = fold (build1 (INDIRECT_REF, va_list_type_node, valist)); != TYPE_MAIN_VARIANT (TREE_TYPE (va_list_type_node))))
abort ();
} }
if (TREE_SIDE_EFFECTS (valist))
valist = save_expr (valist);
} }
else if (TREE_SIDE_EFFECTS (valist)) else
{ {
if (is_array) if (! was_ptr)
valist = save_expr (valist);
else
{ {
valist = build1 (ADDR_EXPR, build_pointer_type (va_list_type_node), tree pt;
valist);
if (! TREE_SIDE_EFFECTS (valist))
return valist;
pt = build_pointer_type (va_list_type_node);
valist = fold (build1 (ADDR_EXPR, pt, valist));
TREE_SIDE_EFFECTS (valist) = 1; TREE_SIDE_EFFECTS (valist) = 1;
valist = save_expr (valist);
valist = fold (build1 (INDIRECT_REF, va_list_type_node, valist));
} }
if (TREE_SIDE_EFFECTS (valist))
valist = save_expr (valist);
valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
valist));
} }
return valist; return valist;
...@@ -2095,10 +2119,22 @@ expand_builtin_va_copy (arglist) ...@@ -2095,10 +2119,22 @@ expand_builtin_va_copy (arglist)
} }
else else
{ {
emit_block_move (expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL), rtx dstb, srcb, size;
expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL),
expand_expr (TYPE_SIZE (va_list_type_node), NULL_RTX, /* Evaluate to pointers. */
VOIDmode, EXPAND_NORMAL), dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
VOIDmode, EXPAND_NORMAL);
/* "Dereference" to BLKmode memories. */
dstb = gen_rtx_MEM (BLKmode, dstb);
MEM_ALIAS_SET (dstb) = get_alias_set (TREE_TYPE (TREE_TYPE (dst)));
srcb = gen_rtx_MEM (BLKmode, srcb);
MEM_ALIAS_SET (srcb) = get_alias_set (TREE_TYPE (TREE_TYPE (src)));
/* Copy. */
emit_block_move (dstb, srcb, size,
TYPE_ALIGN (va_list_type_node) / BITS_PER_UNIT); TYPE_ALIGN (va_list_type_node) / BITS_PER_UNIT);
} }
......
...@@ -1833,6 +1833,7 @@ rs6000_va_start (stdarg_p, valist, nextarg) ...@@ -1833,6 +1833,7 @@ rs6000_va_start (stdarg_p, valist, nextarg)
f_ovf = TREE_CHAIN (f_fpr); f_ovf = TREE_CHAIN (f_fpr);
f_sav = TREE_CHAIN (f_ovf); f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr); gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr); fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf); ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
...@@ -1893,6 +1894,7 @@ rs6000_va_arg (valist, type) ...@@ -1893,6 +1894,7 @@ rs6000_va_arg (valist, type)
f_ovf = TREE_CHAIN (f_fpr); f_ovf = TREE_CHAIN (f_fpr);
f_sav = TREE_CHAIN (f_ovf); f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr); gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr); fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf); ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment