[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #14 from Vincent --- The bug is still in 6.1.0.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 Jonathan Briggs changed: What|Removed |Added CC||zlynx at acm dot org --- Comment #12 from Jonathan Briggs --- This looks incredibly similar to a bug I found this week compiling my code with GCC 6.0. My code was much more complex, which has made it really difficult to write a small reproducer, but I also have a virtual function that is overriding an abstract base class. The implementation function is defined inline and is part of a template class. In code compiled with O2 or O3 the function call and all following code simply disappears from the assembly.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #13 from Vincent --- Indeed, that sounds like the same bug. It took me an entire afternoon shrinking my case down to the code provided in attachment, it was a needle in a huge haystack. I haven't been able to reduce the code further. Even tiny changes which seem completely unrelated make the bug disappear. It looks very much like a front-end bug. I am surprised there hasn't been any confirmation of the bug so far, and it has been resting in bugzilla 7 months so far, only with updates saying it's not a bug.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 Vincent changed: What|Removed |Added Version|5.2.0 |7.3.0 --- Comment #17 from Vincent --- Still there in 7.3.0.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 Jan Hubicka changed: What|Removed |Added CC||jason at redhat dot com --- Comment #8 from Jan Hubicka --- I think this is a bug in testcase and/or C++ FE. I get: main.cpp:33:8: warning: �void AN::rp() [with OC = LR::LLC; RC = BLKC]� used but never defined /tmp/ccT1Jzgh.o:main.cpp:function main: error: undefined reference to 'operator new(unsigned long)' /tmp/ccT1Jzgh.o:main.cpp:function LK::LL>::rb(): error: undefined reference to 'AN::LLC, BLKC>::rp()' _ZN2ANIN2LRI1I2IEXadL_ZL2ETEEE3LLCE4BLKCE2rpEv is virtual function that is not defined: _ZN2ANIN2LRI1I2IEXadL_ZL2ETEEE3LLCE4BLKCE2rpEv/504 (void AN::rp() [with OC = LR::LLC; RC = BLKC]) @0x75aa2000 Type: function Visibility: external public virtual References: Referring: First run: 0 Function flags: Called by: _ZN2REI2ELIN2LRI1I2IEXadL_ZL2ETEEE3LLCEEE2axEv/485 (1.00 per call) (can throw external) Calls: and is used as: _ZN2LKIN2LRI1I2IEXadL_ZL2ETEEE2LLEE2rbEv/484 (void LK::rb() [with T = LR::LL]) @0x75a4fa10 Type: function definition analyzed Visibility: prevailing_def_ironly virtual Address is taken. References: Referring: _ZTV2LKIN2LRI1I2IEXadL_ZL2ETEEE2LLEE/441 (addr) Availability: available First run: 0 Function flags: body Called by: Calls: _ZN2ANIN2LRI1I2IEXadL_ZL2ETEEE3LLCE4BLKCE2rpEv/504 (1.00 per call) (can throw external) Now with -fno-devirtualize we get: /484 (void LK::rb() [with T = LR::LL]) @0x75a4fa10 Type: function definition analyzed Visibility: prevailing_def_ironly virtual Address is taken. References: Referring: _ZTV2LKIN2LRI1I2IEXadL_ZL2ETEEE2LLEE/441 (addr) Availability: available First run: 0 Function flags: body Called by: Calls: Polymorphic indirect call of type struct RE token:0(1.00 per call) (can throw external) nothing known So it is simply devirtualization of: ;; Function void LK::rb() [with T = LR::LL] (_ZN2LKIN2LRI1I2IEXadL_ZL2ETEEE2LLEE2rbEv, funcdef_no=1102, decl_uid=24008, cgraph_uid=438, symbol_order=484) void LK::rb() [with T = LR::LL] (struct LK * const this) { struct RE * _1; int (*__vtbl_ptr_type) () * _3; int (*__vtbl_ptr_type) () _4; : _1 = &MEM[(struct LL *)0B].D.25771.D.25733; _3 = MEM[(struct RE *)0B]._vptr.RE; _4 = *_3; OBJ_TYPE_REF(_4;(struct RE)_1->0) (_1); return; } to ;; Function void LK::rb() [with T = LR::LL] (_ZN2LKIN2LRI1I2IEXadL_ZL2ETEEE2LLEE2rbEv, funcdef_no=1102, decl_uid=24008, cgraph_uid=438, symbol_order=484) void LK::rb() [with T = LR::LL] (struct LK * const this) { struct RE * _1; : _1 = &MEM[(struct LL *)0B].D.25771.D.25733; AN::LLC, BLKC>::rp (_1); return; }
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #9 from Vincent --- To my knowledge that virtual function is duly defined: template struct AN: public RE> { void rp(){} };
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #10 from Vincent --- Additionally, in the snippet: template struct EN: public RE { EN(::std::string){} void rp(){} }; If you replace ::std::string by const char*, the problem disappears. More generally, essentially any simplification of the code, unrelated to virtuals, makes the problem disappear.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #11 from Vincent --- Just tested with 5.3.0, still there.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #16 from Vincent --- Still there in 7.2.0.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #15 from Vincent --- Still there in 7.1.0.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #1 from Andrew Pinski --- > Is it worth it to try reducing my code and produce a code snippet exhibiting > the issue? Always. >Or is the issue known already? I didn't find any track of it. It could also be a bug in your code too. Devirtualization is known to expose invalid code too.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #2 from Vincent --- Ok, working on it, thanks.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #3 from Vincent --- Created attachment 36355 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36355&action=edit Test case Compile using gcc 5.2.0: g++-5 -O1 -std=c++11 main.ii -fdevirtualize The function missing at link edition is: AN::LLC, BLKC>::rp() Without -fdevirtualize, the function is there.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #4 from Andrew Pinski --- > ((T*)0)->ax(); This is undefined behavior.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #5 from Vincent --- The problem is static time, not dynamic time. This artefact is just a result of source code reduction. In my code there is no "0", and the problem exists. I can provide an alternative case without this artefact, but I do not believe it harms investigations at all.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #6 from Vincent --- Replace it with (new T())->ax() if you have doubts. Same thing.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 Richard Biener changed: What|Removed |Added CC||hubicka at gcc dot gnu.org --- Comment #7 from Richard Biener --- Honza - can you please look at the few devirt issues we still have on trunk and the gcc 5 branch?
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 Andrew Pinski changed: What|Removed |Added Status|NEW |RESOLVED Target Milestone|--- |9.0 Resolution|--- |FIXED --- Comment #36 from Andrew Pinski --- Fixed for GCC 9 by the patch for PR 80916. Tested even on the original testcase.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 Vincent changed: What|Removed |Added Version|8.1.0 |8.2.0 --- Comment #32 from Vincent --- The bug is still in 8.2.0.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #33 from Vincent --- Still in gcc 8.3.0.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 Jonathan Wakely changed: What|Removed |Added Last reconfirmed|2018-05-03 00:00:00 |2019-2-26 --- Comment #34 from Jonathan Wakely --- Honza, could you take another look at this reduced version please? __attribute__((weak)) void f() { } template struct Base { virtual void virt() = 0; void do_virt() { virt(); } }; template struct Derived : Base { void virt() {} }; template struct Wrap { T* p = nullptr; virtual void indirect_virt() { #ifdef FIX p->virt(); // OK #else p->do_virt(); // link error #endif } }; template struct Template { }; constexpr char str[] = ""; struct I { I() { f(); } Wrap>> l; }; int main(){new I();} This is valid C++, but when compiled with -O1 -fdevirtualize it fails with: l.cc:13:8: warning: ‘void Derived::virt() [with T = Template<(& str)>]’ used but never defined void virt() {} ^~~~ /usr/bin/ld: /tmp/ccYAFtTY.o: in function `Wrap > >::indirect_virt()': l.cc:(.text+0x57): undefined reference to `Derived >::virt()' collect2: error: ld returned 1 exit status If compiled with -DFIX it links OK. Even though the Template<(&str)> template argument is completely unused, it compiles fine if Derived is used instead, or Derived>. It only fails when using a template that has a pointer for its template parameter.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #35 from Jonathan Wakely --- (In reply to Jonathan Wakely from comment #34) > __attribute__((weak)) void f() { } This is here so that I() { f(); } doesn't get inlined (because the compiler can't know what f() does, since it might get replaced during linking). Without a call to some non-inlinable function it links OK. For the version in comment 29 the std::string constructor and destructor served that purpose, because they're defined in libstdc++.so and not inlined.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #18 from Vincent --- Still in 8.1, now with a different diagnosis: g++-8 -c -O3 67650.cpp 67650.cpp:33:8: warning: 'void AN::rp() [with OC = LR::LLC; RC = BLKC]' used but never defined void rp(){} ^~ Ironically the message complains about the non definition of the member function, and displays that very definition...
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 Jonathan Wakely changed: What|Removed |Added Keywords||diagnostic Target|x86_64-apple-darwin14.4.0 | Status|UNCONFIRMED |NEW Last reconfirmed||2018-05-03 Ever confirmed|0 |1 --- Comment #19 from Jonathan Wakely --- Reduced: struct RE { virtual void rp()=0; void ax(){rp();} }; struct BLKC { virtual void rb(){} }; template struct LK : BLKC { T* p = nullptr; void rb() override { p->ax();} }; template struct AN : RE { void rp() override {} }; template struct LR { virtual ~LR(){} struct LLC { virtual ~LLC(){} }; LK> l; }; constexpr char ET[]=""; struct I { LR _e; }; int main(){new I();} $ g++ -Wall 67650.cc -O1 -fdevirtualize 67650.cc:22:8: warning: ‘void AN< >::rp() [with = LR<(& ET)>::LLC]’ declared ‘static’ but never defined [-Wunused-function] void rp() override {} ^~
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #20 from Jonathan Wakely --- (In reply to Vincent from comment #5) > The problem is static time, not dynamic time. > This artefact is just a result of source code reduction. In my code there > is no "0", and the problem exists. Are you sure about that? Using your original testcase I can only reproduce the link error when it has ((T*)0)->ax()
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #21 from Jonathan Wakely --- Comment 19 shows a bogus warning triggered by -fdevirtualize but I'm not convinced the original report of a link-error bug is valid.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #22 from Vincent --- See comment #6. (In reply to Jonathan Wakely from comment #20) > (In reply to Vincent from comment #5) > > The problem is static time, not dynamic time. > > This artefact is just a result of source code reduction. In my code there > > is no "0", and the problem exists. > > Are you sure about that? Using your original testcase I can only reproduce > the link error when it has ((T*)0)->ax()
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #23 from Vincent --- See comment #10. The error is sensitive to unrelated changes. There is some (front-end?) corruption somewhere. (In reply to Jonathan Wakely from comment #21) > Comment 19 shows a bogus warning triggered by -fdevirtualize but I'm not > convinced the original report of a link-error bug is valid.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #24 from Jonathan Wakely --- (In reply to Vincent from comment #22) > See comment #6. I already saw it, and I already tried that change. The problem disappears if you make that change. (In reply to Vincent from comment #23) > See comment #10. The error is sensitive to unrelated changes. There is some > (front-end?) corruption somewhere. I'm not convinced by that either.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #25 from Vincent --- Oh, it used to be the case. I think that must be due to some additional artefact of more recent compilers. I'll try to find another way to show it. (In reply to Jonathan Wakely from comment #24) > (In reply to Vincent from comment #22) > > See comment #6. > > I already saw it, and I already tried that change. The problem disappears if > you make that change. > > (In reply to Vincent from comment #23) > > See comment #10. The error is sensitive to unrelated changes. There is some > > (front-end?) corruption somewhere. > > I'm not convinced by that either.
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #26 from Jonathan Wakely --- (In reply to Vincent from comment #25) > Oh, it used to be the case. I think that must be due to some additional > artefact of more recent compilers. I'll try to find another way to show it. I tried 5.1.0 and 5.2.0 and several other previous releases, they all link the program successfully, with just this warning: main.cpp:53:8: warning: 'I' has a field 'I::_e' whose type uses the anonymous namespace
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #27 from Vincent --- Sorry for the silly check, are you sure you are trying with -O3 or -fdevirtualize -O2? You can try this with 8.1: void *v; template struct LK: public BLKC { void rb(){((T*)v)->ax();} static T* st; }; As a replacement to the call to null, and the missing definition problem is reported. (In reply to Jonathan Wakely from comment #26) > (In reply to Vincent from comment #25) > > Oh, it used to be the case. I think that must be due to some additional > > artefact of more recent compilers. I'll try to find another way to show it. > > I tried 5.1.0 and 5.2.0 and several other previous releases, they all link > the program successfully, with just this warning: > > main.cpp:53:8: warning: 'I' has a field 'I::_e' whose type uses the > anonymous namespace
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #28 from Vincent --- Other silly check, did you try with my code or your reduced code ? (In reply to Jonathan Wakely from comment #26) > (In reply to Vincent from comment #25) > > Oh, it used to be the case. I think that must be due to some additional > > artefact of more recent compilers. I'll try to find another way to show it. > > I tried 5.1.0 and 5.2.0 and several other previous releases, they all link > the program successfully, with just this warning: > > main.cpp:53:8: warning: 'I' has a field 'I::_e' whose type uses the > anonymous namespace
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 Jonathan Wakely changed: What|Removed |Added Keywords||link-failure --- Comment #29 from Jonathan Wakely --- (In reply to Vincent from comment #27) > Sorry for the silly check, are you sure you are trying with -O3 or > -fdevirtualize -O2? I've tried both. I'm using x86_64-pc-linux-gnu though. > You can try this with 8.1: > > void *v; > > template > struct LK: public BLKC > { > void rb(){((T*)v)->ax();} > static T* st; > }; > > As a replacement to the call to null, and the missing definition problem is > reported. OK now I can reproduce it with trunk. (In reply to Vincent from comment #28) > Other silly check, did you try with my code or your reduced code ? Yours. Here's the reduced form that gives a link-error with trunk: #include template struct RE { virtual void rp()=0; void ax(){rp();} }; struct EN : RE { EN(::std::string = ""){} void rp(){} }; template struct AN : RE { void rp(){} }; template struct LK { T* p = nullptr; virtual void rb(){p->ax();} }; template struct LR { virtual ~LR(){} struct LLC { virtual ~LLC(){} }; LK> l; }; constexpr char ET[]=""; struct I : EN { LR _e; }; int main(){new I();} $ ~/gcc/8.1.0/bin/g++ -Wall -O1 -fdevirtualize main.cc main.cc:19:8: warning: ‘void AN::rp() [with OC = LR<(& ET)>::LLC]’ used but never defined void rp(){} ^~ /tmp/cc4IHAPf.o: In function `LK::LLC> >::rb()': main.cc:(.text+0x37): undefined reference to `AN::LLC>::rp()' collect2: error: ld returned 1 exit status
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #30 from Vincent --- Am using OSX, but I do not believe it makes a big difference. Thanks, Jonathan, let me know if I can help in any way. (In reply to Jonathan Wakely from comment #29) > (In reply to Vincent from comment #27) > > Sorry for the silly check, are you sure you are trying with -O3 or > > -fdevirtualize -O2? > > I've tried both. I'm using x86_64-pc-linux-gnu though. > > > > You can try this with 8.1: > > > > void *v; > > > > template > > struct LK: public BLKC > > { > > void rb(){((T*)v)->ax();} > > static T* st; > > }; > > > > As a replacement to the call to null, and the missing definition problem is > > reported. > > OK now I can reproduce it with trunk. > > (In reply to Vincent from comment #28) > > Other silly check, did you try with my code or your reduced code ? > > Yours. > > Here's the reduced form that gives a link-error with trunk: > > #include > > template > struct RE > { > virtual void rp()=0; > void ax(){rp();} > }; > > struct EN : RE > { > EN(::std::string = ""){} > void rp(){} > }; > > template > struct AN : RE > { > void rp(){} > }; > > template > struct LK > { > T* p = nullptr; > virtual void rb(){p->ax();} > }; > > template > struct LR > { > virtual ~LR(){} > struct LLC { virtual ~LLC(){} }; > LK> l; > }; > > constexpr char ET[]=""; > struct I : EN > { > LR _e; > }; > > int main(){new I();} > > > $ ~/gcc/8.1.0/bin/g++ -Wall -O1 -fdevirtualize main.cc > main.cc:19:8: warning: ‘void AN::rp() [with OC = LR<(& ET)>::LLC]’ used > but never defined >void rp(){} > ^~ > /tmp/cc4IHAPf.o: In function `LK::LLC> >::rb()': > main.cc:(.text+0x37): undefined reference to `AN::LLC>::rp()' > collect2: error: ld returned 1 exit status
[Bug c++/67650] undef reference with -fdevirtualize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67650 --- Comment #31 from Vincent --- It turns out we might be in front of two bugs actually. With 8.1 I have a new diagnosis for this 67650 bug (definition missing at compile time, not just at link edition time), but I do have other parts of my old code where 8.1 is now reporting missing definitions, and the definitions are there (definitions are shown in the error message from 8.1 itself). And no virtuals are involved there at all. So either the old bug is now much more extensive, or there are two bugs now in the same general "area".