Issue 78850
Summary C++20 Modules: Clang gives error `error: 'std::align' has different definitions in different modules` when just including standard headers in two module partitions
Labels clang
Assignees
Reporter ashley-hawkins
    I'm still not sure whether this is a problem with libstdc++ or a problem with clang so I apologise if this is the wrong place to report, but I get this error when including just <chrono> in one module partition and <memory> in another, here is an example on Compiler Explorer: https://godbolt.org/z/Wvv1h5aYa
<details>
<summary>module.cc</summary>

```cpp
module;
#include <chrono>
export module repro;
export import :part;
```
</details>
<details>
<summary>part.cc</summary>

```cpp
module;
#include <memory>
export module repro:part;
```
</details>

In this example I am getting the error `'std::align' has different definitions in different modules`
<details>
<summary>full compiler output</summary>

```
In module 'repro:part' imported from /app/module.cc:4:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.1/../../../../include/c++/14.0.1/bits/align.h:61:1: error: 'std::align' has different definitions in different modules; definition in module 'repro:part.<global>' first difference is function body
   60 | inline void*
      | ~~~~~~~~~~~~
   61 | align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 62 | {
      | ~
   63 |   if (__space < __size)
      | ~~~~~~~~~~~~~~~~~~~~~
   64 |     return nullptr;
      | ~~~~~~~~~~~~~~~
   65 |   const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   66 |   const auto __aligned = (__intptr - 1u + __align) & -__align;
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   67 | const auto __diff = __aligned - __intptr;
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   68 |   if (__diff > (__space - __size))
      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   69 | return nullptr;
      |     ~~~~~~~~~~~~~~~
   70 |   else
      | ~~~~
   71 |     {
      |     ~
   72 |       __space -= __diff;
      |       ~~~~~~~~~~~~~~~~~~
   73 |       return __ptr = reinterpret_cast<void*>(__aligned);
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   74 |     }
 |     ~
   75 | }
      | ~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.1/../../../../include/c++/14.0.1/bits/align.h:61:1: note: but in '' found a different body
   60 | inline void*
      | ~~~~~~~~~~~~
   61 | align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 62 | {
      | ~
   63 |   if (__space < __size)
      | ~~~~~~~~~~~~~~~~~~~~~
   64 |     return nullptr;
      | ~~~~~~~~~~~~~~~
   65 |   const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   66 |   const auto __aligned = (__intptr - 1u + __align) & -__align;
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   67 | const auto __diff = __aligned - __intptr;
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   68 |   if (__diff > (__space - __size))
      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   69 | return nullptr;
      |     ~~~~~~~~~~~~~~~
   70 |   else
      | ~~~~
   71 |     {
      |     ~
   72 |       __space -= __diff;
      |       ~~~~~~~~~~~~~~~~~~
   73 |       return __ptr = reinterpret_cast<void*>(__aligned);
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   74 |     }
 |     ~
   75 | }
      | ~
1 error generated.
```
</details>

I looked at the preprocessed source and saw that the problem causing the function definitions to be considered different was one of them was getting `uintptr_t` from the global namespace, the other was getting `uintptr_t` from a `using` in the std namespace.

I could reproduce the same situation without those included headers to demonstrate the problem:
<details>
<summary>module.cc</summary>

```cc
module;
typedef long T;
namespace ns {
    using ::T;
}
namespace ns {
inline void fun() {
    (void)(T)0;
}
}
export module repro;
export import :part;
```
</details>
<details>
<summary>part.cc</summary>

```cc
module;
typedef long T;
namespace ns {
inline void fun() {
 (void)(T)0;
}
}
export module repro:part;
```
</details>
<details>
<summary>CMakeLists.txt</summary>

```cc
cmake_minimum_required(VERSION 3.28)
project(repro)

set(CMAKE_CXX_STANDARD 20)

add_library(repro)
target_sources(repro PUBLIC FILE_SET CXX_MODULES FILES module.cc part.cc)
```
</details>

And here is the above on compiler explorer: https://godbolt.org/z/Ke6eoGnan and the compiler output from that compiler explorer example:
<details>
<summary>full compiler output</summary>

```
In file included from /app/module.cc:12:
part.cc:4:13: error: 'ns::fun' has different definitions in different modules; definition in module 'repro:part.<global>' first difference is function body
    4 | inline void fun() {
      | ~~~~~~~~~~~~^~~~~~~
    5 |     (void)(T)0;
      |     ~~~~~~~~~~~
 6 | }
      | ~
module.cc:7:13: note: but in '' found a different body
    7 | inline void fun() {
      | ~~~~~~~~~~~~^~~~~~~
    8 | (void)(T)0;
      |     ~~~~~~~~~~~
    9 | }
      | ~
1 error generated.
```
</details>
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to