diff options
| author | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-06-08 12:49:02 +0000 |
|---|---|---|
| committer | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-06-08 12:49:02 +0000 |
| commit | a81a4baae497e0a6fd13fee7609810bc5fbd6362 (patch) | |
| tree | ab5762d3ebc19185880f76a0eb320ec43e23d764 /gcc | |
| parent | 1b2c7cbd9c155ca6aad748effd506f3fbea43b39 (diff) | |
| download | ppe42-gcc-a81a4baae497e0a6fd13fee7609810bc5fbd6362.tar.gz ppe42-gcc-a81a4baae497e0a6fd13fee7609810bc5fbd6362.zip | |
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
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
| -rw-r--r-- | gcc/cp/friend.c | 35 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
| -rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/friend49.C | 26 |
4 files changed, 60 insertions, 11 deletions
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 <nathan@codesourcery.com> + + PR c++/2929 + * friend.c (do_friend): Use push_decl_namespace for classes at + namespace scope. + +2001-06-08 Nathan Sidwell <nathan@codesourcery.com> Jason Merrill <jason_merrill@redhat.com> 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 <nathan@codesourcery.com> + + * g++.old-deja/g++.pt/friend49.C: New test. + 2001-06-07 Nathan Sidwell <nathan@codesourcery.com> * 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 <nathan@codesourcery.com> + +// Bug 2929. We were forgetting about template parm scope when +// injecting a friend decl into a class template specialization's +// containing scope. + +template <class Type> class Vec; + +template <> class Vec<double> +{ +public: + Vec (); + Vec<double> & Fn (double); + friend Vec<double> Fn (const Vec<double> &, double); +}; // pop_binding ICE + +template <class _Tp> class Alloc +{ + template <class _Tp1> struct Rebind + { + typedef Alloc<_Tp1> other; + }; +}; |

