From: Tomasz Kamiński Date: Thu, 12 Feb 2026 21:50:16 +0000 (+0100) Subject: libstdc++: Make __gnu_test:uneq_allocator(int) constructor explicit. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fa1149534d8580cfb88f2a82cd44d42033503206;p=thirdparty%2Fgcc.git libstdc++: Make __gnu_test:uneq_allocator(int) constructor explicit. Presence implicit conversion from int to it's allocator, makes constructing string from rvalue of same string type and int ambiguous, as none of following candidates is better: basic_string(basic_string&&, allocator_type) // conversion from int to allocator for second argument basic_string(const basic_string&, int, allocator_type) // reference adjustment for first argument This makes __gnu_test:uneq_allocator(int) constructor explicit, to avoid above issues. libstdc++-v3/ChangeLog: * testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc (__gnu_test::uneq_allocator(int)): Declare as explicit. * testsuite/std/memory/indirect/ctor.cc: Construct uneq_allocator from int explicitly. * testsuite/std/memory/polymorphic/ctor.cc: Likewise. * testsuite/std/memory/polymorphic/ctor_poly.cc: Likewise. * testsuite/util/testsuite_allocator.h: Likewise. Reviewed-by: Jonathan Wakely Signed-off-by: Tomasz Kamiński --- diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc b/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc index ecc26cb5a63..4eb174a89f3 100644 --- a/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc +++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc @@ -39,10 +39,10 @@ void test01() { using value_type = std::pair, std::pair>; - using scoped_alloc - = std::scoped_allocator_adaptor<__gnu_test::uneq_allocator>; + using uneq_alloc = __gnu_test::uneq_allocator; + using scoped_alloc = std::scoped_allocator_adaptor; - const scoped_alloc a(10); + const scoped_alloc a(uneq_alloc(10)); std::vector v(a); VERIFY( v.get_allocator().get_personality() == a.get_personality() ); @@ -65,11 +65,11 @@ void test02() { using value_type = std::pair, std::pair>; + using uneq_alloc = __gnu_test::uneq_allocator; using scoped_alloc - = std::scoped_allocator_adaptor<__gnu_test::uneq_allocator, - X::allocator_type>; + = std::scoped_allocator_adaptor; - const scoped_alloc a(10, 20); + const scoped_alloc a(uneq_alloc(10), X::allocator_type(20)); std::vector v(a); VERIFY( v.get_allocator().get_personality() == a.get_personality() ); diff --git a/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc b/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc index dfd9341582f..ec34e584b3f 100644 --- a/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc +++ b/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc @@ -16,9 +16,9 @@ using __gnu_test::uneq_allocator; using UneqAlloc = uneq_allocator; -using ScopedAlloc = std::scoped_allocator_adaptor< - uneq_allocator>, - UneqAlloc>; +using UneqVecAlloc = uneq_allocator>; +using ScopedAlloc + = std::scoped_allocator_adaptor; struct Obj { @@ -61,9 +61,10 @@ test_default_ctor() if (std::is_constant_evaluated()) return; + const ScopedAlloc scopedAlloc(UneqVecAlloc(11), UneqAlloc(22)); // Object is constructed using allocator-aware constructor. std::indirect, ScopedAlloc> - i3(std::allocator_arg, ScopedAlloc(11, 22)); + i3(std::allocator_arg, scopedAlloc); VERIFY( i3->empty() ); VERIFY( i3->get_allocator().get_personality() == 22 ); VERIFY( i3.get_allocator().get_personality() == 11 ); @@ -99,17 +100,18 @@ test_forwarding_ctor() if (std::is_constant_evaluated()) return; + const ScopedAlloc scopedAlloc(UneqVecAlloc(11), UneqAlloc(22)); std::vector v{1, 2, 3, 4, 5}; // Object is constructed using allocator-aware constructor. std::indirect, ScopedAlloc> - i7(std::allocator_arg, ScopedAlloc(11, 22), v); + i7(std::allocator_arg, scopedAlloc, v); VERIFY( i7->size() == 5 ); VERIFY( v.size() == 5 ); VERIFY( i7->get_allocator().get_personality() == 22 ); VERIFY( i7.get_allocator().get_personality() == 11 ); std::indirect, ScopedAlloc> - i8(std::allocator_arg, ScopedAlloc(11, 22), std::move(v)); + i8(std::allocator_arg, scopedAlloc, std::move(v)); VERIFY( i8->size() == 5 ); VERIFY( v.size() == 0 ); VERIFY( i8->get_allocator().get_personality() == 22 ); @@ -130,14 +132,16 @@ test_inplace_ctor() VERIFY( i2->c[1] == 0 ); std::indirect> - i3(std::allocator_arg, 42, std::in_place); + i3(std::allocator_arg, uneq_allocator(42), + std::in_place); VERIFY( i3->i == 0 ); VERIFY( i3->c[0] == 0 ); VERIFY( i3->c[1] == 0 ); VERIFY( i3.get_allocator().get_personality() == 42 ); - std::indirect> - i4(std::allocator_arg, 42, std::in_place, 10); + std::indirect> + i4(std::allocator_arg, uneq_allocator(42), + std::in_place, 10); VERIFY( i4->i == 10 ); VERIFY( i4->c[0] == 0 ); VERIFY( i4->c[1] == 0 ); @@ -174,15 +178,16 @@ test_inplace_ctor() if (std::is_constant_evaluated()) return; + const ScopedAlloc scopedAlloc(UneqVecAlloc(11), UneqAlloc(22)); std::indirect, ScopedAlloc> - i14(std::allocator_arg, ScopedAlloc(11, 22), + i14(std::allocator_arg, scopedAlloc, std::in_place); VERIFY( i14->size() == 0 ); VERIFY( i14->get_allocator().get_personality() == 22 ); VERIFY( i14.get_allocator().get_personality() == 11 ); std::indirect, ScopedAlloc> - i15(std::allocator_arg, ScopedAlloc(11, 22), + i15(std::allocator_arg, scopedAlloc, std::in_place, 5, 13); VERIFY( i15->size() == 5 ); VERIFY( i15->at(0) == 13 ); @@ -190,7 +195,7 @@ test_inplace_ctor() VERIFY( i15.get_allocator().get_personality() == 11 ); std::indirect, ScopedAlloc> - i16(std::allocator_arg, ScopedAlloc(11, 22), + i16(std::allocator_arg, scopedAlloc, std::in_place, {1, 2, 3, 4}); VERIFY( i16->size() == 4 ); VERIFY( i16->at(2) == 3 ); diff --git a/libstdc++-v3/testsuite/std/memory/polymorphic/ctor.cc b/libstdc++-v3/testsuite/std/memory/polymorphic/ctor.cc index 4d043db0ea4..a81d5615b4a 100644 --- a/libstdc++-v3/testsuite/std/memory/polymorphic/ctor.cc +++ b/libstdc++-v3/testsuite/std/memory/polymorphic/ctor.cc @@ -16,9 +16,9 @@ using __gnu_test::uneq_allocator; using UneqAlloc = uneq_allocator; -using ScopedAlloc = std::scoped_allocator_adaptor< - uneq_allocator>, - UneqAlloc>; +using UneqVecAlloc = uneq_allocator>; +using ScopedAlloc + = std::scoped_allocator_adaptor; struct Obj { @@ -48,9 +48,10 @@ test_default_ctor() if (std::is_constant_evaluated()) return; + const ScopedAlloc scopedAlloc(UneqVecAlloc(11), UneqAlloc(22)); // Object is constructed using allocator-aware constructor. std::polymorphic, ScopedAlloc> - i3(std::allocator_arg, ScopedAlloc(11, 22)); + i3(std::allocator_arg, scopedAlloc); VERIFY( i3->empty() ); VERIFY( i3->get_allocator().get_personality() == 22 ); VERIFY( i3.get_allocator().get_personality() == 11 ); @@ -82,17 +83,18 @@ test_forwarding_ctor() if (std::is_constant_evaluated()) return; + const ScopedAlloc scopedAlloc(UneqVecAlloc(11), UneqAlloc(22)); std::vector v{1, 2, 3, 4, 5}; // Object is constructed using allocator-aware constructor. std::polymorphic, ScopedAlloc> - i7(std::allocator_arg, ScopedAlloc(11, 22), v); + i7(std::allocator_arg, scopedAlloc, v); VERIFY( i7->size() == 5 ); VERIFY( v.size() == 5 ); VERIFY( i7->get_allocator().get_personality() == 22 ); VERIFY( i7.get_allocator().get_personality() == 11 ); std::polymorphic, ScopedAlloc> - i8(std::allocator_arg, ScopedAlloc(11, 22), std::move(v)); + i8(std::allocator_arg, scopedAlloc, std::move(v)); VERIFY( i8->size() == 5 ); VERIFY( v.size() == 0 ); VERIFY( i8->get_allocator().get_personality() == 22 ); @@ -113,14 +115,16 @@ test_inplace_ctor() VERIFY( i2->c[1] == 0 ); std::polymorphic> - i3(std::allocator_arg, 42, std::in_place_type); + i3(std::allocator_arg, uneq_allocator(42), + std::in_place_type); VERIFY( i3->i == 0 ); VERIFY( i3->c[0] == 0 ); VERIFY( i3->c[1] == 0 ); VERIFY( i3.get_allocator().get_personality() == 42 ); std::polymorphic> - i4(std::allocator_arg, 42, std::in_place_type, 10); + i4(std::allocator_arg, uneq_allocator(42), + std::in_place_type, 10); VERIFY( i4->i == 10 ); VERIFY( i4->c[0] == 0 ); VERIFY( i4->c[1] == 0 ); @@ -160,15 +164,16 @@ test_inplace_ctor() if (std::is_constant_evaluated()) return; + const ScopedAlloc scopedAlloc(UneqVecAlloc(11), UneqAlloc(22)); std::polymorphic, ScopedAlloc> - i14(std::allocator_arg, ScopedAlloc(11, 22), + i14(std::allocator_arg, scopedAlloc, std::in_place_type>); VERIFY( i14->size() == 0 ); VERIFY( i14->get_allocator().get_personality() == 22 ); VERIFY( i14.get_allocator().get_personality() == 11 ); std::polymorphic, ScopedAlloc> - i15(std::allocator_arg, ScopedAlloc(11, 22), + i15(std::allocator_arg, scopedAlloc, std::in_place_type>, 5, 13); VERIFY( i15->size() == 5 ); VERIFY( i15->at(0) == 13 ); @@ -176,7 +181,7 @@ test_inplace_ctor() VERIFY( i15.get_allocator().get_personality() == 11 ); std::polymorphic, ScopedAlloc> - i16(std::allocator_arg, ScopedAlloc(11, 22), + i16(std::allocator_arg, scopedAlloc, std::in_place_type>, {1, 2, 3, 4}); VERIFY( i16->size() == 4 ); VERIFY( i16->at(2) == 3 ); diff --git a/libstdc++-v3/testsuite/std/memory/polymorphic/ctor_poly.cc b/libstdc++-v3/testsuite/std/memory/polymorphic/ctor_poly.cc index cb18031a903..2c275d199d9 100644 --- a/libstdc++-v3/testsuite/std/memory/polymorphic/ctor_poly.cc +++ b/libstdc++-v3/testsuite/std/memory/polymorphic/ctor_poly.cc @@ -129,16 +129,17 @@ test_forwarding_ctor() if (std::is_constant_evaluated()) return; + const ScopedAlloc scopedAlloc(uneq_allocator(11), UneqAlloc(22)); const VecDerived v{1, 2, 3, 4, 5}; // Object is constructed using allocator-aware constructor. std::polymorphic - i5(std::allocator_arg, ScopedAlloc(11, 22), v); + i5(std::allocator_arg, scopedAlloc, v); VERIFY( *i5 == v ); VERIFY( i5->get_personality() == 22 ); VERIFY( i5.get_allocator().get_personality() == 11 ); std::polymorphic - i6(std::allocator_arg, ScopedAlloc(11, 22), auto(v)); + i6(std::allocator_arg, scopedAlloc, auto(v)); VERIFY( *i6 == v ); VERIFY( i6->get_personality() == 22 ); VERIFY( i6.get_allocator().get_personality() == 11 ); @@ -156,13 +157,15 @@ test_inplace_ctor() VERIFY( i2->get_personality() == -2 ); std::polymorphic> - i3(std::allocator_arg, 42, std::in_place_type); + i3(std::allocator_arg, uneq_allocator(42), + std::in_place_type); VERIFY( *i3 == ObjDerived() ); VERIFY( i3->get_personality() == -2 ); VERIFY( i3.get_allocator().get_personality() == 42 ); std::polymorphic> - i4(std::allocator_arg, 42, std::in_place_type, 10, 20, 30); + i4(std::allocator_arg, uneq_allocator(42), + std::in_place_type, 10, 20, 30); VERIFY( *i4 == ObjDerived(10, 20, 30) ); VERIFY( i4->get_personality() == -2 ); VERIFY( i4.get_allocator().get_personality() == 42 ); @@ -189,22 +192,23 @@ test_inplace_ctor() if (std::is_constant_evaluated()) return; + const ScopedAlloc scopedAlloc(uneq_allocator(11), UneqAlloc(22)); std::polymorphic - i8(std::allocator_arg, ScopedAlloc(11, 22), + i8(std::allocator_arg, scopedAlloc, std::in_place_type>); VERIFY( *i8 == ze ); VERIFY( i8->get_personality() == 22 ); VERIFY( i8.get_allocator().get_personality() == 11 ); std::polymorphic - i9(std::allocator_arg, ScopedAlloc(11, 22), + i9(std::allocator_arg, scopedAlloc, std::in_place_type>, 5, 13); VERIFY( *i9 == fe ); VERIFY( i9->get_personality() == 22 ); VERIFY( i9.get_allocator().get_personality() == 11 ); std::polymorphic - i10(std::allocator_arg, ScopedAlloc(11, 22), + i10(std::allocator_arg, scopedAlloc, std::in_place_type>, {1, 2, 3, 4}); VERIFY( *i10 == il ); VERIFY( i10->get_personality() == 22 ); diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h index 295b458e3c6..892a385e307 100644 --- a/libstdc++-v3/testsuite/util/testsuite_allocator.h +++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h @@ -332,7 +332,7 @@ namespace __gnu_test uneq_allocator() _GLIBCXX_USE_NOEXCEPT : personality(0) { } - _GLIBCXX_CONSTEXPR + _GLIBCXX_CONSTEXPR explicit uneq_allocator(int person) _GLIBCXX_USE_NOEXCEPT : personality(person) { }