re PR middle-end/11151 (__builtin_return(__builtin_apply(...)) gives wrong result)

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.

From-SVN: r74312
This commit is contained in:
Eric Botcazou 2003-12-05 07:46:35 +01:00 committed by Eric Botcazou
parent ed31a8173b
commit 6e3077c608
9 changed files with 78 additions and 2 deletions

View File

@ -1,3 +1,16 @@
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

View File

@ -1389,7 +1389,7 @@ expand_builtin_return (rtx result)
/* 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. */

View File

@ -7686,7 +7686,7 @@
emit_insn (gen_rtx_USE (VOIDmode, valreg2));
/* Construct the return. */
expand_null_return ();
expand_naked_return ();
DONE;
})

View File

@ -452,6 +452,7 @@ free_after_compilation (struct function *f)
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;
@ -7132,6 +7133,11 @@ expand_function_end (void)
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

View File

@ -270,6 +270,11 @@ struct function GTY(())
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;
@ -566,6 +571,7 @@ extern int trampolines_created;
#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)

View File

@ -2133,6 +2133,7 @@ extern void purge_hard_subreg_sets (rtx);
/* 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);

View File

@ -2885,6 +2885,26 @@ expand_null_return (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)

View File

@ -1,3 +1,7 @@
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>

View File

@ -0,0 +1,26 @@
/* 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;
}