Open
Description
(This is an outgrowth of my work discussed in #127561 and related to dealii/dealii#18071. @ChuanqiXu9: FYI)
The collection of module partition units below produces a bunch of errors of the following kind:
/usr/bin/clang++-20 -std=c++20 -stdlib=libc++ -MD -MT CMakeFiles/test.dir/b.cc.o -MF CMakeFiles/test.dir/b.cc.o.d @CMakeFiles/test.dir/b.cc.o.modmap -o CMakeFiles/test.dir/b.cc.o -c /home/bangerth/tmp/bug/b.cc
In module 'test:A' imported from /home/bangerth/tmp/bug/b.cc:6:
/usr/include/c++/v1/__random/mersenne_twister_engine.h:223:15: error: cannot befriend target of using declaration
223 | friend bool operator==(
| ^
/home/bangerth/tmp/bug/b.cc:12:16: note: in instantiation of template class 'std::mersenne_twister_engine<unsigned long, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>' requested here
12 | std::mt19937 x1, x2;
| ^
/usr/include/c++/v1/__random/mersenne_twister_engine.h:764:1: note: target of using declaration
764 | operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
| ^
/home/bangerth/tmp/bug/std.ccm:23:14: note: using declaration
23 | using std::operator==;
| ^
In module 'test:A' imported from /home/bangerth/tmp/bug/b.cc:6:
/usr/include/c++/v1/__random/mersenne_twister_engine.h:241:15: error: cannot befriend target of using declaration
241 | friend bool operator!=(
| ^
/usr/include/c++/v1/__random/mersenne_twister_engine.h:807:1: note: target of using declaration
807 | operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
| ^
/home/bangerth/tmp/bug/std.ccm:24:14: note: using declaration
24 | using std::operator!=;
| ^
[...]
I can't see any good reason for this -- it seems like a bug to me.
Here are the relevant files:
// a.ccm
module;
#include <random>
export module test:A;
export {}
// std.ccm
module;
#include <mutex>
#include <random>
export module test:std;
export {
namespace std {
using std::mt19937;
using std::mutex;
using std::operator==;
using std::operator!=;
// Would ordinarily contain much more stuff here...
} // namespace std
#if defined(_LIBCPP_VERSION) // For CLang's support library
_LIBCPP_BEGIN_NAMESPACE_STD
using std::operator==;
using std::operator!=;
_LIBCPP_END_NAMESPACE_STD
#endif
} // export
// b.cc
module;
module test:B;
import :std;
import :A;
bool test()
{
static std::mutex rand_mutex; // Necessary, for unclear reasons
std::mt19937 x1, x2;
return (x1 == x2) && (x1 != x2);
}
# CMakeLists.txt
cmake_minimum_required(VERSION 3.28 FATAL_ERROR)
project(test LANGUAGES CXX)
add_library(test)
target_compile_features(test PUBLIC cxx_std_20)
target_sources(test PUBLIC
FILE_SET CXX_MODULES
FILES
std.ccm
a.ccm
b.cc)
Here are a couple of observations:
- The errors go away if I remove the
#include <random>
froma.ccm
. Becausea.ccm
does not actually export anything, the presence of<random>
does not strike me as wrong. In my original testcase, I cannot remove it because it is transitively#include
d by something else I actually need in that file --a.ccm
wraps an external library of which one of the headers happens to#include <random>
. - The
:std
partition also exports the symbols in_LIBCPP_BEGIN_NAMESPACE_STD
. This is needed to avoid other errors, and is something that @davidstone had already realized in https://github.com/davidstone/std_module/blob/d121f1701884953c9ca468b159b530556e2475a3/source/std_module.cpp, for example. If I remove these lines, the error goes away, but I get many more errors in other places in return (just not for this minimal testcase).