http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50687
--- Comment #4 from Lassi Tuura <lat at cern dot ch> 2011-10-11 12:00:47 UTC --- Right, as far as I can tell at the moment visibility option is somewhat peripheral to the issue. The main difference you see with LTO vs. no LTO appears to be whether code for the type is generated at all. As far as I can tell, once the compiler decides to generate code for 'bar', you get the same behaviour in all cases. The visibility controls only apply after that. Whether it's an issue that LTO in 4.6.x generates references to otherwise unreferenced types I can't say. I'd say it is not invalid, though perhaps undesirable. But once code is generated for types like 'bar', the app needs to make sure it uses correct visibility controls. As far as I understand, the actual upstream problem is that 'bar' really comes from a header file, from another package. The #include for that header is not using visibility push/pop to reset visibility to 'default', so the header inherits the 'hidden' visibility from command line. At the moment, without visibility directives, there's a side effect that 4.6.x LTO generates references to otherwise unused types from those headers, resulting in link errors. But I'd suggest this usage is quite fragile - the moment anything from those headers is actually referenced, the app needs to be fixed to reset visibility to 'default' around #includes anyway (because the module in question is being compiled with -fvisibility=hidden). Of course if 4.6.x can be amended to prune types from LTO more aggressively, it will help to avoid this particular issue. I'm just not sure it will actually fix all the upstream problems, I rather suspect some types coming from headers are actually referenced in ways which in the end will require full visibility management in the source code.