https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86491
--- Comment #1 from Jason Vas Dias <jason.vas.dias at gmail dot com> --- In investigating this problem, I actually modified 6.4.1's gcc/cp/decl2.c with the following patch to print out which component of the base struct it thinks uses the anonymous namespace: BEGIN PATCH: --- decl2.c,r260630 2018-05-18 14:47:27.000000000 +0100 +++ decl2.c 2018-07-11 16:16:13.816541340 +0100 @@ -2154,0 +2155,5 @@ +struct tree_vis +{ tree *tp; + int vis; +}; + @@ -2158 +2163 @@ - int *vis_p = (int *)data; + struct tree_vis *tree_vis_p = (struct tree_vis *)data; @@ -2166 +2171,2 @@ - *vis_p = VISIBILITY_ANON; + tree_vis_p->tp = tp; + tree_vis_p->vis = VISIBILITY_ANON; @@ -2170,2 +2176,4 @@ - && CLASSTYPE_VISIBILITY (*tp) > *vis_p) - *vis_p = CLASSTYPE_VISIBILITY (*tp); + && CLASSTYPE_VISIBILITY (*tp) > tree_vis_p->vis) + { tree_vis_p->vis = CLASSTYPE_VISIBILITY (*tp); + tree_vis_p->tp = tp; + } @@ -2181,3 +2189,8 @@ - int vis = VISIBILITY_DEFAULT; - cp_walk_tree_without_duplicates (&type, min_vis_r, &vis); - return vis; + struct tree_vis tv = { NULL, VISIBILITY_DEFAULT }; + cp_walk_tree_without_duplicates (&type, min_vis_r, &tv); + return tv.vis; +} + +static void +tree_type_visibility (tree_vis *tvis) +{ cp_walk_tree_without_duplicates (tvis->tp, min_vis_r, tvis); @@ -2607 +2620,4 @@ - int subvis = type_visibility (TREE_TYPE (t)); + tree_vis tvis = { &(TREE_TYPE (t)), VISIBILITY_DEFAULT }; + tree_type_visibility (&tvis); + + int subvis = tvis.vis; @@ -2627,2 +2643,2 @@ -%qT has a base %qT whose type uses the anonymous namespace", - type, TREE_TYPE (t)); +%qT has a base %qT whose type uses the anonymous namespace because of its component %qT", + type, TREE_TYPE (t), *tvis.tp); :END PATCH But the offending component is actually the whole base class: N::NT<_C_, _C_OBJ_, _M_>::NT() void N::NA::C::m() In file included from /tmp/tM.C:1:0: /tmp/t2.H: At global scope: /tmp/t2.H:14:9: warning: ‘N::D’ has a base ‘N::NT<N::NA::C, (& N::NA::c_), &N::NA::C::m>’ whose type uses the anonymous namespace because of its component ‘N::NT<N::NA::C, (& N::NA::c_), &N::NA::C::m>’ [-Wsubobject-linkage] class D : public NT<NA::C,&NA::c_,&NA::C::m> ^ N::D::D() N::D::D() N::D::D() int main() N::NT<_C_, _C_OBJ_, _M_>::NT() [with _C_ = N::NA::C; _C_* _C_OBJ_ = (& N::NA::c_); void (_C_::* _M_)() = &N::NA::C::m] N::NT<_C_, _C_OBJ_, _M_>::NT() [with _C_ = N::NA::C; _C_* _C_OBJ_ = (& N::NA::c_); void (_C_::* _M_)() = &N::NA::C::m] N::NT<_C_, _C_OBJ_, _M_>::NT() [with _C_ = N::NA::C; _C_* _C_OBJ_ = (& N::NA::c_); void (_C_::* _M_)() = &N::NA::C::m] Analyzing compilation unit Performing interprocedural optimizations <*free_lang_data> <visibility> <build_ssa_passes> <opt_local_passes> <targetclone> <free-inline-summary> <whole-program> <inline>Assembling functions: <simdclone> void N::NA::C::m() N::D::D() int main() N::NT<_C_, _C_OBJ_, _M_>::NT() [with _C_ = N::NA::C; _C_* _C_OBJ_ = (& N::NA::c_); void (_C_::* _M_)() = &N::NA::C::m] Execution times (seconds) phase setup : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 1386 kB (62%) ggc phase opt and generate : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.01 (100%) wall 169 kB ( 8%) ggc integrated RA : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.01 (100%) wall 96 kB ( 4%) ggc TOTAL : 0.00 0.00 0.01 2223 kB It would be nice if the fix for this could also print out more information about precisely which component of the structure the compiler thinks uses the anonymous namespace - it has taken me 2 days of analysis to get this far, which could have been avoided if GCC printed out information like the above in the first place.