aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-06-20 08:35:55 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2007-06-20 08:35:55 +0200
commit6a4e56a90e3c299e0eb634611cab3d076acbe818 (patch)
tree166cd1ce7322fc29d8e7721de1c5dcbb7dfe0b43 /gcc
parent6cb62483b6958cd89877df5b8c479fc6b9c1faa2 (diff)
downloadgcc-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')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/calls.c14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20070614-1.c33
4 files changed, 57 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9c6108b..7b3e68d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2007-06-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/32285
+ * calls.c (precompute_arguments): Also precompute CALL_EXPR arguments
+ if ACCUMULATE_OUTGOING_ARGS.
+
2007-06-19 Rask Ingemann Lambertsen <rask@sygehus.dk>
* config/m68hc11/m68hc11.c: Include dataflow header file.
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)));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8afda7f..20b44c8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-06-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/32285
+ * gcc.c-torture/execute/20070614-1.c: New test.
+
2007-06-19 Seongbae Park <seongbae.park@gmail.com>
* 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 0000000..fa44f7f
--- /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;
+}