diff options
author | Jakub Jelinek <jakub@redhat.com> | 2010-09-30 22:21:28 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-09-30 22:21:28 +0200 |
commit | 45c13d4cec5c33c3971a42d673503e93c2fbb424 (patch) | |
tree | 86af552168cf72dd7edf9f4c4c6f9ecd2893d26c /gcc | |
parent | 03d79dc39456d034c9b789d520c4f6161b0ecde6 (diff) | |
download | gcc-45c13d4cec5c33c3971a42d673503e93c2fbb424.zip gcc-45c13d4cec5c33c3971a42d673503e93c2fbb424.tar.gz gcc-45c13d4cec5c33c3971a42d673503e93c2fbb424.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr45843.C | 28 |
4 files changed, 42 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7795da1..b82c99d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-09-30 Jakub Jelinek <jakub@redhat.com> + + PR target/45843 + * config/i386/i386.c (ix86_gimplify_va_arg): Use + INTVAL (XEXP (slot, 1)) as prev_size. + 2010-09-30 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/45837 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c36ad74..0998f31 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 71f9784..e3ffb18 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-09-30 Jakub Jelinek <jakub@redhat.com> + + PR target/45843 + * g++.dg/torture/pr45843.C: New test. + 2010-09-30 Janus Weil <janus@gcc.gnu.org> 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 0000000..f77b8cb --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr45843.C @@ -0,0 +1,28 @@ +// PR target/45843 +// { dg-do run } + +#include <stdarg.h> + +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; +} |