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

Nathaniel Shead <nshead at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic
                 CC|                            |nshead at gcc dot gnu.org

--- Comment #2 from Nathaniel Shead <nshead at gcc dot gnu.org> ---
I haven't attempted to fully reproduce, but it appears to me you have something
like the following:

  // user.cpp
  export module User;
  export struct User {
    int value;
  };

  // main.cpp
  struct User;
  struct MainWindow {
    User* u;
  };
  import User;
  int foo(MainWindow m) {
    return m.u->value;
  }

$ g++-15 -fmodules -S user.cpp main.cpp
main.cpp: In function ‘int foo(MainWindow)’:
main.cpp:7:13: error: invalid use of incomplete type ‘struct User’
    7 |   return m.u->value;
      |             ^~
main.cpp:1:8: note: forward declaration of ‘struct User’
    1 | struct User;
      |        ^~~~

This error is expected (though the diagnostic could definitely be improved!):
'User' (in main.cpp) and 'User@User' (in user.cpp) are unrelated, distinct
types; the former belonging to the global module, and the latter attached to
the module 'User'.  You can see this by comparing e.g.:

  // main.cpp
  struct User;
  import User;
  User u;

$ g++-15 -fmodules -S user.cpp main.cpp
main.cpp:3:1: error: reference to ‘User’ is ambiguous
    3 | User u;
      | ^~~~
In module User, imported at main.cpp:2:
user.cpp:2:15: note: candidates are: ‘struct User@User’
    2 | export struct User {
      |               ^~~~
main.cpp:1:8: note:                 ‘struct User’
    1 | struct User;
      |        ^~~~

To fix the issue, you could defined user.cpp as something like this:

  // user.cpp
  export module User;
  export extern "C++" struct User {
    int value;
  };

The 'extern "C++"' ensures that 'User' is declared attached to the global
module.

I'll leave this PR open for now for the diagnostic issue, however, as I imagine
this to be a common mistake, and we should be able to detect this and emit some
kind of note pointing to the conflicting type.

Reply via email to