Skip to content

Commit 8426b51

Browse files
authored
[libcxx][test][NFC] Fix std::pair convertible tests in light of CWG2137 (#97403)
https://cplusplus.github.io/CWG/issues/2137.html This change was previously made as part of 9247013 (#77768) and later reverted in 6e4930c This change is still needed because the comment is still true: A standards-conformant compiler is currently supposed to fail this test. This also means that any future work on CWG2137 with Clang would not need to modify the libc++ test suite
1 parent 6e4bb60 commit 8426b51

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

libcxx/test/std/utilities/utility/pairs/pairs.pair/ctor.pair_U_V_move.pass.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,28 @@ int main(int, char**)
121121
test_pair_rv<CopyOnly, CopyOnly&>();
122122
test_pair_rv<CopyOnly, CopyOnly&&>();
123123

124-
test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly>();
124+
/* For ExplicitTypes::CopyOnly, two of the viable candidates for initializing from a non-const xvalue are:
125+
* pair(const pair&); // (defaulted copy constructor)
126+
* template<class U1, class U2> explicit pair(const pair<U1, U2>&&); [U1 = ExplicitTypes::CopyOnly, U2 = int]
127+
*
128+
* This results in diverging behavior for test_convertible which uses copy-list-initialization.
129+
* Prior to CWG2137, this would have selected the first (non-explicit) ctor as explicit ctors
130+
* would not be considered. Afterwards, it should select the second since it is a better match,
131+
* and then failed because it is explicit.
132+
*
133+
* This may change with future defect reports, and some compilers only have partial support
134+
* for CWG2137, so use std::is_convertible directly to avoid a copy-list-initialization
135+
*/
136+
{
137+
using P1 = std::pair<ExplicitTypes::CopyOnly, int>;
138+
using P2 = std::pair<int, ExplicitTypes::CopyOnly>;
139+
using UP1 = std::pair<ExplicitTypes::CopyOnly, int>&&;
140+
using UP2 = std::pair<int, ExplicitTypes::CopyOnly>&&;
141+
static_assert(std::is_constructible<P1, UP1>::value, "");
142+
static_assert(std::is_convertible<P1, UP1>::value, "");
143+
static_assert(std::is_constructible<P2, UP2>::value, "");
144+
static_assert(std::is_convertible<P2, UP2>::value, "");
145+
}
125146
test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&, true, false>();
126147
test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&&, true, false>();
127148

0 commit comments

Comments
 (0)