aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2021-08-11 15:59:22 -0400
committerPatrick Palka <ppalka@redhat.com>2021-08-11 15:59:22 -0400
commit7e39d1a15f5276f72ee478a692445569bb646e65 (patch)
treec3c5ef9f887c45f799a65b2f212ab848bcd110e2
parent6186708312780bb2139da01946abdde39667e985 (diff)
downloadgcc-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.c63
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction98.C10
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);