Commit 71db7d03 by Jakub Jelinek Committed by Jakub Jelinek

re PR c/3711 (ICE in instantiate_virtual_regs_1, at function.c:3880)

	PR c/3711
	* builtins.c (std_expand_builtin_va_arg): Do all computations on
	trees.

	* gcc.c-torture/execute/20020307-2.c: New test.

From-SVN: r50438
parent 127c1ba5
2002-03-08 Jakub Jelinek <jakub@redhat.com>
PR c/3711
* builtins.c (std_expand_builtin_va_arg): Do all computations on
trees.
Fri Mar 8 06:48:45 2002 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* rtl.c (copy_most_rtx): Move from here ...
......
......@@ -2986,37 +2986,54 @@ rtx
std_expand_builtin_va_arg (valist, type)
tree valist, type;
{
tree addr_tree, t;
HOST_WIDE_INT align;
HOST_WIDE_INT rounded_size;
tree addr_tree, t, type_size = NULL;
tree align, alignm1;
tree rounded_size;
rtx addr;
/* Compute the rounded size of the type. */
align = PARM_BOUNDARY / BITS_PER_UNIT;
rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
if (type == error_mark_node
|| (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
|| TREE_OVERFLOW (type_size))
rounded_size = size_zero_node;
else
rounded_size = fold (build (MULT_EXPR, sizetype,
fold (build (TRUNC_DIV_EXPR, sizetype,
fold (build (PLUS_EXPR, sizetype,
type_size, alignm1)),
align)),
align));
/* Get AP. */
addr_tree = valist;
if (PAD_VARARGS_DOWN)
if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
{
/* Small args are padded downward. */
HOST_WIDE_INT adj
= rounded_size > align ? rounded_size : int_size_in_bytes (type);
addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
build_int_2 (rounded_size - adj, 0));
addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
fold (build (COND_EXPR, sizetype,
fold (build (GT_EXPR, sizetype,
rounded_size,
align)),
size_zero_node,
fold (build (MINUS_EXPR, sizetype,
rounded_size,
type_size))))));
}
addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
addr = copy_to_reg (addr);
/* Compute new value for AP. */
if (! integer_zerop (rounded_size))
{
t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
build (PLUS_EXPR, TREE_TYPE (valist), valist,
build_int_2 (rounded_size, 0)));
rounded_size));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
return addr;
}
......
2002-03-08 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/20020307-2.c: New test.
Thu Mar 7 10:05:31 2002 Jeffrey A Law (law@redhat.com)
* g77.f-torture/compile/20020307-1.f: New test.
......
/* PR c/3711
This testcase ICEd on IA-32 at -O0 and was miscompiled otherwise,
because std_expand_builtin_va_arg didn't handle variable size types. */
#include <stdarg.h>
extern void abort (void);
extern void exit (int);
void bar (int c)
{
static int d = '0';
if (c != d++)
abort ();
if (c < '0' || c > '9')
abort ();
}
void foo (int size, ...)
{
struct
{
char x[size];
} d;
va_list ap;
int i;
va_start (ap, size);
d = va_arg (ap, typeof (d));
for (i = 0; i < size; i++)
bar (d.x[i]);
d = va_arg (ap, typeof (d));
for (i = 0; i < size; i++)
bar (d.x[i]);
va_end (ap);
}
int main (void)
{
struct { char a[5]; } x, y;
x.a[0] = '0';
x.a[1] = '1';
x.a[2] = '2';
x.a[3] = '3';
x.a[4] = '4';
y.a[0] = '5';
y.a[1] = '6';
y.a[2] = '7';
y.a[3] = '8';
y.a[4] = '9';
foo (5, x, y);
exit (0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment