From: Jakub Jelinek Date: Thu, 30 Sep 2010 20:21:28 +0000 (+0200) Subject: re PR target/45843 (__builtin_va_arg overwrites into adjacent stack location) X-Git-Tag: releases/gcc-4.6.0~4014 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=45c13d4cec5c33c3971a42d673503e93c2fbb424;p=thirdparty%2Fgcc.git re PR target/45843 (__builtin_va_arg overwrites into adjacent stack location) PR target/45843 * config/i386/i386.c (ix86_gimplify_va_arg): Use INTVAL (XEXP (slot, 1)) as prev_size. * g++.dg/torture/pr45843.C: New test. From-SVN: r164766 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7795da141d53..b82c99de6e81 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-09-30 Jakub Jelinek + + PR target/45843 + * config/i386/i386.c (ix86_gimplify_va_arg): Use + INTVAL (XEXP (slot, 1)) as prev_size. + 2010-09-30 Michael Meissner PR target/45837 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c36ad74b1570..0998f314975e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -7524,6 +7524,8 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, tree dest_addr, dest; int cur_size = GET_MODE_SIZE (mode); + gcc_assert (prev_size <= INTVAL (XEXP (slot, 1))); + prev_size = INTVAL (XEXP (slot, 1)); if (prev_size + cur_size > size) { cur_size = size - prev_size; @@ -7556,7 +7558,7 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, dest_addr = fold_convert (daddr_type, addr); dest_addr = fold_build2 (POINTER_PLUS_EXPR, daddr_type, dest_addr, - size_int (INTVAL (XEXP (slot, 1)))); + size_int (prev_size)); if (cur_size == GET_MODE_SIZE (mode)) { src = build_va_arg_indirect_ref (src_addr); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 71f97849ff09..e3ffb188d8b4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-09-30 Jakub Jelinek + + PR target/45843 + * g++.dg/torture/pr45843.C: New test. + 2010-09-30 Janus Weil PR fortran/45828 diff --git a/gcc/testsuite/g++.dg/torture/pr45843.C b/gcc/testsuite/g++.dg/torture/pr45843.C new file mode 100644 index 000000000000..f77b8cb0135d --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr45843.C @@ -0,0 +1,28 @@ +// PR target/45843 +// { dg-do run } + +#include + +extern "C" void abort (); +struct S { struct T { } a[14]; char b; }; +struct S arg, s; + +void +foo (int z, ...) +{ + char c; + va_list ap; + va_start (ap, z); + c = 'a'; + arg = va_arg (ap, struct S); + if (c != 'a') + abort (); + va_end (ap); +} + +int +main () +{ + foo (1, s); + return 0; +}