OSDN Git Service

* calls.c (expand_call): Handle cleanups in tail-recursion
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 24 May 2000 21:43:42 +0000 (21:43 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 24 May 2000 21:43:42 +0000 (21:43 +0000)
arguments analagously to cleanups in sibling calls.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@34143 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/calls.c
gcc/testsuite/g++.old-deja/g++.eh/crash4.C [new file with mode: 0644]

index a832f3e..27b5554 100644 (file)
@@ -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.
index 7cf8971..1c2c2ea 100644 (file)
@@ -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 (file)
index 0000000..573149f
--- /dev/null
@@ -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 ());
+}