c++: fix injected friend of template class

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.
This commit is contained in:
Nathan Sidwell 2020-09-22 09:00:20 -07:00
parent 160061ac10
commit 7dfffe3241
2 changed files with 4 additions and 20 deletions

View 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,

View 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" }