tsubst_initializer_list needs the same error checking as cp_parser_mem_initializer_list.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit f51f20ad47d24aee54bfbe26f31c48e0f8a78def Author: Jason Merrill <ja...@redhat.com> Date: Thu Feb 22 18:06:53 2018 -0500 PR c++/70468 - ICE with constructor delegation via typedef. * pt.c (tsubst_initializer_list): Check for other mem-initializers with constructor delegation. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index bc03f0e818e..85d1adbbe3c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -23558,6 +23558,7 @@ static tree tsubst_initializer_list (tree t, tree argvec) { tree inits = NULL_TREE; + tree target_ctor = error_mark_node; for (; t; t = TREE_CHAIN (t)) { @@ -23674,6 +23675,28 @@ tsubst_initializer_list (tree t, tree argvec) in_base_initializer = 0; } + if (target_ctor != error_mark_node + && init != error_mark_node) + { + error ("mem-initializer for %qD follows constructor delegation", + decl); + return inits; + } + /* Look for a target constructor. */ + if (init != error_mark_node + && decl && CLASS_TYPE_P (decl) + && same_type_p (decl, current_class_type)) + { + maybe_warn_cpp0x (CPP0X_DELEGATING_CTORS); + if (inits) + { + error ("constructor delegation follows mem-initializer for %qD", + TREE_PURPOSE (inits)); + continue; + } + target_ctor = init; + } + if (decl) { init = build_tree_list (decl, init); diff --git a/gcc/testsuite/g++.dg/cpp0x/dc9.C b/gcc/testsuite/g++.dg/cpp0x/dc9.C new file mode 100644 index 00000000000..b87f5ce618d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/dc9.C @@ -0,0 +1,30 @@ +// PR c++/70468 +// { dg-do compile { target c++11 } } +// { dg-additional-options -w } + +struct S {}; + +template < typename = S > +class A +{ +public: + A () : f0 (), f1 () {} // { dg-error "" } + +private: + typedef A<> f0; + int f1; +}; + +template < typename = S, typename = S > +class B +{ +}; + +template < typename T1, typename T2 > +B < T1, T2 > &operator<< (B < T1, T2 >&, const int) +{ + A<> (); +} + +template +B < S, S > &operator<< (B < S, S >&, const int);