aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-04-20 02:18:39 -0400
committerJason Merrill <jason@gcc.gnu.org>2019-04-20 02:18:39 -0400
commit1474a2e567653b9a1856b4cb28a64a8eeb3c7c9d (patch)
treec44f0a4514314df1b521b0a7c1ce72bbff4dc3d3
parentd395d8e771fce88e46e5c3908e53669adb5b71c4 (diff)
downloadgcc-1474a2e567653b9a1856b4cb28a64a8eeb3c7c9d.zip
gcc-1474a2e567653b9a1856b4cb28a64a8eeb3c7c9d.tar.gz
gcc-1474a2e567653b9a1856b4cb28a64a8eeb3c7c9d.tar.bz2
PR c++/90190 - CTAD with list-constructor.
The passage quoted talks about an initializer list containing a single expression, but a braced-init-list is not an expression. * pt.c (do_class_deduction): Don't try the single element deduction if the single element is also a braced list. From-SVN: r270468
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/pt.c21
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction65.C22
3 files changed, 38 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9e2c466..11fc9de 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.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6d4140f..5f73fac 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -27325,15 +27325,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 0000000..e9711c1
--- /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{{}};
+}