https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120098
--- Comment #7 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
The change only made ipa-cp to think it is good idea to specialize.
Putting everything to namespace makes the bug trigger on GCC 15 and earlier,
too. ipa-cp does not think it is good idea to specialize but we inline wrap
since it is called once.
/* { dg-do run } */
/* { dg-options "-O3 -fno-partial-inlining -fdump-ipa-cp
-fno-devirtualize-speculatively" } */
/* Main purpose is to verify that we do not produce wrong devirtualization to
C::m_fn1. We currently devirtualize to B::m_fn1, so check that. */
#include <stdlib.h>
namespace {
class A {
public:
unsigned length;
};
class B {};
class MultiTermDocs : public virtual B {
protected:
A readerTermDocs;
A subReaders;
virtual B *m_fn1(int *) { return NULL; }
virtual inline ~MultiTermDocs();
inline void wrap(void)
{
m_fn1(NULL);
m_fn1(NULL);
m_fn1(NULL);
m_fn1(NULL);
m_fn1(NULL);
m_fn1(NULL);
m_fn1(NULL);
m_fn1(NULL);
m_fn1(NULL);
}
};
class C : MultiTermDocs {
B *m_fn1(int *);
};
MultiTermDocs::~MultiTermDocs() {
wrap ();
if (&readerTermDocs) {
B *a;
for (unsigned i = 0; i < subReaders.length; i++)
(a != 0);
}
}
B *C::m_fn1(int *) { abort (); }
}
int main()
{
class C c;
}
/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" { xfail *-*-*
} } } */
After inlining the callgraph already has C::m_fn1. With LTO this gets
diagnosed as type inconsistent and turned to unreachable
Life would be easier if I did remember what this testcase is about, but I guess
it is about C being in construction.
IPA function summary for int main()/41 inlinable
global time: 3.000000
self size: 6
global size: 13
min size: 10
self stack: 16
global stack: 16
size:1.000000, time:1.000000
size:3.000000, time:2.000000, executed if:(not inlined)
calls:
void {anonymous}::MultiTermDocs::wrap.constprop()/60 inlined
freq:1.00
Stack frame offset 16, callee self size 0
virtual {anonymous}::B* {anonymous}::C::m_fn1(int*)/69 inlined
freq:1.00
Stack frame offset 16, callee self size 0
void abort()/54 function body not available
freq:0.00 loop depth: 0 size: 1 time: 10
virtual {anonymous}::B* {anonymous}::C::m_fn1(int*)/68 inlined
freq:1.00
Stack frame offset 16, callee self size 0
void abort()/54 function body not available
freq:0.00 loop depth: 0 size: 1 time: 10
virtual {anonymous}::B* {anonymous}::C::m_fn1(int*)/67 inlined
freq:1.00
Stack frame offset 16, callee self size 0
void abort()/54 function body not available
freq:0.00 loop depth: 0 size: 1 time: 10
virtual {anonymous}::B* {anonymous}::C::m_fn1(int*)/66 inlined
freq:1.00
Stack frame offset 16, callee self size 0
void abort()/54 function body not available
freq:0.00 loop depth: 0 size: 1 time: 10
virtual {anonymous}::B* {anonymous}::C::m_fn1(int*)/65 inlined
freq:1.00
Stack frame offset 16, callee self size 0
void abort()/54 function body not available
freq:0.00 loop depth: 0 size: 1 time: 10
virtual {anonymous}::B* {anonymous}::C::m_fn1(int*)/64 inlined
freq:1.00
Stack frame offset 16, callee self size 0
void abort()/54 function body not available
freq:0.00 loop depth: 0 size: 1 time: 10
virtual {anonymous}::B* {anonymous}::C::m_fn1(int*)/63 inlined
freq:1.00
Stack frame offset 16, callee self size 0
void abort()/54 function body not available
freq:0.00 loop depth: 0 size: 1 time: 10
virtual {anonymous}::B* {anonymous}::C::m_fn1(int*)/62 inlined
freq:1.00
Stack frame offset 16, callee self size 0
void abort()/54 function body not available
freq:0.00 loop depth: 0 size: 1 time: 10
virtual {anonymous}::B* {anonymous}::C::m_fn1(int*)/61 inlined
freq:1.00
Stack frame offset 16, callee self size 0
void abort()/54 function body not available
freq:0.00 loop depth: 0 size: 1 time: 10