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:
parent
ed31a8173b
commit
6e3077c608
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -7686,7 +7686,7 @@
|
||||
emit_insn (gen_rtx_USE (VOIDmode, valreg2));
|
||||
|
||||
/* Construct the return. */
|
||||
expand_null_return ();
|
||||
expand_naked_return ();
|
||||
|
||||
DONE;
|
||||
})
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
20
gcc/stmt.c
20
gcc/stmt.c
@ -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)
|
||||
|
@ -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>
|
||||
|
||||
|
26
gcc/testsuite/gcc.dg/builtin-return-1.c
Normal file
26
gcc/testsuite/gcc.dg/builtin-return-1.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user