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
This commit is contained in:
Nathan Sidwell 2001-06-08 12:49:02 +00:00 committed by Nathan Sidwell
parent 9c65bbf460
commit 9ac1bd2e0a
4 changed files with 60 additions and 11 deletions

View File

@ -1,3 +1,9 @@
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>

View File

@ -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)
{

View File

@ -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.

View File

@ -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;
};
};