Skip to content

libc++ makes wrong assumptions in std::pair constructor #65620

Closed
llvm/llvm-project-release-prs
#702
@grisumbras

Description

@grisumbras

With latest libc++ this code doesn't compile in clang with -std=c++23.

#include <type_traits>
#include <utility>

struct kvp {
  kvp() = default;
  explicit kvp(std::pair<int, int> const& p);
};

namespace std {

template <>
struct tuple_size<kvp> : std::integral_constant<std::size_t, 2> {};

template <>
struct tuple_element<0, kvp> {
  using type = int;
};

template <>
struct tuple_element<1, kvp> {
  using type = int;
};

} // namespace std


static_assert(std::is_nothrow_move_constructible<kvp>::value);

As far as I can tell, when checking wether kvp is nothrow move constructible, the compiler tries instantiating this std::pair constructor( https://github.com/llvm/llvm-project/blob/main/libcxx/include/__utility/pair.h#L286-L291 ).
That in turn tries to compile this code (https://github.com/llvm/llvm-project/blob/main/libcxx/include/__utility/pair.h#L279-L282), which assumes that std::tuple_size<T>::value == 2 means that std::get<0>(T) and std::get<1>(T) will work.

For context, in the original code this type had get overloads in its own namespace, but not in namespace std.

Metadata

Metadata

Assignees

Labels

libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions