mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 08:30:35 +08:00
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:
parent
e292dbb06b
commit
b64de1fe98
@ -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. */
|
||||
|
29
gcc/testsuite/gcc.c-torture/execute/nestfunc-6.c
Normal file
29
gcc/testsuite/gcc.c-torture/execute/nestfunc-6.c
Normal 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
|
Loading…
x
Reference in New Issue
Block a user