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

Reply via email to