aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorGeoff Keating <geoffk@cygnus.com>2000-03-30 00:03:14 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>2000-03-30 00:03:14 +0000
commit9f720c3eba745cb4c97bd827c82f9c28bcbd0027 (patch)
tree20d913563a657194431e95f314f5d4189f855d3a /gcc/builtins.c
parentabe79fd4da641ef2f393be1bcac0ae855035e9b1 (diff)
downloadgcc-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.c63
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));
}