From: Richard Henderson Date: Tue, 28 Sep 1999 08:15:38 +0000 (-0700) Subject: builtins.c (stabilize_va_list): Stabilize array type va_list to a pointer type, not... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8ebecc3b1c66783ed62d5af14148c0778ac66131;p=platform%2Fupstream%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c2e22a5..c1bbe79 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +Tue Sep 28 01:11:05 1999 Richard Henderson + + * 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 * rtl.h (struct rtx_def): Move gc_mark to align mode field. diff --git a/gcc/builtins.c b/gcc/builtins.c index 250177c..36a6493 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 + valist>> + or &ptr, which turned into + >> + 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 a4c173d..a432461 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);