https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122908
--- Comment #5 from Bernardo Negri <b.gomes.negri at gmail dot com> --- I don't quite understand what you mean by "recursively finds": I admit I do not know much about the C++ standard (or C++ in general), but from the links you sent, what I could interpret is: 1. internalLink has internal linkage, which means it is TU-local 2. Class::testFn (the template) names internalLink in its body, which means testFn is an exposure. Exposures in the global module fragment are allowed, however. 3. friendFn<int> (the instantiation of the template in the module purview) names Class. However, I'd argue that because neither Class nor Class::testFn are TU-local because they are not marked static and do not have internal linkage. Therefore, I don't see what is the problem with friendFn<int> naming Class. Exposures only happen when something in module purview name TU-local entities outside the function body (and a few other exceptions), and I don't think either Class or testFn are TU-local. I simply don't see where the standard says being TU-local is a transitive property. Unless the issue is actually that Class<int> (the instantiation in module purview) names internalLink, in which case the existence of friendFn should not matter. Even if we assume friendFn<int> or Class<int> (the instantiations) are exposures (and apparently GCC thinks friendFn<int> is an exposure), [1] says that template instantiations whose declarations are exposures are TU-local, and TU-local entities in module purview are allowed to be exposures. From what I understand, by these rules, a template instantiation *cannot* by itself be a violation of exposure rules. This makes sense, as I find it hard to believe the authors of the standard would make it so easy to accidentally make an exposure that violates the rules (because instantiations are so easy to make). The only way I see the compiler behaving as it does right now is if GCC erroneously applies the rule described in [1] only to classes but not to friend functions. If that was the case, then Class<int> (the instantiation) would be considered TU-local because Class (the template) is an exposure because it names internalLink. Then when friendFn<int> comes along and names Class<int>, it is considered an exposure (because it names the TU-local instantiation) but not TU-local (because GCC does not apply [1] to friend functions). Or I could be entirey wrong, and I have the completely wrong idea about "instantiated declarations" or any of the other concepts the standard mentions. I do find it weird that the definition of TU-local depends on the definition of exposure and the definition of exposure depends on the definition of TU-local. [1] https://eel.is/c++draft/basic.link#15.5
