diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-06-20 08:35:55 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-06-20 08:35:55 +0200 |
commit | 6a4e56a90e3c299e0eb634611cab3d076acbe818 (patch) | |
tree | 166cd1ce7322fc29d8e7721de1c5dcbb7dfe0b43 /gcc/calls.c | |
parent | 6cb62483b6958cd89877df5b8c479fc6b9c1faa2 (diff) | |
download | gcc-6a4e56a90e3c299e0eb634611cab3d076acbe818.zip gcc-6a4e56a90e3c299e0eb634611cab3d076acbe818.tar.gz gcc-6a4e56a90e3c299e0eb634611cab3d076acbe818.tar.bz2 |
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
Diffstat (limited to 'gcc/calls.c')
-rw-r--r-- | gcc/calls.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/gcc/calls.c b/gcc/calls.c index b339c04..868edfc 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))); |