alpha.c (alpha_does_function_need_gp): Return true if the function contains a nonlocal goto.

* 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.

From-SVN: r74327
This commit is contained in:
Richard Henderson 2003-12-05 03:21:48 -08:00
parent e292dbb06b
commit b64de1fe98
2 changed files with 38 additions and 0 deletions

View File

@ -6926,12 +6926,21 @@ alpha_does_function_need_gp (void)
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.
Even if we are a static function, we still need to do this in case
our address is taken and passed to something like qsort. */

View File

@ -0,0 +1,29 @@
/* 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