aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2001-06-08 12:49:02 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2001-06-08 12:49:02 +0000
commit9ac1bd2e0ab404e3aa6f8e562f2f1f39f1fcb8de (patch)
treeab5762d3ebc19185880f76a0eb320ec43e23d764 /gcc
parent9c65bbf460d325bf794a610e16ae941f723e3fef (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/friend.c35
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/friend49.C26
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;
+ };
+};