[PATCH] c++: CTAD and deduction guide selection [PR86439]

Jason Merrill jason@redhat.com
Tue Jun 22 19:56:26 GMT 2021


On 6/22/21 2:45 PM, Patrick Palka wrote:
> During CTAD, we select the best viable deduction guide via
> build_new_function_call, which performs overload resolution on the set
> of candidate guides and then forms a call to the guide.  As the PR
> points out, this latter step is unnecessary and occasionally gives us
> the wrong answer since a call to the selected guide may be ill-formed,
> or forming the call may have side effects such as prematurely deducing
> the type of a {}.
> 
> This patch introduces a specialized subroutine modeled off of
> build_new_function_call that stops short of building a call to the
> selected function, and makes do_class_deduction use this subroutine
> instead.  And since we no longer build a call, do_class_deduction
> doesn't need to set tf_decltype or cp_unevaluated_operand.
> 
> This change causes us to reject some container CTAD examples in the
> libstdc++ testsuite due to deduction failure for {}, which AFAICT is the
> correct behavior.  Previously, in the case of e.g. the first removed
> example for std::map, the type of {} would be deduced to less<int> as a
> side effect of forming the call to the selected guide
> 
>    template<typename _Key, typename _Tp, typename _Compare = less<_Key>,
>               typename _Allocator = allocator<pair<const _Key, _Tp>>,
>               typename = _RequireNotAllocator<_Compare>,
>               typename = _RequireAllocator<_Allocator>>
>        map(initializer_list<pair<_Key, _Tp>>,
>            _Compare = _Compare(), _Allocator = _Allocator())
>        -> map<_Key, _Tp, _Compare, _Allocator>;
> 
> which made later overload resolution for the constructor call
> unambiguous.  Now, the type of {} remains undeduced until constructor
> overload resolution, and we complain about ambiguity with the two
> constructors
> 
>    map(initializer_list<value_type> __l,
>        const _Compare& __comp = _Compare(),
>        const allocator_type& __a = allocator_type())
> 
>    map(initializer_list<value_type> __l, const allocator_type& __a)
> 
> This patch just removes these problematic container CTAD examples.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk?

OK.

> 	PR c++/86439
> 
> gcc/cp/ChangeLog:
> 
> 	* call.c (print_error_for_call_failure): Constify 'args'
> 	parameter.
> 	(perform_dguide_overload_resolution): Define.
> 	* cp-tree.h: (perform_dguide_overload_resolution): Declare.
> 	* pt.c (do_class_deduction): Use perform_dguide_overload_resolution
> 	instead of build_new_function_call.  Don't use tf_decltype or
> 	set cp_unevaluated_operand.  Remove unnecessary NULL_TREE tests.
> 
> libstdc++-v3/ChangeLog:
> 
> 	* testsuite/23_containers/map/cons/deduction.cc: Remove
> 	ambiguous CTAD constructs.
> 	* testsuite/23_containers/multimap/cons/deduction.cc: Likewise.
> 	* testsuite/23_containers/multiset/cons/deduction.cc: Likewise.
> 	* testsuite/23_containers/set/cons/deduction.cc: Likewise.
> 	* testsuite/23_containers/unordered_map/cons/deduction.cc: Likewise.
> 	* testsuite/23_containers/unordered_multimap/cons/deduction.cc:
> 	Likewise.
> 	* testsuite/23_containers/unordered_multiset/cons/deduction.cc:
> 	Likewise.
> 	* testsuite/23_containers/unordered_set/cons/deduction.cc: Likewise.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/cpp1z/class-deduction88.C: New test.
> 	* g++.dg/cpp1z/class-deduction89.C: New test.
> 	* g++.dg/cpp1z/class-deduction90.C: New test.
> ---
>   gcc/cp/call.c                                 | 36 +++++++++++++++-
>   gcc/cp/cp-tree.h                              |  2 +
>   gcc/cp/pt.c                                   | 41 +++++++------------
>   .../g++.dg/cpp1z/class-deduction88.C          | 20 +++++++++
>   .../g++.dg/cpp1z/class-deduction89.C          | 15 +++++++
>   .../g++.dg/cpp1z/class-deduction90.C          | 16 ++++++++
>   .../23_containers/map/cons/deduction.cc       | 19 ---------
>   .../23_containers/multimap/cons/deduction.cc  | 20 ---------
>   .../23_containers/multiset/cons/deduction.cc  | 14 -------
>   .../23_containers/set/cons/deduction.cc       | 15 -------
>   .../unordered_map/cons/deduction.cc           | 16 --------
>   .../unordered_multimap/cons/deduction.cc      | 16 --------
>   .../unordered_multiset/cons/deduction.cc      | 10 -----
>   .../unordered_set/cons/deduction.cc           | 10 -----
>   14 files changed, 102 insertions(+), 148 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction88.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction89.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction90.C
> 
> diff --git a/gcc/cp/call.c b/gcc/cp/call.c
> index 9f03534c20c..aafc7acca24 100644
> --- a/gcc/cp/call.c
> +++ b/gcc/cp/call.c
> @@ -4629,7 +4629,7 @@ perform_overload_resolution (tree fn,
>      functions.  */
>   
>   static void
> -print_error_for_call_failure (tree fn, vec<tree, va_gc> *args,
> +print_error_for_call_failure (tree fn, const vec<tree, va_gc> *args,
>   			      struct z_candidate *candidates)
>   {
>     tree targs = NULL_TREE;
> @@ -4654,6 +4654,40 @@ print_error_for_call_failure (tree fn, vec<tree, va_gc> *args,
>       print_z_candidates (loc, candidates);
>   }
>   
> +/* Perform overload resolution on the set of deduction guides DGUIDES
> +   using ARGS.  Returns the selected deduction guide, or error_mark_node
> +   if overload resolution fails.  */
> +
> +tree
> +perform_dguide_overload_resolution (tree dguides, const vec<tree, va_gc> *args,
> +				    tsubst_flags_t complain)
> +{
> +  z_candidate *candidates;
> +  bool any_viable_p;
> +  tree result;
> +
> +  gcc_assert (deduction_guide_p (OVL_FIRST (dguides)));
> +
> +  /* Get the high-water mark for the CONVERSION_OBSTACK.  */
> +  void *p = conversion_obstack_alloc (0);
> +
> +  z_candidate *cand = perform_overload_resolution (dguides, args, &candidates,
> +						   &any_viable_p, complain);
> +  if (!cand)
> +    {
> +      if (complain & tf_error)
> +	print_error_for_call_failure (dguides, args, candidates);
> +      result = error_mark_node;
> +    }
> +  else
> +    result = cand->fn;
> +
> +  /* Free all the conversions we allocated.  */
> +  obstack_free (&conversion_obstack, p);
> +
> +  return result;
> +}
> +
>   /* Return an expression for a call to FN (a namespace-scope function,
>      or a static member function) with the ARGS.  This may change
>      ARGS.  */
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index 36f99ccf189..6f713719589 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -6437,6 +6437,8 @@ extern void complain_about_bad_argument	(location_t arg_loc,
>   						 tree from_type, tree to_type,
>   						 tree fndecl, int parmnum);
>   extern void maybe_inform_about_fndecl_for_bogus_argument_init (tree, int);
> +extern tree perform_dguide_overload_resolution	(tree, const vec<tree, va_gc> *,
> +						 tsubst_flags_t);
>   
>   
>   /* A class for recording information about access failures (e.g. private
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index 15947b2c812..732fb405adf 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -29382,7 +29382,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
>       if (tree guide = maybe_aggr_guide (tmpl, init, args))
>         cands = lookup_add (guide, cands);
>   
> -  tree call = error_mark_node;
> +  tree fndecl = error_mark_node;
>   
>     /* If this is list-initialization and the class has a list constructor, first
>        try deducing from the list as a single argument, as [over.match.list].  */
> @@ -29396,11 +29396,9 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
>         }
>     if (list_cands)
>       {
> -      ++cp_unevaluated_operand;
> -      call = build_new_function_call (list_cands, &args, tf_decltype);
> -      --cp_unevaluated_operand;
> +      fndecl = perform_dguide_overload_resolution (list_cands, args, tf_none);
>   
> -      if (call == error_mark_node)
> +      if (fndecl == error_mark_node)
>   	{
>   	  /* That didn't work, now try treating the list as a sequence of
>   	     arguments.  */
> @@ -29416,31 +29414,22 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
>   	     "user-declared constructors", type);
>         return error_mark_node;
>       }
> -  else if (!cands && call == error_mark_node)
> +  else if (!cands && fndecl == error_mark_node)
>       {
>         error ("cannot deduce template arguments of %qT, as it has no viable "
>   	     "deduction guides", type);
>         return error_mark_node;
>       }
>   
> -  if (call == error_mark_node)
> -    {
> -      ++cp_unevaluated_operand;
> -      call = build_new_function_call (cands, &args, tf_decltype);
> -      --cp_unevaluated_operand;
> -    }
> +  if (fndecl == error_mark_node)
> +    fndecl = perform_dguide_overload_resolution (cands, args, tf_none);
>   
> -  if (call == error_mark_node)
> +  if (fndecl == error_mark_node)
>       {
>         if (complain & tf_warning_or_error)
>   	{
>   	  error ("class template argument deduction failed:");
> -
> -	  ++cp_unevaluated_operand;
> -	  call = build_new_function_call (cands, &args,
> -					  complain | tf_decltype);
> -	  --cp_unevaluated_operand;
> -
> +	  perform_dguide_overload_resolution (cands, args, complain);
>   	  if (elided)
>   	    inform (input_location, "explicit deduction guides not considered "
>   		    "for copy-initialization");
> @@ -29451,8 +29440,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
>        constructor is chosen, the initialization is ill-formed.  */
>     else if (flags & LOOKUP_ONLYCONVERTING)
>       {
> -      tree fndecl = cp_get_callee_fndecl_nofold (call);
> -      if (fndecl && DECL_NONCONVERTING_P (fndecl))
> +      if (DECL_NONCONVERTING_P (fndecl))
>   	{
>   	  if (complain & tf_warning_or_error)
>   	    {
> @@ -29470,12 +29458,10 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
>   
>     /* If CTAD succeeded but the type doesn't have any explicit deduction
>        guides, this deduction might not be what the user intended.  */
> -  if (call != error_mark_node && !any_dguides_p)
> +  if (fndecl != error_mark_node && !any_dguides_p)
>       {
> -      tree fndecl = cp_get_callee_fndecl_nofold (call);
> -      if (fndecl != NULL_TREE
> -	  && (!DECL_IN_SYSTEM_HEADER (fndecl)
> -	      || global_dc->dc_warn_system_headers)
> +      if ((!DECL_IN_SYSTEM_HEADER (fndecl)
> +	   || global_dc->dc_warn_system_headers)
>   	  && warning (OPT_Wctad_maybe_unsupported,
>   		      "%qT may not intend to support class template argument "
>   		      "deduction", type))
> @@ -29483,7 +29469,8 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
>   		"warning");
>       }
>   
> -  return cp_build_qualified_type (TREE_TYPE (call), cp_type_quals (ptype));
> +  return cp_build_qualified_type (TREE_TYPE (TREE_TYPE (fndecl)),
> +				  cp_type_quals (ptype));
>   }
>   
>   /* Replace occurrences of 'auto' in TYPE with the appropriate type deduced
> diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction88.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction88.C
> new file mode 100644
> index 00000000000..f8fea966696
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction88.C
> @@ -0,0 +1,20 @@
> +// PR c++/86439
> +// { dg-do compile { target c++17 } }
> +
> +struct NC {
> +  NC() = default;
> +  NC(NC const&) = delete;
> +  NC& operator=(NC const&) = delete;
> +};
> +
> +template <int>
> +struct C {
> +  C(NC const&);
> +};
> +
> +C(NC) -> C<0>;
> +
> +int main() {
> +  NC nc;
> +  C c(nc);
> +}
> diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction89.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction89.C
> new file mode 100644
> index 00000000000..dd898573022
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction89.C
> @@ -0,0 +1,15 @@
> +// PR c++/86439
> +// { dg-do compile { target c++17 } }
> +
> +struct B { };
> +struct C { };
> +
> +template<class T>
> +struct A {
> +  A(T, B);
> +};
> +
> +template<class T>
> +A(T, C) -> A<T>;
> +
> +A a(0, {});
> diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction90.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction90.C
> new file mode 100644
> index 00000000000..8b93193c7b0
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction90.C
> @@ -0,0 +1,16 @@
> +// PR c++/86439
> +// { dg-do compile { target c++17 } }
> +
> +struct less { };
> +struct allocator { };
> +
> +template<class T, class U = less, class V = allocator>
> +struct A {
> +  A(T, U);
> +  A(T, V);
> +};
> +
> +template<class T, class U = less>
> +A(T, U) -> A<T>;
> +
> +A a(0, {}); // { dg-error "ambiguous" }
> diff --git a/libstdc++-v3/testsuite/23_containers/map/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/map/cons/deduction.cc
> index e9628c4ac32..8def11ed574 100644
> --- a/libstdc++-v3/testsuite/23_containers/map/cons/deduction.cc
> +++ b/libstdc++-v3/testsuite/23_containers/map/cons/deduction.cc
> @@ -39,10 +39,6 @@ static_assert(std::is_same_v<
>   	      std::map<int, double>>);
>   */
>   
> -static_assert(std::is_same_v<
> -	      decltype(std::map{{std::pair{1, 2.0}, {2, 3.0}, {3, 4.0}}, {}}),
> -	      std::map<int, double>>);
> -
>   /* This is not deducible, ambiguous candidates:
>    * map(initializer_list<value_type>, const Compare&, const _Allocator& = {})
>    * map(initializer_list<value_type>, const _Allocator&)
> @@ -90,11 +86,6 @@ void f()
>   				  std::less<int>{}, {}}),
>   		std::map<int, double>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::map(x.begin(), x.end(),
> -				  {})),
> -		std::map<int, double>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::map{x.begin(), x.end(),
>   				  std::allocator<value_type>{}}),
> @@ -143,11 +134,6 @@ void g()
>   				  std::less<int>{}, {}}),
>   		std::map<int, double>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::map(x.begin(), x.end(),
> -				  {})),
> -		std::map<int, double>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::map{x.begin(), x.end(),
>   				  std::allocator<value_type>{}}),
> @@ -193,11 +179,6 @@ void h()
>   				  std::less<int>{}, {}}),
>   		std::map<int, double>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::map(x.begin(), x.end(),
> -				  {})),
> -		std::map<int, double>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::map{x.begin(), x.end(),
>   				  std::allocator<value_type>{}}),
> diff --git a/libstdc++-v3/testsuite/23_containers/multimap/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/multimap/cons/deduction.cc
> index 791cc963479..ff855081ab3 100644
> --- a/libstdc++-v3/testsuite/23_containers/multimap/cons/deduction.cc
> +++ b/libstdc++-v3/testsuite/23_containers/multimap/cons/deduction.cc
> @@ -40,11 +40,6 @@ static_assert(std::is_same_v<
>   	      std::multimap<int, double>>);
>   */
>   
> -static_assert(std::is_same_v<
> -	      decltype(std::multimap{{std::pair{1, 2.0}, {2, 3.0}, {3, 4.0}},
> -		    {}}),
> -	      std::multimap<int, double>>);
> -
>   static_assert(std::is_same_v<
>   	      decltype(std::multimap{{value_type{1, 2.0}, {2, 3.0}, {3, 4.0}},
>   				     {}, SimpleAllocator<value_type>{}}),
> @@ -75,11 +70,6 @@ void f()
>   				       std::less<int>{}, {}}),
>   		std::multimap<int, double>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::multimap(x.begin(), x.end(),
> -				       {})),
> -		std::multimap<int, double>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::multimap{x.begin(), x.end(),
>   		      {},
> @@ -117,11 +107,6 @@ void g()
>   				       std::less<int>{}, {}}),
>   		std::multimap<int, double>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::multimap(x.begin(), x.end(),
> -				       {})),
> -		std::multimap<int, double>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::multimap{x.begin(), x.end(),
>   				       {},
> @@ -156,11 +141,6 @@ void h()
>   				       std::less<int>{}, {}}),
>   		std::multimap<int, double>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::multimap(x.begin(), x.end(),
> -				       {})),
> -		std::multimap<int, double>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::multimap{x.begin(), x.end(),
>   				       {},
> diff --git a/libstdc++-v3/testsuite/23_containers/multiset/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/multiset/cons/deduction.cc
> index ad12755ccc6..be7ca237e78 100644
> --- a/libstdc++-v3/testsuite/23_containers/multiset/cons/deduction.cc
> +++ b/libstdc++-v3/testsuite/23_containers/multiset/cons/deduction.cc
> @@ -19,10 +19,6 @@ static_assert(std::is_same_v<
>   	      decltype(std::multiset{{1, 2, 3}, std::less<int>{}, {}}),
>   	      std::multiset<int>>);
>   
> -static_assert(std::is_same_v<
> -	      decltype(std::multiset{{1, 2, 3}, {}}),
> -	      std::multiset<int>>);
> -
>   static_assert(std::is_same_v<
>   	      decltype(std::multiset{{1, 2, 3}, SimpleAllocator<int>{}}),
>   	      std::multiset<int, std::less<int>, SimpleAllocator<int>>>);
> @@ -50,11 +46,6 @@ void f()
>   		      std::less<int>{}, {}}),
>   		std::multiset<int>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::multiset(x.begin(), x.end(),
> -				  {})),
> -		std::multiset<int>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::multiset{x.begin(), x.end(),
>   				       std::allocator<int>{}}),
> @@ -101,11 +92,6 @@ void g()
>   				  std::less<int>{}, {}}),
>   		std::multiset<int>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::multiset(x.begin(), x.end(),
> -				  {})),
> -		std::multiset<int>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::multiset{x.begin(), x.end(),
>   				  std::allocator<value_type>{}}),
> diff --git a/libstdc++-v3/testsuite/23_containers/set/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/set/cons/deduction.cc
> index 89a2c43b937..48d1a3ebbe2 100644
> --- a/libstdc++-v3/testsuite/23_containers/set/cons/deduction.cc
> +++ b/libstdc++-v3/testsuite/23_containers/set/cons/deduction.cc
> @@ -20,11 +20,6 @@ static_assert(std::is_same_v<
>   		    std::less<int>{}, {}}),
>   	      std::set<int>>);
>   
> -static_assert(std::is_same_v<
> -	      decltype(std::set{{1, 2, 3},
> -		    {}}),
> -	      std::set<int>>);
> -
>   static_assert(std::is_same_v<
>   	      decltype(std::set{{1, 2, 3},
>   		    SimpleAllocator<int>{}}),
> @@ -56,11 +51,6 @@ void f()
>   		      std::less<int>{}, {}}),
>   		std::set<int>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::set(x.begin(), x.end(),
> -				  {})),
> -		std::set<int>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::set{x.begin(), x.end(),
>   		      {},
> @@ -102,11 +92,6 @@ void g()
>   				  std::less<int>{}, {}}),
>   		std::set<int>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::set(x.begin(), x.end(),
> -				  {})),
> -		std::set<int>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::set{x.begin(), x.end(),
>   				  std::allocator<value_type>{}}),
> diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/deduction.cc
> index d8489b23f8a..bd266492b2a 100644
> --- a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/deduction.cc
> +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/deduction.cc
> @@ -21,12 +21,6 @@ static_assert(std::is_same_v<
>   		1}),
>   	      std::unordered_map<int, double>>);
>   
> -static_assert(std::is_same_v<
> -	      decltype(std::unordered_map{{std::pair{1, 2.0},
> -		      {2, 3.0}, {3, 4.0}},
> -		    {}, std::hash<int>{}, {}}),
> -	      std::unordered_map<int, double>>);
> -
>   static_assert(std::is_same_v<
>   	      decltype(std::unordered_map{{std::pair{1, 2.0},
>   		      {2, 3.0}, {3, 4.0}},
> @@ -57,16 +51,6 @@ void f()
>   		      std::allocator<std::pair<const int, double>>{}}),
>   		std::unordered_map<int, double>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::unordered_map{x.begin(), x.end(),
> -		      {}, std::hash<int>{}, {}}),
> -		std::unordered_map<int, double>>);
> -
> -  static_assert(std::is_same_v<
> -		decltype(std::unordered_map(x.begin(), x.end(),
> -		      {})),
> -		std::unordered_map<int, double>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::unordered_map{x.begin(), x.end(), 1}),
>   		std::unordered_map<int, double>>);
> diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/deduction.cc
> index 13f54d43451..74a0165574d 100644
> --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/deduction.cc
> +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/deduction.cc
> @@ -15,12 +15,6 @@ static_assert(std::is_same_v<
>   		      {2, 3.0}, {3, 4.0}}}),
>   	      std::unordered_multimap<int, double>>);
>   
> -static_assert(std::is_same_v<
> -	      decltype(std::unordered_multimap{{std::pair{1, 2.0},
> -		      {2, 3.0}, {3, 4.0}},
> -		    {}, std::hash<int>{}, {}}),
> -	      std::unordered_multimap<int, double>>);
> -
>   static_assert(std::is_same_v<
>   	      decltype(std::unordered_multimap{{std::pair{1, 2.0},
>   		      {2, 3.0}, {3, 4.0}},
> @@ -66,16 +60,6 @@ void f()
>   		      std::allocator<std::pair<const int, double>>{}}),
>   		std::unordered_multimap<int, double>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::unordered_multimap{x.begin(), x.end(),
> -		      {}, std::hash<int>{}, {}}),
> -		std::unordered_multimap<int, double>>);
> -
> -  static_assert(std::is_same_v<
> -		decltype(std::unordered_multimap(x.begin(), x.end(),
> -				  {})),
> -		std::unordered_multimap<int, double>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::unordered_multimap(x.begin(), x.end(), 1)),
>   		std::unordered_multimap<int, double>>);
> diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/deduction.cc
> index 1850237e44c..e3006fdbfe3 100644
> --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/deduction.cc
> +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/deduction.cc
> @@ -9,11 +9,6 @@ static_assert(std::is_same_v<
>   	      decltype(std::unordered_multiset{1, 2, 3}),
>   	      std::unordered_multiset<int>>);
>   
> -static_assert(std::is_same_v<
> -	      decltype(std::unordered_multiset{{1, 2, 3},
> -		    0, std::hash<int>{}, {}}),
> -	      std::unordered_multiset<int>>);
> -
>   static_assert(std::is_same_v<
>   	      decltype(std::unordered_multiset{{1, 2, 3},
>   		    {}}),
> @@ -76,11 +71,6 @@ void f()
>   		      std::allocator<int>{}}),
>   		std::unordered_multiset<int>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::unordered_multiset{x.begin(), x.end(),
> -		      {}, std::hash<int>{}, {}}),
> -		std::unordered_multiset<int>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::unordered_multiset(x.begin(), x.end(),
>   		      {})),
> diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/deduction.cc
> index a745dce0fba..69922cd92e7 100644
> --- a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/deduction.cc
> +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/deduction.cc
> @@ -9,11 +9,6 @@ static_assert(std::is_same_v<
>   	      decltype(std::unordered_set{1, 2, 3}),
>   	      std::unordered_set<int>>);
>   
> -static_assert(std::is_same_v<
> -	      decltype(std::unordered_set{{1, 2, 3},
> -		    0, std::hash<int>{}, {}}),
> -	      std::unordered_set<int>>);
> -
>   static_assert(std::is_same_v<
>   	      decltype(std::unordered_set{{1, 2, 3},
>   		    {}}),
> @@ -71,11 +66,6 @@ void f()
>   		      std::allocator<int>{}}),
>   		std::unordered_set<int>>);
>   
> -  static_assert(std::is_same_v<
> -		decltype(std::unordered_set{x.begin(), x.end(),
> -		      {}, std::hash<int>{}, {}}),
> -		std::unordered_set<int>>);
> -
>     static_assert(std::is_same_v<
>   		decltype(std::unordered_set(x.begin(), x.end(),
>   		      {})),
> 



More information about the Gcc-patches mailing list