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