fix alpha gp reload vs nonlocal gotos
Richard Henderson
rth@redhat.com
Fri Dec 5 11:25:00 GMT 2003
I happened to consider this case while examining the gpc
nonlocal goto patch that I just approved and applied.
r~
* config/alpha/alpha.c (alpha_does_function_need_gp): Return
true if the function contains a nonlocal goto.
* gcc.c-torture/execute/nestfunc-6.c: New.
Index: config/alpha/alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.337
retrieving revision 1.338
diff -c -p -d -r1.337 -r1.338
*** config/alpha/alpha.c 30 Oct 2003 02:02:34 -0000 1.337
--- config/alpha/alpha.c 5 Dec 2003 11:21:48 -0000 1.338
*************** alpha_does_function_need_gp (void)
*** 6926,6935 ****
--- 6926,6944 ----
if (! TARGET_ABI_OSF)
return 0;
+ /* We need the gp to load the address of __mcount. */
if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
return 1;
+ /* The code emitted by alpha_output_mi_thunk_osf uses the gp. */
if (current_function_is_thunk)
+ return 1;
+
+ /* The nonlocal receiver pattern assumes that the gp is valid for
+ the nested function. Reasonable because it's almost always set
+ correctly already. For the cases where that's wrong, make sure
+ the nested function loads its gp on entry. */
+ if (current_function_has_nonlocal_goto)
return 1;
/* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
-----------------------------------
/* Test that the GP gets properly restored, either by the nonlocal
receiver or the nested function. */
#ifndef NO_TRAMPOLINES
typedef __SIZE_TYPE__ size_t;
extern void abort (void);
extern void exit (int);
extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
int main ()
{
__label__ nonlocal;
int compare (const void *a, const void *b)
{
goto nonlocal;
}
char array[3];
qsort (array, 3, 1, compare);
abort ();
nonlocal:
exit (0);
}
#else
int main() { return 0; }
#endif
More information about the Gcc-patches
mailing list