summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-05-24 21:43:42 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-05-24 21:43:42 +0000
commit34cf214284676e522a1d113a87635b839042de33 (patch)
treea2e82baf04352a994fb25663c70965aa05e4b6ac
parent19f06d8622c5119a2b265f34d018cd1646e244f1 (diff)
downloadgcc-34cf214284676e522a1d113a87635b839042de33.tar.gz
* calls.c (expand_call): Handle cleanups in tail-recursion
arguments analagously to cleanups in sibling calls. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@34143 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/calls.c17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/crash4.C14
3 files changed, 33 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a832f3e2108..27b55542a79 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2000-05-24 Mark Mitchell <mark@codesourcery.com>
+
+ * calls.c (expand_call): Handle cleanups in tail-recursion
+ arguments analagously to cleanups in sibling calls.
+
2000-05-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* simplify-rtx.c: Rename macro SIGN_EXTEND to HWI_SIGN_EXTEND.
diff --git a/gcc/calls.c b/gcc/calls.c
index 7cf8971307f..1c2c2eacec2 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2400,7 +2400,7 @@ expand_call (exp, target, ignore)
break;
case 1: /* Mildly unsafe. */
- args[i].tree_value = unsave_expr (args[i].tree_value);
+ args[i].tree_value = unsave_expr (args[i].tree_value);
break;
case 2: /* Wildly unsafe. */
@@ -2444,9 +2444,20 @@ expand_call (exp, target, ignore)
made until after RTL generation for the entire function is
complete. */
start_sequence ();
-
+ /* If expanding any of the arguments creates cleanups, we can't
+ do a tailcall. So, we'll need to pop the pending cleanups
+ list. If, however, all goes well, and there are no cleanups
+ then the call to expand_start_target_temps will have no
+ effect. */
+ expand_start_target_temps ();
if (optimize_tail_recursion (actparms, get_last_insn ()))
- tail_recursion_insns = get_insns ();
+ {
+ if (any_pending_cleanups (1))
+ try_tail_call = try_tail_recursion = 0;
+ else
+ tail_recursion_insns = get_insns ();
+ }
+ expand_end_target_temps ();
end_sequence ();
/* Restore the original pending stack adjustment for the sibling and
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/crash4.C b/gcc/testsuite/g++.old-deja/g++.eh/crash4.C
new file mode 100644
index 00000000000..573149fdd31
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.eh/crash4.C
@@ -0,0 +1,14 @@
+// Build don't link:
+// Origin: Nathan Sidwell <nathan@codesourcery.com>
+// Special g++ Options: -O2
+
+struct A
+{
+ A (int) { }
+ ~A () { }
+ int get () const { return 0; }
+};
+
+void f (const A &s) {
+ f (s.get ());
+}