Tested x86_64-pc-linux-gnu, applying to trunk. -- 8< --
get_template_info was crashing because it assumed that any decl with DECL_LANG_SPECIFIC could use DECL_TEMPLATE_INFO. It's more complicated than that. PR c++/113498 gcc/cp/ChangeLog: * pt.cc (decl_template_info): New fn. (get_template_info): Use it. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-using4.C: New test. --- gcc/cp/pt.cc | 30 ++++++++++++++++++-- gcc/testsuite/g++.dg/cpp2a/concepts-using4.C | 24 ++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-using4.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index fbbca469219..74013533b0f 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -339,6 +339,32 @@ build_template_info (tree template_decl, tree template_args) return result; } +/* DECL_TEMPLATE_INFO, if applicable, or NULL_TREE. */ + +static tree +decl_template_info (const_tree decl) +{ + /* This needs to match template_info_decl_check. */ + if (DECL_LANG_SPECIFIC (decl)) + switch (TREE_CODE (decl)) + { + case FUNCTION_DECL: + if (DECL_THUNK_P (decl)) + break; + gcc_fallthrough (); + case VAR_DECL: + case FIELD_DECL: + case TYPE_DECL: + case CONCEPT_DECL: + case TEMPLATE_DECL: + return DECL_TEMPLATE_INFO (decl); + + default: + break; + } + return NULL_TREE; +} + /* Return the template info node corresponding to T, whatever T is. */ tree @@ -353,8 +379,8 @@ get_template_info (const_tree t) || TREE_CODE (t) == PARM_DECL) return NULL; - if (DECL_P (t) && DECL_LANG_SPECIFIC (t)) - tinfo = DECL_TEMPLATE_INFO (t); + if (DECL_P (t)) + tinfo = decl_template_info (t); if (!tinfo && DECL_IMPLICIT_TYPEDEF_P (t)) t = TREE_TYPE (t); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-using4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-using4.C new file mode 100644 index 00000000000..a39a7c0a8a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-using4.C @@ -0,0 +1,24 @@ +// PR c++/113498 +// { dg-do compile { target c++20 } } + +template<int d> +struct S_Base +{ + static constexpr int D = d; +}; + +template<int d> +struct S : public S_Base<d> +{ + using S_Base<d>::D; + constexpr void f() const + requires(D > 0) {} + +}; + +int main(int, char**) +{ + S<1> s; + s.f(); + return 0; +} base-commit: 631a922e5c8578a1c878b69f1651d482b661ef4a -- 2.39.3