<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/125530>125530</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            `-Winclude-angled-in-module-purview` false-positive
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            false-positive
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          vvd170501
      </td>
    </tr>
</table>

<pre>
    `-Winclude-angled-in-module-purview` can be incorrectly diagnosed in the following case:
1. A header declares or defines a type named `module`.
2. The same header (or another one) declares a typedef for this type.
3. The header with typedef is included before an angled include.

```cpp
// test.h
struct module;  // Doesn't trigger the warning, but needed for typedefs below

namespace ns {
    struct module; // Same as above, type declaration doesn't trigger the warning
    typedef module mod_alias1;  // Also doesn't trigger the warning (typedef must be in global namespace?)
}

namespace {
    // These typedefs also don't trigger the warning
    typedef module mod_alias2;
    typedef ns::module mod_alias3;
}

typedef module mod_alias4;  // Triggers the warning in test.cpp
typedef ns::module mod_alias5;  // Also triggers the warning
```

```cpp
// test.cpp
#include "test.h"
#include <iostream>
```

```bash
$ clang++-18 -c -std=c++20 test.cpp -c
test.cpp:2:10: warning: '#include <filename>' attaches the declarations to the named module 'mod_alias4', which is not usually intended; consider moving that directive before the module declaration [-Winclude-angled-in-module-purview]
    2 | #include <iostream>
      | ^
1 warning generated.
```

I couldn;t test a multi-file example with trunk clang, but the error can be also reproduced with a single file: https://godbolt.org/z/sdfb3bxPc

The single-file example is less realistic (includes are usually placed before any declarations or definitions), but could be easier to debug:
```cpp
struct module;

namespace ns {
 struct module;
}

typedef module mod_alias4;
typedef ns::module mod_alias5;

#include <iostream>
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJycVl2P6jYQ_TXmZRTkOB8sDzyEpUh9q9SV-lhN7CFxa2xkO3C3v75yEliWvXfv6qJIIY5zZubMmZNgCLqzRBtWbVm1W-AQe-c357PKV7zi-aJ16nXDap79pa00g6IMbWdIZdpmR6cGQ9lp8GdNF1ZzkGihJdBWOu9JRvMKSmNnXSAF2kLsCQ7OGHfRtgOJgVjRMN7kS2igJ1TkQZE06CmAS_8P2lIAhPh6IrB4JAWs5lNkVvMl441YwktPEPBIVwwmnpwHtC725MFZYmL9BjyhKTrAwXmIvQ7jQsIqJqwZ5qJjf9urA8wUKGjp4DwBWpjYuN5JEOmo-XTI0yldij0Te4gU4rJnvAnRDzLCXESxBZh37BwFy8QqQvS668iPhF3QW207Jp6hHSJYopTCmPqUWoCWjLtMsRNH4YSSwAZgqy3jDQDAh5hzyD8TaxgAW3emFGIkeqIKo3YW1KdJTehXjib4dPobjcaQ31fXmOA-R0t9u0ENIU5ags64Fg3cKmPFnol1Kne1eyz6reI56ktPgd6YwimJXy1IsGL7sMWGpOGiedxaTFtvOf4Isrzn6GXKKLxjJQ1O0s6kpp_FrT5wHr8Deq_Sn4r2ulLMMgcmxKxmIR7uFM_ahegJj6z47ZMoLYZ-fLQEaTDJe8vENsufIJOQhahYsZPTouC3NCCTiYJrUkUjWNHknBXNrbCiASZW71M6aENJIyklsQKMEWVPEyF3Wg8Q3bg2Gc3MLBOru2Yl6Ge49Fr2yRKsizCEAY15BW0jWUUqNUA6G3TykKM7px7GHiMonUxRn-lqICnWHOV-5Fi1_YLfVrtZiQLY6hk-awKMv3FXla7zm7Y6suQxklp-7NXvIN1glGXFNo4dAITjYKLOEp9A3_B4MjS7pB_sv9dOTkaViiPvnb--FsbZ83TyTg2S1PQgQtCpQkiYqXl9jKdR2qMAO6daZ-LS-Y6J_X9M7IM6tEX77Q85JTla_4jwPisdwFAI4AmNDlHLZC4zQQHQ061tJ4Py3tNf30vi-hrS42Uynrm-kZxUF2HQyUUcKGqHbnqlPYzTo__-2Ky_t_MrHvJFa5jH8CsTu1CbQq2LNS5ok6-Kp5rneVku-k2tnsS6rA8rVeaqrteVXLWIhCRlKfhTu9AbwUXFBS_yuqzKclnUOUc6tLU8cMVlxUpOR9Rmacz5mJq70CEMtMlFVRV8YbAlE8aPEiEOaAJlJxd0Gp3kONVu4TfpyawdusBKnjoc3rCijoa-_tXyPsBi8GbzIEId-6FdSndkYp-izKfs5N0_JCMT-zH9wMR-ruC8Ef8HAAD__znRB0Y">