diff options
author | Geoff Keating <geoffk@cygnus.com> | 2000-03-30 00:03:14 +0000 |
---|---|---|
committer | Geoffrey Keating <geoffk@gcc.gnu.org> | 2000-03-30 00:03:14 +0000 |
commit | 9f720c3eba745cb4c97bd827c82f9c28bcbd0027 (patch) | |
tree | 20d913563a657194431e95f314f5d4189f855d3a /gcc/builtins.c | |
parent | abe79fd4da641ef2f393be1bcac0ae855035e9b1 (diff) | |
download | gcc-9f720c3eba745cb4c97bd827c82f9c28bcbd0027.zip gcc-9f720c3eba745cb4c97bd827c82f9c28bcbd0027.tar.gz gcc-9f720c3eba745cb4c97bd827c82f9c28bcbd0027.tar.bz2 |
c-common.c (c_common_nodes_and_builtins): The first parameter to __builtin_va_start and __builtin_va_copy is now either a...
* c-common.c (c_common_nodes_and_builtins): The first parameter to
__builtin_va_start and __builtin_va_copy is now either a 'va_list'
or a reference to a va_list.
* builtins.c (stabilize_va_list): Simplify now we don't have to
work around C array address decay.
* c-typeck.c (convert_for_assignment): Handle assignment to
a reference parameter by taking the address of the RHS.
* ginclude/stdarg.h (va_start): Don't take address of first parameter.
(va_copy): Likewise.
(__va_copy): Likewise.
* ginclude/varargs.h (va_start): Likewise.
(__va_copy): Likewise.
From-SVN: r32821
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 63 |
1 files changed, 20 insertions, 43 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 0271d12..94997fb 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -1901,66 +1901,43 @@ expand_builtin_next_arg (arglist) from multiple evaluations. */ static tree -stabilize_va_list (valist, was_ptr) +stabilize_va_list (valist, needs_lvalue) tree valist; - int was_ptr; + int needs_lvalue; { 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 (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 + /* For this case, the backends will be expecting a pointer to + TREE_TYPE (va_list_type_node), but it's possible we've + actually been given an array (an actual va_list_type_node). + So fix it. */ + if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE) { - 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 (); + tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node)); + tree p2 = build_pointer_type (va_list_type_node); + valist = build1 (ADDR_EXPR, p2, valist); + valist = fold (build1 (NOP_EXPR, p1, valist)); } - - if (TREE_SIDE_EFFECTS (valist)) - valist = save_expr (valist); } else { - if (! was_ptr) - { - tree pt; + tree pt; + if (! needs_lvalue) + { if (! TREE_SIDE_EFFECTS (valist)) return valist; - + pt = build_pointer_type (va_list_type_node); - valist = fold (build1 (ADDR_EXPR, pt, valist)); + valist = fold (build1 (ADDR_EXPR, pt, valist)); TREE_SIDE_EFFECTS (valist) = 1; } + if (TREE_SIDE_EFFECTS (valist)) - valist = save_expr (valist); + valist = save_expr (valist); valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist)); } |