c++: CTAD and explicit deduction guides for copy-list-init [PR90210]
authorMarek Polacek <polacek@redhat.com>
Fri, 18 Sep 2020 20:57:34 +0000 (16:57 -0400)
committerMarek Polacek <polacek@redhat.com>
Thu, 1 Oct 2020 00:56:42 +0000 (20:56 -0400)
commitcf7dae01734eea0dfb4c387e4cd40e1f9a682f56
tree4c98b0601dc585df10374119507e2a15d623f7d0
parent660bfe61d4045c7931a7c1c3a166d0a2cd199412
c++: CTAD and explicit deduction guides for copy-list-init [PR90210]

This PR points out that we accept

  template<typename T> struct tuple { tuple(T); }; // #1
  template<typename T> explicit tuple(T t) -> tuple<T>; // #2
  tuple t = { 1 };

despite the 'explicit' deduction guide in a copy-list-initialization
context.  That's because in deduction_guides_for we first find the
user-defined deduction guide (#2), and then ctor_deduction_guides_for
creates artificial deduction guides: one from the tuple(T) constructor and
a copy guide.  So we end up with these three guides:

  (1) template<class T> tuple(T) -> tuple<T> [DECL_NONCONVERTING_P]
  (2) template<class T> tuple(tuple<T>) -> tuple<T>
  (3) template<class T> tuple(T) -> tuple<T>

Then, in do_class_deduction, we prune this set, and get rid of (1).
Then overload resolution selects (3) and we succeed.

But [over.match.list]p1 says "In copy-list-initialization, if an explicit
constructor is chosen, the initialization is ill-formed."  It also goes
on to say that this differs from other situations where only converting
constructors are considered for copy-initialization.  Therefore for
list-initialization we consider explicit constructors and complain if one
is chosen.  E.g. convert_like_internal/ck_user can give an error.

So my logic runs that we should not prune the deduction_guides_for guides
in a copy-list-initialization context, and only complain if we actually
choose an explicit deduction guide.  This matches clang++/EDG/msvc++.

gcc/cp/ChangeLog:

PR c++/90210
* pt.c (do_class_deduction): Don't prune explicit deduction guides
in copy-list-initialization.  In copy-list-initialization, if an
explicit deduction guide was selected, give an error.

gcc/testsuite/ChangeLog:

PR c++/90210
* g++.dg/cpp1z/class-deduction73.C: New test.
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1z/class-deduction73.C [new file with mode: 0644]