diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-09-28 08:15:38 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-09-28 08:15:38 +0000 |
commit | 11a61dea09c60c2ef59154418facfb6e90d4d9bf (patch) | |
tree | a14d3c43fc5eb3c00ec2e264f337dbe3bd05f7e3 | |
parent | 6129020e637cfc882e670ff6644481d3e17b5d41 (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/builtins.c | 82 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 2 |
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); |