[gnu.gcc.bug] pcc-struct-return on vax

keith@EXPO.LCS.MIT.EDU (Keith Packard) (03/25/89)

Any machine with a return instruction will suffer this fate.  The
return_label is (conditionally) generated before testing for
pcc_struct_return.  So, any function returning a structure doesn't
get a return_label, which results in the function not loading r0 with
the structure return address.  Also, the vax has no function epilogue,
so an explicit return must be placed after the register is loaded.

The fix is simple, delay the return_label computation until after 
current_function_returns_pcc_struct is computed.

Diffs to version 1.34 follow:

*** /users/keith/gcc-1.34/stmt.c	Wed Feb 22 12:28:32 1989
--- stmt.c	Fri Mar 24 17:19:05 1989
***************
*** 1321,1328
    expand_goto_internal (0, return_label, last_insn);
  #endif
  #else /* no FUNCTION_EPILOGUE */
!   emit_jump_insn (gen_return ());
!   emit_barrier ();
  #endif
    last_expr_type = 0;
  }

--- 1321,1334 -----
    expand_goto_internal (0, return_label, last_insn);
  #endif
  #else /* no FUNCTION_EPILOGUE */
!   /* sort of an implicit function epilogue */ 
!   if (current_function_returns_pcc_struct)
!     expand_goto_internal (0, return_label, last_insn);
!   else
!      {
!        emit_jump_insn (gen_return ());
!        emit_barrier ();
!      }
  #endif
    last_expr_type = 0;
  }
***************
*** 4160,4176
    current_function_returns_pcc_struct = 0;
    current_function_returns_struct = 0;
  
-   /* Make the label for return statements to jump to, if this machine
-      does not have a one-instruction return.  */
- #ifdef HAVE_return
-   if (HAVE_return && ! current_function_returns_pcc_struct)
-     return_label = 0;
-   else
-     return_label = gen_label_rtx ();
- #else
-   return_label = gen_label_rtx ();
- #endif
- 
    /* No space assigned yet for structure values.  */
    max_structure_value_size = 0;
    structure_value = 0;

--- 4166,4171 -----
    current_function_returns_pcc_struct = 0;
    current_function_returns_struct = 0;
  
    /* No space assigned yet for structure values.  */
    max_structure_value_size = 0;
    structure_value = 0;
***************
*** 4261,4266
    if (GET_CODE (DECL_RTL (DECL_RESULT (subr))) == REG)
      REG_FUNCTION_VALUE_P (DECL_RTL (DECL_RESULT (subr))) = 1;
  
    /* If doing stupid allocation, mark parms as born here.  */
  
    if (obey_regdecls)

--- 4256,4272 -----
    if (GET_CODE (DECL_RTL (DECL_RESULT (subr))) == REG)
      REG_FUNCTION_VALUE_P (DECL_RTL (DECL_RESULT (subr))) = 1;
  
+   /* Make the label for return statements to jump to, if this machine
+      does not have a one-instruction return.  */
+ #ifdef HAVE_return
+   if (HAVE_return && ! current_function_returns_pcc_struct)
+     return_label = 0;
+   else
+     return_label = gen_label_rtx ();
+ #else
+   return_label = gen_label_rtx ();
+ #endif
+ 
    /* If doing stupid allocation, mark parms as born here.  */
  
    if (obey_regdecls)
***************
*** 4366,4371
  
        emit_move_insn (outgoing, value_address);
        use_variable (outgoing);
      }
  
    /* Fix up any gotos that jumped out to the outermost

--- 4372,4383 -----
  
        emit_move_insn (outgoing, value_address);
        use_variable (outgoing);
+ #ifndef FUNCTION_EPILOGUE
+       /* don't let this function fall off the end,
+        * put an explicit return here */
+       emit_jump_insn (gen_return ());
+       emit_barrier ();
+ #endif
      }
  
    /* Fix up any gotos that jumped out to the outermost
***************
*** 4376,4379
       and they need to create temporary variables,
       then you will lose.  */
    fixup_gotos (0, 0, 0, get_insns (), 0);
  }

--- 4388,4392 -----
       and they need to create temporary variables,
       then you will lose.  */
    fixup_gotos (0, 0, 0, get_insns (), 0);
+ 
  }