friend.c (add_friend): Deal gracefully with error_mark_node.
authorMark Mitchell <mark@codesourcery.com>
Sun, 11 Apr 1999 18:48:27 +0000 (18:48 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sun, 11 Apr 1999 18:48:27 +0000 (18:48 +0000)
* 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

gcc/cp/ChangeLog
gcc/cp/friend.c
gcc/cp/method.c
gcc/testsuite/g++.old-deja/g++.pt/crash37.C [new file with mode: 0644]

index 8d04a2d911c76a394243b0330d41957169cd1e2c..be8c8653ad9e7fbb8b416b96176523d9359cd145 100644 (file)
@@ -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>
index 285432f5ccd64d9694359f03952bc620509e5e7d..48b566a943a0d7d542a581c9089cbe80f5a91dc6 100644 (file)
@@ -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)
index d0bbf1546f68f69cf024ec34209f10ed5108fcb7..82d216822d040d5adf7737499500f1a452203dd3 100644 (file)
@@ -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 (file)
index 0000000..c2325bf
--- /dev/null
@@ -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);
+}
+