From a81a4baae497e0a6fd13fee7609810bc5fbd6362 Mon Sep 17 00:00:00 2001 From: nathan Date: Fri, 8 Jun 2001 12:49:02 +0000 Subject: [PATCH] cp: PR c++/2929 * friend.c (do_friend): Use push_decl_namespace for classes at namespace scope. testsuite: * g++.old-deja/g++.pt/friend49.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@43013 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 +++++ gcc/cp/friend.c | 35 +++++++++++++++++++--------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.old-deja/g++.pt/friend49.C | 26 +++++++++++++++++++++ 4 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/friend49.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1fa95c8aad5..5b03f596b62 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,4 +1,10 @@ 2001-06-08 Nathan Sidwell + + PR c++/2929 + * friend.c (do_friend): Use push_decl_namespace for classes at + namespace scope. + +2001-06-08 Nathan Sidwell Jason Merrill PR c++/3061 diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index 913ed9ccd0b..8b2e8f8a4c7 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -388,18 +388,31 @@ do_friend (ctype, declarator, decl, parmdecls, attrlist, && current_template_parms && uses_template_parms (decl)); - /* We can call pushdecl here, because the TREE_CHAIN of this - FUNCTION_DECL is not needed for other purposes. Don't do - this for a template instantiation. However, we don't - call pushdecl() for a friend function of a template - class, since in general, such a declaration depends on - template parameters. Instead, we call pushdecl when the - class is instantiated. */ - if (!is_friend_template - && template_class_depth (current_class_type) == 0) - decl = pushdecl (decl); - else + if (is_friend_template + || template_class_depth (current_class_type) != 0) + /* We can't call pushdecl for a template class, since in + general, such a declaration depends on template + parameters. Instead, we call pushdecl when the class + is instantiated. */ decl = push_template_decl_real (decl, /*is_friend=*/1); + else if (current_function_decl) + /* This must be a local class, so pushdecl will be ok, and + insert an unqualified friend into the local scope + (rather than the containing namespace scope, which the + next choice will do). */ + decl = pushdecl (decl); + else + { + /* We can't use pushdecl, as we might be in a template + class specialization, and pushdecl will insert an + unqualified friend decl into the template parameter + scope, rather than the namespace containing it. */ + tree ns = decl_namespace_context (decl); + + push_nested_namespace (ns); + decl = pushdecl_namespace_level (decl); + pop_nested_namespace (ns); + } if (warn) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4a775683024..1c83b609247 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2001-06-08 Nathan Sidwell + + * g++.old-deja/g++.pt/friend49.C: New test. + 2001-06-07 Nathan Sidwell * g++.old-deja/g++.ext/anon3.C: New test. diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend49.C b/gcc/testsuite/g++.old-deja/g++.pt/friend49.C new file mode 100644 index 00000000000..3b243f09249 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/friend49.C @@ -0,0 +1,26 @@ +// Build don't link: + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 5 Jun 2001 + +// Bug 2929. We were forgetting about template parm scope when +// injecting a friend decl into a class template specialization's +// containing scope. + +template class Vec; + +template <> class Vec +{ +public: + Vec (); + Vec & Fn (double); + friend Vec Fn (const Vec &, double); +}; // pop_binding ICE + +template class Alloc +{ + template struct Rebind + { + typedef Alloc<_Tp1> other; + }; +}; -- 2.11.0