http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52973
--- Comment #2 from Jason Merrill <jason at gcc dot gnu.org> 2012-06-01 21:36:35 UTC --- The bug here is that we aren't applying the visibility attribute to b until after we've decided that a<b> is hidden because b is hidden. Changing the code to template <class T> class __attribute__((visibility("default"))) a { public: /* A */ static int c; }; class __attribute__((visibility("default"))) b; class b: a <b> {}; template<> /* B */ int a<b>::c = 0; works around the issue.