Hi! On the following testcase, there is a type template argument, for which we create a decl (decl == parm in that case) and pushdecl it. But, if the pushdecl detects a redeclaration in that scope, duplicate_decls will ggc_free the decl passed to it and we then add that ggc_freed tree into the template parameter TREE_LIST.
The following patch fixes that by using the result value from pushdecl. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-04-19 Jakub Jelinek <ja...@redhat.com> PR c++/90138 * pt.c (process_template_parm): Set decl to pushdecl result. If !is_non_type, also set parm to that. * g++.dg/template/pr90138.C: New test. --- gcc/cp/pt.c.jj 2019-04-18 12:16:47.000000000 +0200 +++ gcc/cp/pt.c 2019-04-18 14:12:36.765494173 +0200 @@ -4433,7 +4433,9 @@ process_template_parm (tree list, locati process_template_parm could fail. */ tree reqs = finish_shorthand_constraint (parm, constr); - pushdecl (decl); + decl = pushdecl (decl); + if (!is_non_type) + parm = decl; /* Build the parameter node linking the parameter declaration, its default argument (if any), and its constraints (if any). */ --- gcc/testsuite/g++.dg/template/pr90138.C.jj 2019-04-18 14:58:06.035564846 +0200 +++ gcc/testsuite/g++.dg/template/pr90138.C 2019-04-18 14:57:27.056206214 +0200 @@ -0,0 +1,5 @@ +// PR c++/90138 + +template <, typename T, typename typename, typename T> // { dg-error "expected" } +struct S; // { dg-error "no default" } +// { dg-error "two or more" "" { target *-*-* } .-2 } Jakub