2018-03-01 Nathan Sidwell PR c++/84434 * name-lookup.c (member_vec_dedup): Remove manually peeled iteration. Ignore dependent ctor inheritance. PR c++/84434 * g++.dg/template/pr84434.C: New. Index: cp/name-lookup.c =================================================================== --- cp/name-lookup.c (revision 258100) +++ cp/name-lookup.c (working copy) @@ -1591,68 +1591,58 @@ member_vec_dedup (vec *memb if (!len) return; - tree current = (*member_vec)[0], name = OVL_NAME (current); - tree next = NULL_TREE, next_name = NULL_TREE; - for (unsigned jx, ix = 0; ix < len; - ix = jx, current = next, name = next_name) + tree name = OVL_NAME ((*member_vec)[0]); + for (unsigned jx, ix = 0; ix < len; ix = jx) { + tree current = NULL_TREE; tree to_type = NULL_TREE; tree to_using = NULL_TREE; tree marker = NULL_TREE; - if (IDENTIFIER_CONV_OP_P (name)) - { - marker = current; - current = OVL_CHAIN (current); - name = DECL_NAME (OVL_FUNCTION (marker)); - gcc_checking_assert (name == conv_op_identifier); - } - if (TREE_CODE (current) == USING_DECL) + for (jx = ix; jx < len; jx++) { - current = strip_using_decl (current); - if (is_overloaded_fn (current)) - current = NULL_TREE; - else if (TREE_CODE (current) == USING_DECL) + tree next = (*member_vec)[jx]; + if (jx != ix) { - to_using = current; - current = NULL_TREE; + tree next_name = OVL_NAME (next); + if (next_name != name) + { + name = next_name; + break; + } } - } - if (current && DECL_DECLARES_TYPE_P (current)) - { - to_type = current; - current = NULL_TREE; - } - - for (jx = ix + 1; jx < len; jx++) - { - next = (*member_vec)[jx]; - next_name = OVL_NAME (next); - if (next_name != name) - break; - - if (marker) + if (IDENTIFIER_CONV_OP_P (name)) { - gcc_checking_assert (OVL_FUNCTION (marker) - == OVL_FUNCTION (next)); + marker = next; next = OVL_CHAIN (next); } if (TREE_CODE (next) == USING_DECL) { + if (IDENTIFIER_CTOR_P (name)) + /* Dependent inherited ctor. */ + continue; + next = strip_using_decl (next); - if (is_overloaded_fn (next)) - next = NULL_TREE; - else if (TREE_CODE (next) == USING_DECL) + if (TREE_CODE (next) == USING_DECL) { to_using = next; - next = NULL_TREE; + continue; } + + if (is_overloaded_fn (next)) + continue; } - if (next && DECL_DECLARES_TYPE_P (next)) - to_type = next; + if (DECL_DECLARES_TYPE_P (next)) + { + to_type = next; + continue; + } + + if (!current) + current = next; } if (to_using) @@ -1671,13 +1661,15 @@ member_vec_dedup (vec *memb current = stat_hack (current, to_type); } - gcc_assert (current); - if (marker) + if (current) { - OVL_CHAIN (marker) = current; - current = marker; + if (marker) + { + OVL_CHAIN (marker) = current; + current = marker; + } + (*member_vec)[store++] = current; } - (*member_vec)[store++] = current; } while (store++ < len) Index: testsuite/g++.dg/template/pr84434.C =================================================================== --- testsuite/g++.dg/template/pr84434.C (revision 0) +++ testsuite/g++.dg/template/pr84434.C (working copy) @@ -0,0 +1,23 @@ +// PR c++/84434 ICE with deduction guide and dependent using decl +// { dg-do compile { target c++17 } } + +template class B { +public: + template B (U) {} +}; + +template +struct scope_guard : B { + using base_type = B; + + using base_type::base_type; + + ~scope_guard() = default; +}; + +template +scope_guard (T) -> scope_guard; + +void Frob () { + scope_guard (1); +}