https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124200

--- Comment #12 from Nathaniel Shead <nshead at gcc dot gnu.org> ---
(In reply to Thomas Berger from comment #11)
> (In reply to Nathaniel Shead from comment #10)
> > Are you maybe looking at a different testcase?  The testcase in comment #1
> > only used header units, there are no named modules involved, so everything
> > should be OK.  ...ah, I see, in the patch the testcase there used named
> > modules instead of header units.  Right, that makes sense then.
> That's on me, sorry, sometime during testing i migrated from header to
> modules,
> and forgotten, you are right, that is essentially my testcase, that should
> produce an ODR, that is an different issue. 
> 
> I will recheck later today with the initial header-units variant.
> 
> Sorry for that confusion.

No worries, thank you!  It's probably a good idea to still include such a test
with named modules to make sure that we at least don't crash or something.

> 
> > I agree that if we end up with functions attached to different named modules
> > (an adjustment of the testcase where we export different declarations) then
> > this is IFNDR.  And probably the most sensible approach in that case would
> > be to just continue to consider as them different declarations, so don't do
> > any extra attempts at merging.
> 
> That is already the logic here. But if i read the standard correctly, a
> diagnostic is required in this case "[...]a diagnostic is required only if
> the definable item is attached to a named module
> and a prior definition is reachable at the point where a later definition
> occurs.[...]".

Note though that the definitions are not reachable from each other.  For a
simplified case:

  // a.C
  export module A;
  export void foo() {}  // have not imported B, foo@B is not reachable

  // b.C
  export module B;
  export void foo() {}  // have not imported A, foo@A is not reachable

  // c.C
  import A;
  import B;
  // this is the first point we could see the clash, but there's no
  // requirement for a diagnostic here (because this isn't a point of
  // definition).  Of course now doing this would require a diagnostic:
  void foo() {}  // error

Note that if foo@A and foo@B are not exported though we don't complain if a
definition is made in 'c.C'.  My understanding is that this is a deliberate
choice that's come along with having 'strong module ownership', as we consider
them to be unrelated "definable items" as e.g. foo@A does not "precede" the foo
in 'c.C' (https://eel.is/c++draft/basic.lookup.general#2), and so the
declarations do not correspond (and these are not the same definable item)
(https://eel.is/c++draft/basic.scope.scope#6).

But probably in the case where the module definitions are defined as `extern
"C++"` we should complain still I guess, I'll think more on this another time.

Reply via email to