From: Jakub Jelinek Date: Wed, 20 Jun 2007 06:35:55 +0000 (+0200) Subject: re PR middle-end/32285 (Miscompilation with pure _Complex returning call inside anoth... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6a4e56a90e3c299e0eb634611cab3d076acbe818;p=gcc.git re PR middle-end/32285 (Miscompilation with pure _Complex returning call inside another fn's argument list) PR middle-end/32285 * calls.c (precompute_arguments): Also precompute CALL_EXPR arguments if ACCUMULATE_OUTGOING_ARGS. * gcc.c-torture/execute/20070614-1.c: New test. From-SVN: r125873 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9c6108bd551..7b3e68d5bca 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-06-20 Jakub Jelinek + + PR middle-end/32285 + * calls.c (precompute_arguments): Also precompute CALL_EXPR arguments + if ACCUMULATE_OUTGOING_ARGS. + 2007-06-19 Rask Ingemann Lambertsen * config/m68hc11/m68hc11.c: Include dataflow header file. diff --git a/gcc/calls.c b/gcc/calls.c index b339c04d902..868edfc396d 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1269,13 +1269,25 @@ precompute_arguments (int flags, int num_actuals, struct arg_data *args) /* If this is a libcall, then precompute all arguments so that we do not get extraneous instructions emitted as part of the libcall sequence. */ - if ((flags & ECF_LIBCALL_BLOCK) == 0) + + /* If we preallocated the stack space, and some arguments must be passed + on the stack, then we must precompute any parameter which contains a + function call which will store arguments on the stack. + Otherwise, evaluating the parameter may clobber previous parameters + which have already been stored into the stack. (we have code to avoid + such case by saving the outgoing stack arguments, but it results in + worse code) */ + if ((flags & ECF_LIBCALL_BLOCK) == 0 && !ACCUMULATE_OUTGOING_ARGS) return; for (i = 0; i < num_actuals; i++) { enum machine_mode mode; + if ((flags & ECF_LIBCALL_BLOCK) == 0 + && TREE_CODE (args[i].tree_value) != CALL_EXPR) + continue; + /* If this is an addressable type, we cannot pre-evaluate it. */ gcc_assert (!TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value))); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8afda7faf41..20b44c82749 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-06-20 Jakub Jelinek + + PR middle-end/32285 + * gcc.c-torture/execute/20070614-1.c: New test. + 2007-06-19 Seongbae Park * gcc.target/arm/stack-corruption.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/20070614-1.c b/gcc/testsuite/gcc.c-torture/execute/20070614-1.c new file mode 100644 index 00000000000..fa44f7fa3ec --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20070614-1.c @@ -0,0 +1,33 @@ +extern void abort (void); + +_Complex v = 3.0 + 1.0iF; + +void +foo (_Complex z, int *x) +{ + if (z != v) + abort (); +} + +_Complex bar (_Complex z) __attribute__ ((pure)); +_Complex +bar (_Complex z) +{ + return v; +} + +int +baz (void) +{ + int a, i; + for (i = 0; i < 6; i++) + foo (bar (1.0iF * i), &a); + return 0; +} + +int +main () +{ + baz (); + return 0; +}