aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-04-11 18:48:27 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-04-11 18:48:27 +0000
commit82bed8708b5683a8b4de4ad4bc0f2eb31a2dbda9 (patch)
treee40a5a4230b6f1a24d2e45c91caac2b7cf27e931 /gcc
parent391cdef0565eab9385be36eab55be03d4fe46a6b (diff)
downloadgcc-82bed8708b5683a8b4de4ad4bc0f2eb31a2dbda9.zip
gcc-82bed8708b5683a8b4de4ad4bc0f2eb31a2dbda9.tar.gz
gcc-82bed8708b5683a8b4de4ad4bc0f2eb31a2dbda9.tar.bz2
friend.c (add_friend): Deal gracefully with error_mark_node.
* friend.c (add_friend): Deal gracefully with error_mark_node. * method.c (build_overload_value): Handle pointers-to-members as template parameters. From-SVN: r26351
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/friend.c12
-rw-r--r--gcc/cp/method.c16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash37.C22
4 files changed, 51 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8d04a2d..be8c865 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
1999-04-11 Mark Mitchell <mark@codesourcery.com>
+ * friend.c (add_friend): Deal gracefully with error_mark_node.
+ * method.c (build_overload_value): Handle pointers-to-members as
+ template parameters.
+
* decl.c (push_binding): Fix typo in comment.
1999-04-10 Mark Mitchell <mark@codesourcery.com>
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index 285432f..48b566a 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -141,10 +141,16 @@ void
add_friend (type, decl)
tree type, decl;
{
- tree typedecl = TYPE_MAIN_DECL (type);
- tree list = DECL_FRIENDLIST (typedecl);
- tree name = DECL_NAME (decl);
+ tree typedecl;
+ tree list;
+ tree name;
+
+ if (decl == error_mark_node)
+ return;
+ typedecl = TYPE_MAIN_DECL (type);
+ list = DECL_FRIENDLIST (typedecl);
+ name = DECL_NAME (decl);
type = TREE_TYPE (typedecl);
while (list)
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index d0bbf15..82d2168 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -858,6 +858,22 @@ build_overload_value (type, value, in_template)
tree delta2;
my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 0);
+
+ /* We'll get a ADDR_EXPR of a SCOPE_REF here if we're
+ mangling, an instantiation of something like:
+
+ template <class T, void (T::*fp)()> class C {};
+ template <class T> C<T, &T::f> x();
+
+ We mangle the return type of the function, and that
+ contains template parameters. */
+ if (TREE_CODE (value) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (value, 0)) == SCOPE_REF)
+ {
+ build_overload_scope_ref (TREE_OPERAND (value, 0));
+ break;
+ }
+
my_friendly_assert (TREE_CODE (value) == PTRMEM_CST, 0);
expand_ptrmemfunc_cst (value, &delta, &idx, &pfn, &delta2);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash37.C b/gcc/testsuite/g++.old-deja/g++.pt/crash37.C
new file mode 100644
index 0000000..c2325bf
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash37.C
@@ -0,0 +1,22 @@
+// Build don't link:
+// Origin: Jens Maurer <jmaurer@menuett.rhein-main.de>
+
+template<class T, void (T::*f)(int)>
+class C { };
+
+template<class T>
+C<T, &T::output> call(T& obj)
+{ return C<T, &T::output>();
+}
+
+class Test {
+public:
+ void output(int);
+};
+
+void sub()
+{
+ Test t;
+ call(t);
+}
+