diff options
author | Jakub Jelinek <jakub@redhat.com> | 2002-03-08 14:45:13 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2002-03-08 14:45:13 +0100 |
commit | 71db7d0315cfa958ceead1b436a130cd5d21002c (patch) | |
tree | ca62fffdce452b4e9d9875e01e4aa2868d4a3388 | |
parent | 127c1ba59832e7cbca6f86a38a9c6c090f3d0361 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/builtins.c | 51 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20020307-2.c | 55 |
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); +} |