From: Nathan Sidwell Date: Thu, 14 May 2020 14:13:54 +0000 (-0700) Subject: c++: Adjust push_template_decl_real X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5adbd0907563f494b602b9f38283d29c7b029bdf;p=gcc.git c++: Adjust push_template_decl_real Push_template_decl_real's friend-pushing logic was confusing me. This is more understandable. Fix a latent type bug I disovered. * pt.c (push_template_decl_real): Adjust friend pushing logic. Reinit template type. --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 45b60de120b..9bc3e8d7c81 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2020-05-14 Nathan Sidwell + * pt.c (push_template_decl_real): Adjust friend pushing logic. + Reinit template type. + * pt.c (build_template_decl): Init DECL_TEMPLATE_RESULT & TREE_TYPE here ... (process_partial_specialization): ... not here ... diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 837644f8e6c..68d113bab90 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5979,24 +5979,32 @@ push_template_decl_real (tree decl, bool is_friend) gcc_checking_assert (DECL_TEMPLATE_RESULT (tmpl) == decl); - /* Push template declarations for global functions and types. Note - that we do not try to push a global template friend declared in a - template class; such a thing may well depend on the template - parameters of the class. */ - if (new_template_p && !ctx - && !(is_friend && template_class_depth (current_class_type) > 0)) - { - tmpl = pushdecl_namespace_level (tmpl, is_friend); - if (tmpl == error_mark_node) - return error_mark_node; - /* Hide template friend classes that haven't been declared yet. */ - if (is_friend && TREE_CODE (decl) == TYPE_DECL) + if (new_template_p) + { + /* Push template declarations for global functions and types. + Note that we do not try to push a global template friend + declared in a template class; such a thing may well depend on + the template parameters of the class and we'll push it when + instantiating the befriending class. */ + if (!ctx + && !(is_friend && template_class_depth (current_class_type) > 0)) { - DECL_ANTICIPATED (tmpl) = 1; - DECL_FRIEND_P (tmpl) = 1; + tmpl = pushdecl_namespace_level (tmpl, is_friend); + if (tmpl == error_mark_node) + return error_mark_node; + + /* Hide template friend classes that haven't been declared yet. */ + if (is_friend && TREE_CODE (decl) == TYPE_DECL) + { + DECL_ANTICIPATED (tmpl) = 1; + DECL_FRIEND_P (tmpl) = 1; + } } } + else + /* The type may have been completed, or (erroneously) changed. */ + TREE_TYPE (tmpl) = TREE_TYPE (decl); if (is_primary) {