+2003-12-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR middle-end/11151
+ * function.h (struct function): New field 'x_naked_return_label'.
+ * function.c (free_after_compilation): Set it to NULL.
+ (expand_function_end): Emit 'naked_return_label' if it exists.
+ * rtl.h (expand_naked_return): Declare.
+ * stmt.c (expand_naked_return): New function to generate a
+ jump to 'naked_return_label'.
+ * builtins.c (expand_builtin_return): Call expand_naked_return
+ instead of expand_null_return.
+ * config/sparc/sparc.md (untyped_return): Likewise.
+
2003-12-04 Andrew Pinski <pinskia@physics.uc.edu>
PR target/11322
/* Return whatever values was restored by jumping directly to the end
of the function. */
- expand_null_return ();
+ expand_naked_return ();
}
/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
emit_insn (gen_rtx_USE (VOIDmode, valreg2));
/* Construct the return. */
- expand_null_return ();
+ expand_naked_return ();
DONE;
})
f->x_nonlocal_goto_stack_level = NULL;
f->x_cleanup_label = NULL;
f->x_return_label = NULL;
+ f->x_naked_return_label = NULL;
f->computed_goto_common_label = NULL;
f->computed_goto_common_reg = NULL;
f->x_save_expr_regs = NULL;
cfun->x_clobber_return_insn = after;
}
+ /* Output the label for the naked return from the function, if one is
+ expected. This is currently used only by __builtin_return. */
+ if (naked_return_label)
+ emit_label (naked_return_label);
+
/* ??? This should no longer be necessary since stupid is no longer with
us, but there are some parts of the compiler (eg reload_combine, and
sh mach_dep_reorg) that still try and compute their own lifetime info
on machines which require execution of the epilogue on all returns. */
rtx x_return_label;
+ /* Label that will go on the end of function epilogue.
+ Jumping to this label serves as a "naked return" instruction
+ on machines which require execution of the epilogue on all returns. */
+ rtx x_naked_return_label;
+
/* Label and register for unswitching computed gotos. */
rtx computed_goto_common_label;
rtx computed_goto_common_reg;
#define parm_reg_stack_loc (cfun->x_parm_reg_stack_loc)
#define cleanup_label (cfun->x_cleanup_label)
#define return_label (cfun->x_return_label)
+#define naked_return_label (cfun->x_naked_return_label)
#define save_expr_regs (cfun->x_save_expr_regs)
#define stack_slot_list (cfun->x_stack_slot_list)
#define parm_birth_insn (cfun->x_parm_birth_insn)
/* In stmt.c */
extern void set_file_and_line_for_stmt (location_t);
extern void expand_null_return (void);
+extern void expand_naked_return (void);
extern void emit_jump (rtx);
extern int preserve_subexpressions_p (void);
expand_null_return_1 (last_insn);
}
+/* Generate RTL to return directly from the current function.
+ (That is, we bypass any return value.) */
+
+void
+expand_naked_return (void)
+{
+ rtx last_insn, end_label;
+
+ last_insn = get_last_insn ();
+ end_label = naked_return_label;
+
+ clear_pending_stack_adjust ();
+ do_pending_stack_adjust ();
+ clear_last_expr ();
+
+ if (end_label == 0)
+ end_label = naked_return_label = gen_label_rtx ();
+ expand_goto_internal (NULL_TREE, end_label, last_insn);
+}
+
/* Try to guess whether the value of return means error code. */
static enum br_predictor
return_prediction (rtx val)
+2003-12-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * gcc.dg/builtin-return-1.c: New test.
+
2003-12-04 Stuart Menefy <stuart.menefy@st.com>
J"orn Rennecke <joern.rennecke@superh.com>
--- /dev/null
+/* PR middle-end/11151 */
+/* Originator: Andrew Church <gcczilla@achurch.org> */
+/* { dg-do run } */
+
+/* This used to fail on SPARC because the (undefined) return
+ value of 'bar' was overwriting that of 'foo'. */
+
+extern void abort(void);
+
+int foo(int n)
+{
+ return n+1;
+}
+
+int bar(int n)
+{
+ __builtin_return(__builtin_apply((void (*)(void))foo, __builtin_apply_args(), 64));
+}
+
+int main(void)
+{
+ if (bar(1) != 2)
+ abort();
+
+ return 0;
+}