On Thu, Mar 06, 2025 at 12:45:33PM -0500, Jason Merrill wrote:
> On 3/5/25 7:54 AM, Nathaniel Shead wrote:
> > On Wed, Feb 26, 2025 at 10:29:59AM -0500, Jason Merrill wrote:
> > > On 2/21/25 6:05 AM, Nathaniel Shead wrote:
> > > > After seeing PR c++/118964 I'm coming back around to this [1] patch
> > > > series, since it appears that this can cause errors on otherwise valid
> > > > code by instantiations coming into module purview that reference
> > > > TU-local entities.
> > > > 
> > > > [1]: https://gcc.gnu.org/pipermail/gcc-patches/2024-May/650324.html
> > > > 
> > > > We'd previously discussed that the best way to solve this in general
> > > > would be to perform all deferred instantiations at the end of the GMF to
> > > > ensure that they would not leak into the module purview.  I still
> > > > tentatively agree that this would be the "nicer" way to go (though I've
> > > > since come across https://eel.is/c++draft/temp.point#7 and wonder if
> > > > this may not be strictly conforming according to the current wording?).
> > > 
> > > Hmm, interesting point.
> > > 
> > > > I've not yet managed to implement this however, and even if I had, at
> > > > this stage it would definitely not be appropriate for GCC15; would the
> > > > approach described below be appropriate for GCC15 as a stop-gap to
> > > > reduce these issues?
> > > 
> > > As I suggested earlier in this discussion, it seems to me that the
> > > purviewness of an implicit instantiation shouldn't matter, they should all
> > > be treated as discardable.
> > 
> > So looking further I believe that currently they are not, in that
> > implicit instantiations themselves are only ever emitted if they are
> > reached from elsewhere (regardless of their purviewness), so the issues
> > are mostly just with deferred explicit instantiations etc.  However...
> > 
> > > Could we instead set DECL_MODULE_PURVIEW_P as appropriate when we see an
> > > explicit instantiation and use that + DECL_EXPLICIT_INSTANTIATION to
> > > recompute module_kind?
> 
> As in the attached, which works for me.  Do you see a problem with this
> approach?
> 

Ah I see, I think I misunderstood; yes, this makes sense to me and
should work fine.  I'm OK with this patch; here's another couple of
testcases I tried as well that also passed with your change:

-- >8 --

// { dg-additional-options "-fmodules-ts -Wno-global-module -fdump-lang-module" 
}
// { dg-module-cmi M }

module;

// Deferred instantiation of GM virtual functions or friend functions
// should not place newly discovered declarations in the module purview.
template <typename T>
void go() {
  extern T fn_decl();
}
template <typename T>
struct S {
  friend void x() {}
  virtual void f() {
    go<char>();
  }
};
S<int> s;

export module M;

// The whole GMF should be discarded here
// { dg-final { scan-lang-dump "Wrote 0 clusters" module } }

-- >8 --

// { dg-additional-options "-fmodules-ts -fdump-lang-module" }
// { dg-module-cmi empty }

module;
#include "xtreme-header.h"
export module empty;

// The whole GMF should be discarded here
// { dg-final { scan-lang-dump "Wrote 0 clusters" module } }

-- >8 --

> > > Or go with this patch but only look at the saved module_kind if
> > > DECL_EXPLICIT_INSTANTIATION, but that seems a bit of a waste of space. 
> > > Might
> > > be safer at this point, though.
> > 
> > Part of the issue is handling things that are "implicit instantiations"
> > that we don't track were as such; the obvious case here is friend decls,
> > which get instantiated with the current purviewness but might only have
> > been instantiated due to a deferred implicit instantiation, and for
> > which we remove any evidence that they were created due to an implicit
> > instantiation.
> > 
> > So maybe looking at the problem from that side would also work, but I'm
> > not sure exactly how best to do that just yet.
> > 
> > > > Another approach would be to maybe lower the error to a permerror, so
> > > > that users that 'know better' could compile such modules anyway (at risk
> > > > of various link errors and ODR issues), though I would also need to
> > > > adjust the streaming logic to handle this better.  Thoughts?
> > > 
> > > This also sounds desirable.  With a warning flag so it can be disabled for
> > > certain deliberate cases like the gthr stuff.
> > 
> > OK, I'll try and took a look if I get a chance (unfortunately life has
> > interrupted me again for the time being...).  I'm not sure that this
> > would work for the gthr case though (since the error occurs at the point
> > of use not at the point of declaration); for that we would probably need
> > some kind of attribute I guess?
> 
> We frequently use warning_enabled_at to suppress a diagnostic based on
> whether the diagnostic is enabled at the point of definition of some entity.
> 
> Jason

Ah, thanks for the pointer; I didn't realise that existed.  I'm not sure
I'll have anything done in the GCC 15 timeframe though unfortunately,
but I'll see how I go.

Nathaniel

Reply via email to