summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-09-28 08:15:38 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-09-28 08:15:38 +0000
commit11a61dea09c60c2ef59154418facfb6e90d4d9bf (patch)
treea14d3c43fc5eb3c00ec2e264f337dbe3bd05f7e3
parent6129020e637cfc882e670ff6644481d3e17b5d41 (diff)
downloadgcc-11a61dea09c60c2ef59154418facfb6e90d4d9bf.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29690 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/builtins.c82
-rw-r--r--gcc/config/rs6000/rs6000.c2
3 files changed, 71 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c2e22a5ed58..c1bbe794752 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 250177c9c45..36a6493d645 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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 ();
}
+
+ if (TREE_SIDE_EFFECTS (valist))
+ valist = save_expr (valist);
}
- else if (TREE_SIDE_EFFECTS (valist))
+ else
{
- if (is_array)
- valist = save_expr (valist);
- 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);
}
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index a4c173ddff6..a4324615869 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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);