diff options
author | Patrick Palka <ppalka@redhat.com> | 2021-08-11 15:59:22 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2021-08-11 15:59:22 -0400 |
commit | 7e39d1a15f5276f72ee478a692445569bb646e65 (patch) | |
tree | c3c5ef9f887c45f799a65b2f212ab848bcd110e2 | |
parent | 6186708312780bb2139da01946abdde39667e985 (diff) | |
download | gcc-7e39d1a15f5276f72ee478a692445569bb646e65.zip gcc-7e39d1a15f5276f72ee478a692445569bb646e65.tar.gz gcc-7e39d1a15f5276f72ee478a692445569bb646e65.tar.bz2 |
c++: recognize class-scope non-template dguides [PR79501]
It looks like we still don't recognize class-scope non-template
deduction guides even after r12-2260. This is because deduction guides
are tagged as such in cp_parser_init_declarator after calling
cp_parser_declarator, but in cp_parser_member_declaration we call
cp_parser_declarator directly.
So let's tag them in cp_parser_member_declaration as well.
PR c++/79501
gcc/cp/ChangeLog:
* parser.c (maybe_adjust_declarator_for_dguide): New, split
out from ...
(cp_parser_init_declarator): ... here.
(cp_parser_member_declaration): Use it.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/class-deduction98.C: New test.
-rw-r--r-- | gcc/cp/parser.c | 63 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/class-deduction98.C | 10 |
2 files changed, 54 insertions, 19 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 87e8d37..b5e117d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -22078,6 +22078,37 @@ warn_about_ambiguous_parse (const cp_decl_specifier_seq *decl_specifiers, } } +/* If DECLARATOR with DECL_SPECS is a function declarator that has + the form of a deduction guide, tag it as such. CTOR_DTOR_OR_CONV_P + has the same meaning as in cp_parser_declarator. */ + +static void +cp_parser_maybe_adjust_declarator_for_dguide (cp_parser *parser, + cp_decl_specifier_seq *decl_specs, + cp_declarator *declarator, + int *ctor_dtor_or_conv_p) +{ + if (cxx_dialect >= cxx17 + && *ctor_dtor_or_conv_p <= 0 + && !decl_specs->type + && !decl_specs->any_type_specifiers_p + && function_declarator_p (declarator)) + { + cp_declarator *id = get_id_declarator (declarator); + tree name = id->u.id.unqualified_name; + parser->scope = id->u.id.qualifying_scope; + tree tmpl = cp_parser_lookup_name_simple (parser, name, id->id_loc); + if (tmpl + && (DECL_CLASS_TEMPLATE_P (tmpl) + || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))) + { + id->u.id.unqualified_name = dguide_name (tmpl); + id->u.id.sfk = sfk_deduction_guide; + *ctor_dtor_or_conv_p = 1; + } + } +} + /* Declarators [gram.dcl.decl] */ /* Parse an init-declarator. @@ -22254,25 +22285,13 @@ cp_parser_init_declarator (cp_parser* parser, if (function_declarator_p (declarator)) { - /* Handle C++17 deduction guides. */ - if (!decl_specifiers->type - && !decl_specifiers->any_type_specifiers_p - && ctor_dtor_or_conv_p <= 0 - && cxx_dialect >= cxx17) - { - cp_declarator *id = get_id_declarator (declarator); - tree name = id->u.id.unqualified_name; - parser->scope = id->u.id.qualifying_scope; - tree tmpl = cp_parser_lookup_name_simple (parser, name, id->id_loc); - if (tmpl - && (DECL_CLASS_TEMPLATE_P (tmpl) - || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))) - { - id->u.id.unqualified_name = dguide_name (tmpl); - id->u.id.sfk = sfk_deduction_guide; - ctor_dtor_or_conv_p = 1; - } - } + /* Handle C++17 deduction guides. Note that class-scope + non-template deduction guides are instead handled in + cp_parser_member_declaration. */ + cp_parser_maybe_adjust_declarator_for_dguide (parser, + decl_specifiers, + declarator, + &ctor_dtor_or_conv_p); if (!member_p && !cp_parser_error_occurred (parser)) warn_about_ambiguous_parse (decl_specifiers, declarator); @@ -26956,6 +26975,12 @@ cp_parser_member_declaration (cp_parser* parser) goto out; } + /* Handle class-scope non-template C++17 deduction guides. */ + cp_parser_maybe_adjust_declarator_for_dguide (parser, + &decl_specifiers, + declarator, + &ctor_dtor_or_conv_p); + if (declares_class_or_enum & 2) cp_parser_check_for_definition_in_return_type (declarator, decl_specifiers.type, diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction98.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction98.C new file mode 100644 index 0000000..bee0ce4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction98.C @@ -0,0 +1,10 @@ +// PR c++/79501 +// { dg-do compile { target c++17 } } + +template<class T> +struct A { + template<class U> struct B { template<class V> B(V); }; + B(T) -> B<T>; +}; + +A<int>::B b(0); |