c++: Adjust push_template_decl_real
authorNathan Sidwell <nathan@acm.org>
Thu, 14 May 2020 14:13:54 +0000 (07:13 -0700)
committerNathan Sidwell <nathan@acm.org>
Thu, 14 May 2020 14:18:04 +0000 (07:18 -0700)
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.

gcc/cp/ChangeLog
gcc/cp/pt.c

index 45b60de120b194f13b244858326603728c64a84d..9bc3e8d7c8139b7412912e53ec48761e97c754b6 100644 (file)
@@ -1,5 +1,8 @@
 2020-05-14  Nathan Sidwell  <nathan@acm.org>
 
+       * 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 ...
index 837644f8e6cb3bd37596a9a6f1cea09513f9ab75..68d113bab901377b028223c190abdf632fcf6368 100644 (file)
@@ -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)
     {