diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2001-06-08 12:49:02 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2001-06-08 12:49:02 +0000 |
commit | 9ac1bd2e0ab404e3aa6f8e562f2f1f39f1fcb8de (patch) | |
tree | ab5762d3ebc19185880f76a0eb320ec43e23d764 /gcc | |
parent | 9c65bbf460d325bf794a610e16ae941f723e3fef (diff) | |
download | gcc-9ac1bd2e0ab404e3aa6f8e562f2f1f39f1fcb8de.zip gcc-9ac1bd2e0ab404e3aa6f8e562f2f1f39f1fcb8de.tar.gz gcc-9ac1bd2e0ab404e3aa6f8e562f2f1f39f1fcb8de.tar.bz2 |
re PR c++/2929 (gcc crash when compiling a sample)
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.
From-SVN: r43013
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 1fa95c8..5b03f59 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 913ed9c..8b2e8f8 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 4a77568..1c83b60 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 0000000..3b243f0 --- /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; + }; +}; |