On 2015.11.23 at 11:11 -0800, Steven Noonan wrote: > On Tue, Nov 17, 2015 at 1:09 AM, Markus Trippelsdorf > <mar...@trippelsdorf.de> wrote: > > On 2015.11.16 at 14:18 -0800, Steven Noonan wrote: > >> Hi folks, > >> > >> (I'm not subscribed to the list, so please CC me on all responses.) > >> > >> This is using GCC 5.2 on Linux x86_64. On a project at work I've found > >> that one of our shared libraries refuses to link because of some > >> symbol references it shouldn't be making. If I add "-fno-devirtualize > >> -fno-devirtualize-speculatively" to the compile flags, the issue goes > >> away and everything links/runs fine. The issue does *not* appear on > >> GCC 4.8 (which is used by our current production toolchain). > >> > >> First of all, does anyone have any ideas off the top of their head why > >> devirtualization would break like this? > >> > >> Second, I'm looking for any ideas on how to gather meaningful data to > >> submit a useful bug report for this issue. The best idea I've come up > >> with so far is to preprocess one of the sources with the incorrect > >> references and use 'delta' to reduce it to a minimal preprocessed > >> source file that references one of these incorrect symbols. > >> Unfortunately this is a sluggish process because such a minimal test > >> case would need to compile correctly to an object file -- so "delta" > >> is reducing it very slowly. So far I'm down from 11MB preprocessed > >> source to 1.1MB preprocessed source after running delta a few times. > > > > These undefined references are normally user errors. For example, when > > you define an inline function, you need to link with the symbols it > > uses. > > > > markus@x4 /tmp % cat main.ii > > struct A { > > void foo(); > > }; > > struct B { > > A v; > > virtual void bar() { v.foo(); } > > }; > > struct C { > > B *w; > > void Test() { > > if (!w) > > return; > > while (1) > > w->bar(); > > } > > }; > > C a; > > int main() { a.Test(); } > > > > markus@x4 /tmp % g++ -fno-devirtualize -O2 -Wl,--no-undefined main.ii > > markus@x4 /tmp % g++ -O2 -Wl,--no-undefined main.ii > > /tmp/ccEvh2dL.o:main.ii:function B::bar(): error: undefined reference to > > 'A::foo()' > > /tmp/ccEvh2dL.o:main.ii:function main: error: undefined reference to > > 'A::foo()' > > collect2: error: ld returned 1 exit status > > > > Instead of using delta you could try creduce instead. It is normally > > much quicker: > > > > https://github.com/csmith-project/creduce > > > > creduce did make a much smaller test case, and it's actually sort of > readable. I'm not sure that I selected for the right criteria in my > test script though. It appears to exhibit the negative behavior we're > observing at least. > > --- > namespace panorama { > class A { > public: > virtual int *AccessIUIStyle() = 0; > }; > class CUIPanel : A { > int *AccessIUIStyle() { return AccessStyle(); } > int *AccessStyle() const; > }; > class B { > float GetSplitterPosition(); > A *m_pIUIPanel; > }; > } > using namespace panorama; > float B::GetSplitterPosition() { > m_pIUIPanel->AccessIUIStyle(); > return 0.0f; > }
Yes. It is the same issue that I've pointed out in my example above. You need to either link with the object file that provides the _ZNK8panorama8CUIPanel11AccessStyleEv symbol. Or move the definition of panorama::CUIPanel::AccessIUIStyle() to the file that defines panorama::CUIPanel::AccessStyle(). -- Markus