/* PR 5878.
|
/* PR 5878.
|
|
|
We ICEd in verify_local_live_at_start because we incorrectly forced
|
We ICEd in verify_local_live_at_start because we incorrectly forced
|
the PIC register live between BAR and BAZ. We did this because the
|
the PIC register live between BAR and BAZ. We did this because the
|
definition of PIC_OFFSET_TABLE_REGNUM was incorrectly not INVALID_REGNUM
|
definition of PIC_OFFSET_TABLE_REGNUM was incorrectly not INVALID_REGNUM
|
when !flag_pic for most targets. */
|
when !flag_pic for most targets. */
|
|
|
/* { dg-do run } */
|
/* { dg-do run } */
|
/* { dg-options "-O -fno-pic" } */
|
/* { dg-options "-O -fno-pic" } */
|
|
|
extern void abort (void);
|
extern void abort (void);
|
|
|
#if defined(__alpha__)
|
#if defined(__alpha__)
|
/* PIC register is $29, but is used even without -fpic. */
|
/* PIC register is $29, but is used even without -fpic. */
|
#elif defined(__arc__)
|
#elif defined(__arc__)
|
# define PIC_REG "26"
|
# define PIC_REG "26"
|
#elif defined(__arm__)
|
#elif defined(__arm__)
|
# define PIC_REG "9"
|
# define PIC_REG "9"
|
#elif defined(AVR)
|
#elif defined(AVR)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__cris__)
|
#elif defined(__cris__)
|
# define PIC_REG "0"
|
# define PIC_REG "0"
|
#elif defined(__fr30__)
|
#elif defined(__fr30__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__)
|
#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(_IBMR2)
|
#elif defined(_IBMR2)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__i386__)
|
#elif defined(__i386__)
|
# define PIC_REG "ebx"
|
# define PIC_REG "ebx"
|
#elif defined(__ia64__)
|
#elif defined(__ia64__)
|
/* PIC register is r1, but is used even without -fpic. */
|
/* PIC register is r1, but is used even without -fpic. */
|
#elif defined(__M32R__)
|
#elif defined(__M32R__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__m68k__)
|
#elif defined(__m68k__)
|
# define PIC_REG "a5"
|
# define PIC_REG "a5"
|
#elif defined(__mc68hc1x__)
|
#elif defined(__mc68hc1x__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__mcore__)
|
#elif defined(__mcore__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__mips__)
|
#elif defined(__mips__)
|
/* PIC register is $28, but is used even without -fpic. */
|
/* PIC register is $28, but is used even without -fpic. */
|
#elif defined(__MMIX__)
|
#elif defined(__MMIX__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__mn10300__)
|
#elif defined(__mn10300__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__hppa__)
|
#elif defined(__hppa__)
|
/* PIC register is %r27 or %r19, but is used even without -fpic. */
|
/* PIC register is %r27 or %r19, but is used even without -fpic. */
|
#elif defined(__pdp11__)
|
#elif defined(__pdp11__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__powerpc__) || defined(__PPC__) || defined(__POWERPC__)
|
#elif defined(__powerpc__) || defined(__PPC__) || defined(__POWERPC__)
|
# ifdef __MACH__
|
# ifdef __MACH__
|
# define PIC_REG "31"
|
# define PIC_REG "31"
|
# else
|
# else
|
# define PIC_REG "30"
|
# define PIC_REG "30"
|
# endif
|
# endif
|
#elif defined(__s390__)
|
#elif defined(__s390__)
|
# define PIC_REG "12"
|
# define PIC_REG "12"
|
#elif defined(__sparc__)
|
#elif defined(__sparc__)
|
# define PIC_REG "l7"
|
# define PIC_REG "l7"
|
#elif defined(__v850)
|
#elif defined(__v850)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__vax__)
|
#elif defined(__vax__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__xstormy16__)
|
#elif defined(__xstormy16__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__XTENSA__)
|
#elif defined(__XTENSA__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__sh__)
|
#elif defined(__sh__)
|
# define PIC_REG "r12"
|
# define PIC_REG "r12"
|
#elif defined(__x86_64__)
|
#elif defined(__x86_64__)
|
/* No pic register. */
|
/* No pic register. */
|
#elif defined(__m32c__)
|
#elif defined(__m32c__)
|
/* No pic register. */
|
/* No pic register. */
|
#else
|
#else
|
# error "Modify the test for your target."
|
# error "Modify the test for your target."
|
#endif
|
#endif
|
|
|
#if defined PIC_REG && !defined __PIC__ && !defined __pic__
|
#if defined PIC_REG && !defined __PIC__ && !defined __pic__
|
register void *reg __asm__(PIC_REG);
|
register void *reg __asm__(PIC_REG);
|
#else
|
#else
|
/* We really need a global register variable set to the PIC register
|
/* We really need a global register variable set to the PIC register
|
to expose the bug. Oh well, let the test case not fail. */
|
to expose the bug. Oh well, let the test case not fail. */
|
static void *reg;
|
static void *reg;
|
#endif
|
#endif
|
|
|
void * __attribute__((noinline))
|
void * __attribute__((noinline))
|
dummy (void *x)
|
dummy (void *x)
|
{
|
{
|
return x;
|
return x;
|
}
|
}
|
|
|
void
|
void
|
f (void)
|
f (void)
|
{
|
{
|
goto *dummy (&&bar);
|
goto *dummy (&&bar);
|
for (;;)
|
for (;;)
|
{
|
{
|
foo:
|
foo:
|
reg = (void *) 1;
|
reg = (void *) 1;
|
if (!reg)
|
if (!reg)
|
goto baz;
|
goto baz;
|
reg = &&foo;
|
reg = &&foo;
|
}
|
}
|
|
|
bar:
|
bar:
|
baz:
|
baz:
|
reg = 0;
|
reg = 0;
|
}
|
}
|
|
|
int
|
int
|
main()
|
main()
|
{
|
{
|
void *old_reg = reg;
|
void *old_reg = reg;
|
reg = (void *) 1;
|
reg = (void *) 1;
|
|
|
f ();
|
f ();
|
|
|
/* Additionally test that the prologue/epilogue properly does *not*
|
/* Additionally test that the prologue/epilogue properly does *not*
|
save and restore global registers. Not possible when the PIC
|
save and restore global registers. Not possible when the PIC
|
register is in a register window, of course. On Darwin, you can't
|
register is in a register window, of course. On Darwin, you can't
|
call library routines from non-PIC code. */
|
call library routines from non-PIC code. */
|
#if !defined (__sparc__) && !defined(__MACH__)
|
#if !defined (__sparc__) && !defined(__MACH__)
|
if (reg)
|
if (reg)
|
abort ();
|
abort ();
|
#endif
|
#endif
|
|
|
reg = old_reg;
|
reg = old_reg;
|
return 0;
|
return 0;
|
}
|
}
|
|
|