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.