diff mbox series

[C++] PR c++/90190 - CTAD with list-constructor.

Message ID 20190420061517.20046-1-jason@redhat.com
State New
Headers show
Series [C++] PR c++/90190 - CTAD with list-constructor. | expand

Commit Message

Jason Merrill April 20, 2019, 6:15 a.m. UTC
The passage quoted talks about an initializer list containing a single
expression, but a braced-init-list is not an expression.

Tested x86_64-pc-linux-gnu, applying to trunk.

	* pt.c (do_class_deduction): Don't try the single element deduction
	if the single element is also a braced list.
---
 gcc/cp/pt.c                                   | 21 ++++++++++--------
 .../g++.dg/cpp1z/class-deduction65.C          | 22 +++++++++++++++++++
 gcc/cp/ChangeLog                              |  4 ++++
 3 files changed, 38 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction65.C


base-commit: dbb68bd891ba4d345f3667c3ae7f1bfda04233b2
prerequisite-patch-id: 7a1f94e26f7a69284c97add19c28b3b39b2cb58f
diff mbox series

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3a11eaa7630..515f9d585cf 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -27327,15 +27327,18 @@  do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
 	     where U is a specialization of C or a class derived from a
 	     specialization of C.  */
 	  tree elt = CONSTRUCTOR_ELT (init, 0)->value;
-	  tree etype = TREE_TYPE (elt);
-
-	  tree tparms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
-	  tree targs = make_tree_vec (TREE_VEC_LENGTH (tparms));
-	  int err = unify (tparms, targs, type, etype,
-			   UNIFY_ALLOW_DERIVED, /*explain*/false);
-	  if (err == 0)
-	    try_list_ctor = false;
-	  ggc_free (targs);
+	  if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
+	    {
+	      tree etype = TREE_TYPE (elt);
+	      tree tparms = (INNERMOST_TEMPLATE_PARMS
+			     (DECL_TEMPLATE_PARMS (tmpl)));
+	      tree targs = make_tree_vec (TREE_VEC_LENGTH (tparms));
+	      int err = unify (tparms, targs, type, etype,
+			       UNIFY_ALLOW_DERIVED, /*explain*/false);
+	      if (err == 0)
+		try_list_ctor = false;
+	      ggc_free (targs);
+	    }
 	}
       if (try_list_ctor || is_std_init_list (type))
 	args = make_tree_vector_single (init);
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction65.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction65.C
new file mode 100644
index 00000000000..e9711c1acb8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction65.C
@@ -0,0 +1,22 @@ 
+// PR c++/90190
+// { dg-do compile { target c++17 } }
+
+#include <initializer_list>
+
+enum class X {};
+
+struct Term {
+  double a;
+  X i;
+};
+
+template <class It = const Term *>
+struct sum {
+  sum(std::initializer_list<Term>) {}
+};
+
+int main() {
+  auto c2 = sum{{1, X()}, {2, X()}};
+  auto c1 = sum{{1, X()}};  // fails only this
+  auto c0 = sum{{}};
+}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e7521446b59..acbb74b6af3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@ 
 2019-04-19  Jason Merrill  <jason@redhat.com>
 
+	PR c++/90190 - CTAD with list-constructor.
+	* pt.c (do_class_deduction): Don't try the single element deduction
+	if the single element is also a braced list.
+
 	PR c++/90171 - ICE with destroying delete with size_t parm.
 	* call.c (sized_deallocation_fn_p): New.  Use it instead of
 	second_parm_is_size_t in most cases.