[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