[committed] libstdc++: Make debug containers prefer copy ctor to base ctor (PR 90102)

Jonathan Wakely jwakely@redhat.com
Tue Jun 2 17:14:22 GMT 2020


When given a type which can convert to any container-like type, the
C(const C&) copy constructor and C(const C::_Base&) converting
constructor are ambiguous. This change replaces the converting
constructor's parameter with a reference_wrapper-like type so that
calling that constructor requires an additional user-defined conversion.
This gives it a lower rank than the copy constructor, avoiding the
ambiguity.

While testing this change I discovered that __gnu_debug::forward_list
doesn't have a convering constructor from the std::forward_list base, so
this adds it.

We should probably consider whether the converting constructors should
be 'explicit' but I'm not changing that now.

libstdc++-v3/ChangeLog:

	PR libstdc++/90102
	* include/debug/deque (deque(const _Base&)): Replace parameter
	with a struct that wraps a const _Base&.
	* include/debug/forward_list (forward_list(_Base_ref)): New
	constructor.
	* include/debug/list (list(const _Base&)): Replace parameter
	with a struct that wraps a const _Base&.
	* include/debug/map.h (map(const _Base&)): Likewise.
	* include/debug/multimap.h (multimap(const _Base&)): Likewise.
	* include/debug/multiset.h (multiset(const _Base&)): Likewise.
	* include/debug/set.h (set(const _Base&)): Likewise.
	* include/debug/unordered_map (unordered_map(const _Base&))
	(unordered_multimap(const _Base&)): Likewise.
	* include/debug/unordered_set (unordered_set(const _Base&))
	(unordered_multiset(const _Base&)): Likewise.
	* testsuite/23_containers/vector/cons/destructible_debug_neg.cc:
	Adjust dg-error line number.
	* include/debug/vector (vector(const _Base&)): Likewise.
	* testsuite/23_containers/deque/debug/90102.cc: New test.
	* testsuite/23_containers/forward_list/debug/90102.cc: New test.
	* testsuite/23_containers/list/debug/90102.cc: New test.
	* testsuite/23_containers/map/debug/90102.cc: New test.
	* testsuite/23_containers/multimap/debug/90102.cc: New test.
	* testsuite/23_containers/multiset/debug/90102.cc: New test.
	* testsuite/23_containers/set/debug/90102.cc: New test.
	* testsuite/23_containers/unordered_map/debug/90102.cc: New test.
	* testsuite/23_containers/unordered_multimap/debug/90102.cc: New test.
	* testsuite/23_containers/unordered_multiset/debug/90102.cc: New test.
	* testsuite/23_containers/unordered_set/debug/90102.cc: New test.
	* testsuite/23_containers/vector/debug/90102.cc: New test.

Tested powerpc64le-linux, committed to master.


-------------- next part --------------
commit eca833b81289438ec5ae3ed4c77ffb49cfb65f34
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Jun 2 18:13:08 2020 +0100

    libstdc++: Make debug containers prefer copy ctor to base ctor (PR 90102)
    
    When given a type which can convert to any container-like type, the
    C(const C&) copy constructor and C(const C::_Base&) converting
    constructor are ambiguous. This change replaces the converting
    constructor's parameter with a reference_wrapper-like type so that
    calling that constructor requires an additional user-defined conversion.
    This gives it a lower rank than the copy constructor, avoiding the
    ambiguity.
    
    While testing this change I discovered that __gnu_debug::forward_list
    doesn't have a convering constructor from the std::forward_list base, so
    this adds it.
    
    We should probably consider whether the converting constructors should
    be 'explicit' but I'm not changing that now.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/90102
            * include/debug/deque (deque(const _Base&)): Replace parameter
            with a struct that wraps a const _Base&.
            * include/debug/forward_list (forward_list(_Base_ref)): New
            constructor.
            * include/debug/list (list(const _Base&)): Replace parameter
            with a struct that wraps a const _Base&.
            * include/debug/map.h (map(const _Base&)): Likewise.
            * include/debug/multimap.h (multimap(const _Base&)): Likewise.
            * include/debug/multiset.h (multiset(const _Base&)): Likewise.
            * include/debug/set.h (set(const _Base&)): Likewise.
            * include/debug/unordered_map (unordered_map(const _Base&))
            (unordered_multimap(const _Base&)): Likewise.
            * include/debug/unordered_set (unordered_set(const _Base&))
            (unordered_multiset(const _Base&)): Likewise.
            * testsuite/23_containers/vector/cons/destructible_debug_neg.cc:
            Adjust dg-error line number.
            * include/debug/vector (vector(const _Base&)): Likewise.
            * testsuite/23_containers/deque/debug/90102.cc: New test.
            * testsuite/23_containers/forward_list/debug/90102.cc: New test.
            * testsuite/23_containers/list/debug/90102.cc: New test.
            * testsuite/23_containers/map/debug/90102.cc: New test.
            * testsuite/23_containers/multimap/debug/90102.cc: New test.
            * testsuite/23_containers/multiset/debug/90102.cc: New test.
            * testsuite/23_containers/set/debug/90102.cc: New test.
            * testsuite/23_containers/unordered_map/debug/90102.cc: New test.
            * testsuite/23_containers/unordered_multimap/debug/90102.cc: New test.
            * testsuite/23_containers/unordered_multiset/debug/90102.cc: New test.
            * testsuite/23_containers/unordered_set/debug/90102.cc: New test.
            * testsuite/23_containers/vector/debug/90102.cc: New test.

diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
index 4d525bfc0aa..2bb99023870 100644
--- a/libstdc++-v3/include/debug/deque
+++ b/libstdc++-v3/include/debug/deque
@@ -64,6 +64,16 @@ namespace __debug
       template<typename _ItT, typename _SeqT, typename _CatT>
 	friend class ::__gnu_debug::_Safe_iterator;
 
+      // Reference wrapper for base class. Disambiguates deque(const _Base&)
+      // from copy constructor by requiring a user-defined conversion.
+      // See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       typedef typename _Base::reference			reference;
       typedef typename _Base::const_reference		const_reference;
@@ -143,8 +153,8 @@ namespace __debug
 		__gnu_debug::__base(__last), __a)
 	{ }
 
-      deque(const _Base& __x)
-      : _Base(__x) { }
+      deque(_Base_ref __x)
+      : _Base(__x._M_ref) { }
 
 #if __cplusplus < 201103L
       deque&
diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index 2fd03e70499..fc6bf6359e9 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -201,6 +201,14 @@ namespace __debug
       template<typename _ItT, typename _SeqT, typename _CatT>
 	friend class ::__gnu_debug::_Safe_iterator;
 
+      // Reference wrapper for base class. See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       typedef typename _Base::reference		reference;
       typedef typename _Base::const_reference	const_reference;
@@ -265,6 +273,8 @@ namespace __debug
 
       ~forward_list() = default;
 
+      forward_list(_Base_ref __x) : _Base(__x._M_ref) { }
+
       forward_list&
       operator=(const forward_list&) = default;
 
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index 6dd85741f81..8f2a8cb0f01 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -65,6 +65,16 @@ namespace __debug
       template<typename _ItT, typename _SeqT, typename _CatT>
 	friend class ::__gnu_debug::_Safe_iterator;
 
+      // Reference wrapper for base class. Disambiguates list(const _Base&)
+      // from copy constructor by requiring a user-defined conversion.
+      // See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       typedef typename _Base::reference			reference;
       typedef typename _Base::const_reference		const_reference;
@@ -144,8 +154,8 @@ namespace __debug
 		__gnu_debug::__base(__last), __a)
 	{ }
 
-      list(const _Base& __x)
-      : _Base(__x) { }
+      list(_Base_ref __x)
+      : _Base(__x._M_ref) { }
 
 #if __cplusplus < 201103L
       list&
diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index adbabf62915..03eb0cbe332 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -59,6 +59,16 @@ namespace __debug
       template<typename _ItT, typename _SeqT, typename _CatT>
 	friend class ::__gnu_debug::_Safe_iterator;
 
+      // Reference wrapper for base class. Disambiguates map(const _Base&)
+      // from copy constructor by requiring a user-defined conversion.
+      // See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       // types:
       typedef _Key					key_type;
@@ -126,8 +136,8 @@ namespace __debug
       ~map() = default;
 #endif
 
-      map(const _Base& __x)
-      : _Base(__x) { }
+      map(_Base_ref __x)
+      : _Base(__x._M_ref) { }
 
       explicit map(const _Compare& __comp,
 		   const _Allocator& __a = _Allocator())
diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h
index 6cba52d35dc..e8d420e2196 100644
--- a/libstdc++-v3/include/debug/multimap.h
+++ b/libstdc++-v3/include/debug/multimap.h
@@ -59,6 +59,16 @@ namespace __debug
       template<typename _ItT, typename _SeqT, typename _CatT>
 	friend class ::__gnu_debug::_Safe_iterator;
 
+      // Reference wrapper for base class. Disambiguates multimap(const _Base&)
+      // from copy constructor by requiring a user-defined conversion.
+      // See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       // types:
       typedef _Key					key_type;
@@ -138,8 +148,8 @@ namespace __debug
 		__gnu_debug::__base(__last),
 	      __comp, __a) { }
 
-      multimap(const _Base& __x)
-      : _Base(__x) { }
+      multimap(_Base_ref __x)
+      : _Base(__x._M_ref) { }
 
 #if __cplusplus < 201103L
       multimap&
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
index a2d5e717b34..152ebcd6870 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -58,6 +58,16 @@ namespace __debug
       template<typename _ItT, typename _SeqT, typename _CatT>
 	friend class ::__gnu_debug::_Safe_iterator;
 
+      // Reference wrapper for base class. Disambiguates multiset(const _Base&)
+      // from copy constructor by requiring a user-defined conversion.
+      // See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       // types:
       typedef _Key					key_type;
@@ -138,8 +148,8 @@ namespace __debug
 		__gnu_debug::__base(__last),
 		__comp, __a) { }
 
-      multiset(const _Base& __x)
-      : _Base(__x) { }
+      multiset(_Base_ref __x)
+      : _Base(__x._M_ref) { }
 
 #if __cplusplus < 201103L
       multiset&
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index 210186623df..85bc89e9915 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -58,6 +58,16 @@ namespace __debug
       template<typename _ItT, typename _SeqT, typename _CatT>
 	friend class ::__gnu_debug::_Safe_iterator;
 
+      // Reference wrapper for base class. Disambiguates set(const _Base&)
+      // from copy constructor by requiring a user-defined conversion.
+      // See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       // types:
       typedef _Key					key_type;
@@ -137,8 +147,8 @@ namespace __debug
 		__gnu_debug::__base(__last),
 		__comp, __a) { }
 
-      set(const _Base& __x)
-      : _Base(__x) { }
+      set(_Base_ref __x)
+      : _Base(__x._M_ref) { }
 
 #if __cplusplus < 201103L
       set&
diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map
index 17fbba3aade..7d55174f63b 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -81,6 +81,14 @@ namespace __debug
       template<typename _ItT, typename _SeqT>
 	friend class ::__gnu_debug::_Safe_local_iterator;
 
+      // Reference wrapper for base class. See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       typedef typename _Base::size_type			size_type;
       typedef typename _Base::hasher			hasher;
@@ -121,8 +129,8 @@ namespace __debug
 
       unordered_map(const unordered_map&) = default;
 
-      unordered_map(const _Base& __x)
-      : _Base(__x) { }
+      unordered_map(_Base_ref __x)
+      : _Base(__x._M_ref) { }
 
       unordered_map(unordered_map&&) = default;
 
@@ -776,6 +784,14 @@ namespace __debug
       template<typename _ItT, typename _SeqT>
 	friend class ::__gnu_debug::_Safe_local_iterator;
 
+      // Reference wrapper for base class. See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       typedef typename _Base::size_type			size_type;
       typedef typename _Base::hasher			hasher;
@@ -816,8 +832,8 @@ namespace __debug
 
       unordered_multimap(const unordered_multimap&) = default;
 
-      unordered_multimap(const _Base& __x)
-      : _Base(__x) { }
+      unordered_multimap(_Base_ref __x)
+      : _Base(__x._M_ref) { }
 
       unordered_multimap(unordered_multimap&&) = default;
 
diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set
index 4d30852186c..37031da947e 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -78,6 +78,14 @@ namespace __debug
       template<typename _ItT, typename _SeqT>
 	friend class ::__gnu_debug::_Safe_local_iterator;
 
+      // Reference wrapper for base class. See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       typedef typename _Base::size_type			size_type;
       typedef typename _Base::hasher			hasher;
@@ -118,8 +126,8 @@ namespace __debug
 
       unordered_set(const unordered_set&) = default;
 
-      unordered_set(const _Base& __x)
-      : _Base(__x) { }
+      unordered_set(_Base_ref __x)
+      : _Base(__x._M_ref) { }
 
       unordered_set(unordered_set&&) = default;
 
@@ -646,6 +654,14 @@ namespace __debug
       template<typename _ItT, typename _SeqT>
 	friend class ::__gnu_debug::_Safe_local_iterator;
 
+      // Reference wrapper for base class. See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       typedef typename _Base::size_type			size_type;
       typedef typename _Base::hasher			hasher;
@@ -686,8 +702,8 @@ namespace __debug
 
       unordered_multiset(const unordered_multiset&) = default;
 
-      unordered_multiset(const _Base& __x)
-      : _Base(__x) { }
+      unordered_multiset(_Base_ref __x)
+      : _Base(__x._M_ref) { }
 
       unordered_multiset(unordered_multiset&&) = default;
 
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 4c08ab61ce8..47466169f8e 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -135,6 +135,16 @@ namespace __debug
       template<typename _ItT, typename _SeqT, typename _CatT>
 	friend class ::__gnu_debug::_Safe_iterator;
 
+      // Reference wrapper for base class. Disambiguates vector(const _Base&)
+      // from copy constructor by requiring a user-defined conversion.
+      // See PR libstdc++/90102.
+      struct _Base_ref
+      {
+	_Base_ref(const _Base& __r) : _M_ref(__r) { }
+
+	const _Base& _M_ref;
+      };
+
     public:
       typedef typename _Base::reference			reference;
       typedef typename _Base::const_reference		const_reference;
@@ -207,8 +217,8 @@ namespace __debug
       : _Base(__x, __a) { }
 
       vector(vector&& __x, const allocator_type& __a)
-	noexcept( noexcept(
-	  _Base(std::declval<_Base&&>()), std::declval<const allocator_type&>()) )
+      noexcept(noexcept(
+	_Base(std::declval<_Base&&>()), std::declval<const allocator_type&>()))
       : _Safe(std::move(__x._M_safe()), __a),
 	_Base(std::move(__x._M_base()), __a),
 	_Safe_vector(std::move(__x)) { }
@@ -221,8 +231,8 @@ namespace __debug
 #endif
 
       /// Construction from a normal-mode vector
-      vector(const _Base& __x)
-      : _Base(__x) { }
+      vector(_Base_ref __x)
+      : _Base(__x._M_ref) { }
 
 #if __cplusplus < 201103L
       vector&
diff --git a/libstdc++-v3/testsuite/23_containers/deque/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/deque/debug/90102.cc
new file mode 100644
index 00000000000..80141a38ab8
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/deque>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::deque<int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::deque<int> d(static_cast<std::deque<int>>(a));
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/90102.cc
new file mode 100644
index 00000000000..a382bde98a8
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/forward_list>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::forward_list<int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::forward_list<int> d(static_cast<std::forward_list<int>>(a));
diff --git a/libstdc++-v3/testsuite/23_containers/list/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/list/debug/90102.cc
new file mode 100644
index 00000000000..49a23dc9d73
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/list>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::list<int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::list<int> d(static_cast<std::list<int>>(a));
diff --git a/libstdc++-v3/testsuite/23_containers/map/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/map/debug/90102.cc
new file mode 100644
index 00000000000..d50617f743a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/map>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::map<int, int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::map<int, int> d(static_cast<std::map<int, int>>(a));
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/multimap/debug/90102.cc
new file mode 100644
index 00000000000..f11e3fe332b
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/map>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::multimap<int, int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::multimap<int, int> d(static_cast<std::multimap<int, int>>(a));
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/multiset/debug/90102.cc
new file mode 100644
index 00000000000..32ff73863c4
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/set>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::multiset<int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::multiset<int> d(static_cast<std::multiset<int>>(a));
diff --git a/libstdc++-v3/testsuite/23_containers/set/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/set/debug/90102.cc
new file mode 100644
index 00000000000..1da9f62bc81
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/set>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::set<int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::set<int> d(static_cast<std::set<int>>(a));
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/90102.cc
new file mode 100644
index 00000000000..da7f3901e8b
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/unordered_map>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::unordered_map<int, int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::unordered_map<int, int> d(static_cast<std::unordered_map<int, int>>(a));
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/90102.cc
new file mode 100644
index 00000000000..398e7265491
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/unordered_map>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::unordered_multimap<int, int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::unordered_multimap<int, int> d(static_cast<std::unordered_multimap<int, int>>(a));
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/90102.cc
new file mode 100644
index 00000000000..a257acf7d9d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/unordered_set>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::unordered_multiset<int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::unordered_multiset<int> d(static_cast<std::unordered_multiset<int>>(a));
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/90102.cc
new file mode 100644
index 00000000000..49f352f55d7
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/unordered_set>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::unordered_set<int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::unordered_set<int> d(static_cast<std::unordered_set<int>>(a));
diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc
index 0eae8ee908c..9e58f0f4ddd 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc
@@ -46,7 +46,7 @@ test02()
 // { dg-error "value type is destructible" "" { target *-*-* } 0 }
 
 // In Debug Mode the "required from here" errors come from <debug/vector>
-// { dg-error "required from here" "" { target *-*-* } 163 }
+// { dg-error "required from here" "" { target *-*-* } 173 }
 
 // Needed because of PR c++/92193
 // { dg-prune-output "deleted function" }
diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/90102.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/90102.cc
new file mode 100644
index 00000000000..19eb1fabafe
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/debug/90102.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <debug/vector>
+
+// PR libstdc++/90102
+
+struct AnyCont
+{
+  template<class Cont, class Check = decltype(std::declval<Cont>().clear())>
+  operator Cont () const;
+} a;
+
+// This should use copy constructor, not be ambiguous
+__gnu_debug::vector<int> c(a);
+
+// Ensure construction from base container still works
+__gnu_debug::vector<int> d(static_cast<std::vector<int>>(a));


More information about the Libstdc++ mailing list