[Bug c++/61214] New: [4.9 regression]=?UTF-8?Q?=C2=A0Weird=20interaction=20between=20=2Dfvisibility=2Dinlines=2Dhidden?=, inline virtuals and devirtualization
delroth@dolphin-emu.org
gcc-bugzilla@gcc.gnu.org
Sun May 18 02:46:00 GMT 2014
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61214
Bug ID: 61214
Summary: [4.9 regression] Weird interaction between
-fvisibility-inlines-hidden, inline virtuals and
devirtualization
Product: gcc
Version: 4.9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: delroth@dolphin-emu.org
Created attachment 32814
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=32814&action=edit
Small test case reproducing this issue
A shared library (libtest.so) is compiled using -fvisibility=hidden
-fvisibility-inlines-hidden. This library exports (visibility=default) a class
hierarchy with virtual inline methods:
struct VISIBILITY_DEFAULT Base { virtual Base* clone() { return new Base(); }};
struct VISIBILITY_DEFAULT Foo { virtual Base* clone() { return new Foo(); }};
// + at least one method that is defined in a compilation unit, along with the
vtable, typeinfo, etc.
The code that uses libtest.so looks like this:
Base* obj = new Foo();
obj->clone();
When this is compiled to libtest.so, Base::clone and Foo::clone are not present
among the exported symbols. This did not cause issues before g++4.9 because g++
was not smart enough to determine that "obj" is always a Foo. It always issued
a call through the vtable, which *is* exported by libtest.so (and contains a
valid entry for Foo::clone).
Now, with g++4.9 and (better) devirtualization, g++ tries to generate a direct
call to Foo::clone. But instead of instantiating the inline function, it
assumes the inline function is already instantiated. This fails at link time
because no definition of Foo::clone can be found.
Small test case attached (with Makefile, reproduces the bug on g++4.9 on Linux
x86_64). In practice, s/libtest/wxWidgets/,
s/Foo::clone/wxCommandEvent::Clone/. Whether this is a bug of wxWidgets that
should not be using -fvisibility-inlines-hidden or a bug of g++4.9 that should
be instantiating the inline function, is something you will have to debate :)
More information about the Gcc-bugs
mailing list