https://gcc.gnu.org/g:1c555ba67a34ced2460a065eac05ae2e2693ca4d

commit r16-6248-g1c555ba67a34ced2460a065eac05ae2e2693ca4d
Author: Jakub Jelinek <[email protected]>
Date:   Thu Dec 18 16:41:10 2025 +0100

    c++: Fix up recent cp_parser_template_id regression [PR123186]
    
    On Fri, Dec 12, 2025 at 09:39:18AM -0500, Patrick Palka wrote:
    > +      TREE_TYPE (templ)
    > +     = build_typename_type (TYPE_CONTEXT (TREE_TYPE (templ)),
    > +                            TYPE_NAME (TREE_TYPE (templ)),
    > +                            fullname,
    > +                            get_typename_type_tag (TREE_TYPE (templ)));
    >        template_id = templ;
    >      }
    >    else
    
    This change causes ICE e.g. on the following testcase.
    
    The problem is that build_typename_type expects IDENTIFIER_NODE as the
    second argument, e.g. it uses it as
          tree d = build_decl (input_location, TYPE_DECL, name, t);
    argument.  But TYPE_NAME doesn't have to be an IDENTIFIER_NODE, it can
    be a TYPE_DECL too and when we build a TYPE_DECL with TYPE_DECL as
    DECL_NAME, it breaks all kinds of assumptions everywhere in the FE as well
    as middle-end.
    
    Fixed by using TYPE_IDENTIFIER instead.
    
    2025-12-18  Jakub Jelinek  <[email protected]>
    
            PR c++/123186
            * parser.cc (cp_parser_template_id): Use TYPE_IDENTIFIER instead of
            TYPE_NAME in second build_typename_type argument.
    
            * g++.dg/template/crash133.C: New test.

Diff:
---
 gcc/cp/parser.cc                         | 2 +-
 gcc/testsuite/g++.dg/template/crash133.C | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 18df3b1014e9..521c05549f1e 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -20435,7 +20435,7 @@ cp_parser_template_id (cp_parser *parser,
                                   fullname, arguments);
       TREE_TYPE (templ)
        = build_typename_type (TYPE_CONTEXT (TREE_TYPE (templ)),
-                              TYPE_NAME (TREE_TYPE (templ)),
+                              TYPE_IDENTIFIER (TREE_TYPE (templ)),
                               fullname,
                               get_typename_tag (TREE_TYPE (templ)));
       template_id = templ;
diff --git a/gcc/testsuite/g++.dg/template/crash133.C 
b/gcc/testsuite/g++.dg/template/crash133.C
new file mode 100644
index 000000000000..9a1a6b136c64
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash133.C
@@ -0,0 +1,6 @@
+// PR c++/123186
+
+template <class T>
+struct A : T {
+  typename A <T>::template B <42> C;
+};

Reply via email to