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