On 1/26/22 12:49, Patrick Palka wrote:
In the nested_name_specifier branch within cp_parser_class_head, we need
to update TYPE with the result of maybe_process_partial_specialization
just like we do in the template_id_p branch.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

OK.

        PR c++/92944

gcc/cp/ChangeLog:

        * parser.cc (cp_parser_class_head): Update TYPE with the result
        of maybe_process_partial_specialization in the
        nested_name_specifier branch too.  Refactor nearby code to
        accomodate that maybe_process_partial_specialization returns a
        _TYPE, not a TYPE_DECL, and eliminate local variable CLASS_TYPE.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp2a/concepts-partial-spec10.C: New test.
---
  gcc/cp/parser.cc                               | 18 +++++++-----------
  .../g++.dg/cpp2a/concepts-partial-spec10.C     |  6 ++++++
  2 files changed, 13 insertions(+), 11 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec10.C

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index ed219d79dc9..aa1768ffab1 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -26534,7 +26534,7 @@ cp_parser_class_head (cp_parser* parser,
      }
    else if (nested_name_specifier)
      {
-      tree class_type;
+      type = TREE_TYPE (type);
/* Given: @@ -26544,31 +26544,27 @@ cp_parser_class_head (cp_parser* parser,
         we will get a TYPENAME_TYPE when processing the definition of
         `S::T'.  We need to resolve it to the actual type before we
         try to define it.  */
-      if (TREE_CODE (TREE_TYPE (type)) == TYPENAME_TYPE)
+      if (TREE_CODE (type) == TYPENAME_TYPE)
        {
-         class_type = resolve_typename_type (TREE_TYPE (type),
-                                             /*only_current_p=*/false);
-         if (TREE_CODE (class_type) != TYPENAME_TYPE)
-           type = TYPE_NAME (class_type);
-         else
+         type = resolve_typename_type (type, /*only_current_p=*/false);
+         if (TREE_CODE (type) == TYPENAME_TYPE)
            {
              cp_parser_error (parser, "could not resolve typename type");
              type = error_mark_node;
            }
        }
- if (maybe_process_partial_specialization (TREE_TYPE (type))
-         == error_mark_node)
+      type = maybe_process_partial_specialization (type);
+      if (type == error_mark_node)
        {
          type = NULL_TREE;
          goto done;
        }
- class_type = current_class_type;
        /* Enter the scope indicated by the nested-name-specifier.  */
        pushed_scope = push_scope (nested_name_specifier);
        /* Get the canonical version of this type.  */
-      type = TYPE_MAIN_DECL (TREE_TYPE (type));
+      type = TYPE_MAIN_DECL (type);
        /* Call push_template_decl if it seems like we should be defining a
         template either from the template headers or the type we're
         defining, so that we diagnose both extra and missing headers.  */
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec10.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec10.C
new file mode 100644
index 00000000000..8504a055ac5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec10.C
@@ -0,0 +1,6 @@
+// PR c++/92944
+// { dg-do compile { target c++20 } }
+
+namespace ns { template<class T> struct A { }; }
+template<class T> requires true struct ns::A<T> { };
+template<class T> requires false struct ns::A<T> { };

Reply via email to