[libcxx-commits] [clang] [libcxx] [Clang] Add __builtin_common_reference (PR #121199)
Nico Weber via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Dec 2 11:54:39 PST 2025
nico wrote:
Here's another snippet that builds fine before this patch but not after it:
```
#include <type_traits>
template <typename T>
class Foo;
struct Baz {
Baz() = default;
#if 0
Baz(Foo<int> foo) {}
#else
template <typename T>
requires(std::is_convertible_v<T, Foo<int>>)
explicit Baz(T foo) {}
#endif
};
struct Quux {
mutable Baz baz;
};
```
```
# libc++ built as described in libcxx/docs/VendorDocumentation.rst,
# but with -DCMAKE_INSTALL_PREFIX=$PWD/install-libcxx added to cmake invocation
# ninja -C build cxx cxxabi unwind
# ninja -C build install-cxx install-cxxabi install-unwind
out/gn/bin/clang -c repro.cc -std=c++20 -nostdinc++ -isystem install-libcxx/include/c++/v1
```
Before, this built fine. After, it yields
```
% out/gn/bin/clang -c repro.cc -std=c++20 -nostdinc++ -isystem install-libcxx/include/c++/v1
In file included from repro.cc:1:
In file included from install-libcxx/include/c++/v1/type_traits:491:
install-libcxx/include/c++/v1/__type_traits/is_convertible.h:26:96: error: implicit instantiation of undefined template 'Foo<int>'
26 | _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_convertible_v = __is_convertible(_From, _To);
| ^
repro.cc:13:19: note: in instantiation of variable template specialization 'std::is_convertible_v<Baz, Foo<int>>' requested here
13 | requires(std::is_convertible_v<T, Foo<int>>)
| ^
repro.cc:13:14: note: while substituting template arguments into constraint expression here
13 | requires(std::is_convertible_v<T, Foo<int>>)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
repro.cc:6:34: note: while checking constraint satisfaction for template 'Baz<Baz>' required here
6 | struct __attribute__((lockable)) Baz {
| ^~~
repro.cc:6:34: note: while substituting deduced template arguments into function template 'Baz' [with T = Baz]
repro.cc:18:8: note: while declaring the implicit copy constructor for 'Quux'
18 | struct Quux {
| ^
repro.cc:4:7: note: template is declared here
4 | class Foo;
| ^
1 error generated.
```
The snippet is a bit weird! The motivation is that it wants to say `Baz(Foo<int> foo) {}`, but `Foo<T>` is forward-declared, so it uses that template hack, and everyone who wants to call that ctor has to make sure to include a definition of `Foo<>`.
This worked before this change, but not after. Was that behavior change intentional? (The repro only works if the `mutable` is present somehow, which suggests that this isn't intentional.)
Maybe this is also what's causing the libc++-built-as-module diag mentioned above?
https://github.com/llvm/llvm-project/pull/121199
More information about the libcxx-commits
mailing list