aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2002-03-08 14:45:13 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2002-03-08 14:45:13 +0100
commit71db7d0315cfa958ceead1b436a130cd5d21002c (patch)
treeca62fffdce452b4e9d9875e01e4aa2868d4a3388 /gcc
parent127c1ba59832e7cbca6f86a38a9c6c090f3d0361 (diff)
downloadgcc-71db7d0315cfa958ceead1b436a130cd5d21002c.zip
gcc-71db7d0315cfa958ceead1b436a130cd5d21002c.tar.gz
gcc-71db7d0315cfa958ceead1b436a130cd5d21002c.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/builtins.c51
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20020307-2.c55
4 files changed, 99 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b951136..ea61862 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+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 ...
diff --git a/gcc/builtins.c b/gcc/builtins.c
index c4aebd3..806dd0d 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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. */
- t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
- build (PLUS_EXPR, TREE_TYPE (valist), valist,
- build_int_2 (rounded_size, 0)));
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ if (! integer_zerop (rounded_size))
+ {
+ t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ build (PLUS_EXPR, TREE_TYPE (valist), valist,
+ rounded_size));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
return addr;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ffe70aa..1c06928 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+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.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20020307-2.c b/gcc/testsuite/gcc.c-torture/execute/20020307-2.c
new file mode 100644
index 0000000..0e67a2c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20020307-2.c
@@ -0,0 +1,55 @@
+/* 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);
+}