mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 23:30:59 +08:00
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
This commit is contained in:
parent
5e49cb95ea
commit
8ebecc3b1c
gcc
@ -1,3 +1,13 @@
|
||||
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>
|
||||
|
||||
* rtl.h (struct rtx_def): Move gc_mark to align mode field.
|
||||
|
@ -1826,40 +1826,64 @@ stabilize_va_list (valist, was_ptr)
|
||||
tree valist;
|
||||
int was_ptr;
|
||||
{
|
||||
int is_array = TREE_CODE (va_list_type_node) == ARRAY_TYPE;
|
||||
|
||||
if (was_ptr)
|
||||
if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
|
||||
{
|
||||
/* 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
|
||||
rather than the array as we'd intended. Undo this mistake. */
|
||||
if (is_array
|
||||
&& TREE_CODE (valist) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (valist, 0))) == POINTER_TYPE)
|
||||
|
||||
if (was_ptr)
|
||||
{
|
||||
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);
|
||||
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
|
||||
{
|
||||
if (TREE_SIDE_EFFECTS (valist))
|
||||
valist = save_expr (valist);
|
||||
valist = fold (build1 (INDIRECT_REF, va_list_type_node, valist));
|
||||
if (! POINTER_TYPE_P (TREE_TYPE (valist))
|
||||
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (valist)))
|
||||
!= TYPE_MAIN_VARIANT (TREE_TYPE (va_list_type_node))))
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
else if (TREE_SIDE_EFFECTS (valist))
|
||||
{
|
||||
if (is_array)
|
||||
|
||||
if (TREE_SIDE_EFFECTS (valist))
|
||||
valist = save_expr (valist);
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! was_ptr)
|
||||
{
|
||||
valist = build1 (ADDR_EXPR, build_pointer_type (va_list_type_node),
|
||||
valist);
|
||||
tree pt;
|
||||
|
||||
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;
|
||||
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;
|
||||
@ -2095,10 +2119,22 @@ expand_builtin_va_copy (arglist)
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_block_move (expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL),
|
||||
expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL),
|
||||
expand_expr (TYPE_SIZE (va_list_type_node), NULL_RTX,
|
||||
VOIDmode, EXPAND_NORMAL),
|
||||
rtx dstb, srcb, size;
|
||||
|
||||
/* Evaluate to pointers. */
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1833,6 +1833,7 @@ rs6000_va_start (stdarg_p, valist, nextarg)
|
||||
f_ovf = TREE_CHAIN (f_fpr);
|
||||
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);
|
||||
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
|
||||
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
|
||||
@ -1893,6 +1894,7 @@ rs6000_va_arg (valist, type)
|
||||
f_ovf = TREE_CHAIN (f_fpr);
|
||||
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);
|
||||
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
|
||||
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
|
||||
|
Loading…
x
Reference in New Issue
Block a user