c++: fix injected friend of template class
authorNathan Sidwell <nathan@acm.org>
Tue, 22 Sep 2020 16:00:20 +0000 (09:00 -0700)
committerNathan Sidwell <nathan@acm.org>
Tue, 22 Sep 2020 16:05:20 +0000 (09:05 -0700)
In working on fixing hiddenness, I discovered some suspicious code in
template instantiation.  I suspect it dates from when we didn't do the
hidden friend injection thing at all.  The xreftag finds the same
class, but makes it visible to name lookup.  Which is wrong.
hurrah, fixing a bug by deleting code!

gcc/cp/
* pt.c (instantiate_class_template_1): Do not repush and unhide
injected friend.
gcc/testsuite/
* g++.old-deja/g++.pt/friend34.C: Check injected friend is still
invisible.

gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.pt/friend34.C

index 97d0c245f7e4acbddc85f470aaba909c810c7b1a..44ca14afc4e50a790d51ffd797e541c0b6af0295 100644 (file)
@@ -12030,25 +12030,6 @@ instantiate_class_template_1 (tree type)
                    adjust_processing_template_decl = true;
                  --processing_template_decl;
                }
-             else if (TREE_CODE (friend_type) != BOUND_TEMPLATE_TEMPLATE_PARM
-                      && !CLASSTYPE_USE_TEMPLATE (friend_type)
-                      && TYPE_HIDDEN_P (friend_type))
-               {
-                 /* friend class C;
-
-                    where C hasn't been declared yet.  Let's lookup name
-                    from namespace scope directly, bypassing any name that
-                    come from dependent base class.  */
-                 tree ns = decl_namespace_context (TYPE_MAIN_DECL (friend_type));
-
-                 /* The call to xref_tag_from_type does injection for friend
-                    classes.  */
-                 push_nested_namespace (ns);
-                 friend_type =
-                   xref_tag_from_type (friend_type, NULL_TREE,
-                                       /*tag_scope=*/ts_current);
-                 pop_nested_namespace (ns);
-               }
              else if (uses_template_parms (friend_type))
                /* friend class C<T>;  */
                friend_type = tsubst (friend_type, args,
index 5e80ab98b2ec4dc71ccbf9bc0384e4864ad9f3a0..dcd6df0ce553b3f129c2f2fc2cecc5bb1d555696 100644 (file)
@@ -6,9 +6,12 @@
 template <typename T = void>
 class bar {
 public:
-  friend class foo; // this is not bar::foo, it forward-declares ::foo
+  friend class foo; // this is not bar::foo, it injects hidden ::foo
   class foo {};
   bar() { foo(); } // but this should refer to bar::foo
 };
 
 bar<> baz;
+
+// We still have not made foo visible.
+foo *b;  // { dg-error "does not name a type" }