blob: fd8bcff79b79bdff46d1c6f78f5fbf5a46399e04 [file] [log] [blame]
// PR c/81854 - weak alias of an incompatible symbol accepted
// { dg-do compile }
// { dg-require-ifunc "" } */
// { dg-options "-Wextra -Wno-pmf-conversions" }
struct Klass
{
int implementation ();
int good_magic ();
int iffy_magic ();
const char* bad_magic ();
typedef int (Func)(Klass*);
typedef int (Klass::*MemFuncPtr)();
static Func* good_resolver ();
static void* iffy_resolver ();
static MemFuncPtr bad_resolver ();
};
int Klass::implementation (void)
{
return 0;
}
// Verify no warning for the expected/compatible declaration.
int __attribute__ ((ifunc ("_ZN5Klass13good_resolverEv")))
Klass::good_magic ();
Klass::Func*
Klass::good_resolver (void)
{
MemFuncPtr mfp = &Klass::implementation;
return reinterpret_cast<Func*>(mfp);
}
// Verify a warning for the unsafe declaration.
int __attribute__ ((ifunc ("_ZN5Klass13iffy_resolverEv")))
Klass::iffy_magic (); // { dg-message "resolver indirect function declared here" }
void*
Klass::iffy_resolver (void) // { dg-warning ".ifunc. resolver for .int Klass::iffy_magic\\(\\). should return .int \\(\\*\\)\\(Klass\\*\\)." }
{
MemFuncPtr mfp = &Klass::implementation;
return reinterpret_cast<void*>(mfp);
}
// Verify an error for an incompatible declaration.
const char* __attribute__ ((ifunc ("_ZN5Klass12bad_resolverEv")))
Klass::bad_magic (); // { dg-message "resolver indirect function declared here" }
Klass::MemFuncPtr
Klass::bad_resolver (void) // { dg-error ".ifunc. resolver for .const char\\* Klass::bad_magic\\(\\). must return .const char\\* \\(\\*\\)\\(Klass\\*\\)." }
{
return &Klass::implementation;
}