https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59930
--- Comment #2 from Nathan Sidwell <nathan at gcc dot gnu.org> --- When we parse the template friend declaration, we're not injecting an invisible template decl into the enclosing namespace. When we instantiate the template we do an unqualified lookup (and ask for hidden objects) from the enclosing namespace. In the first testcase, this fails to find anything. Then we explicitly inject into the global scope, as Richard surmised: /* The friend template has not already been declared. In this case, the instantiation of the template class will cause the injection of this template into the global scope. */ That just seems wrong. Perhaps it was right at some point? In the second testcase we perform the unqualified lookup, but find the ::B, as it's declared at the point of the instantiation. So we make it a friend. Bah. 10.3.1.2/3 talks about invisible friend injection, and AFAICT doesn't prohibit that happening during template parsing time.