diff options
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/friend.c | 12 | ||||
-rw-r--r-- | gcc/cp/method.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/crash37.C | 22 |
4 files changed, 51 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8d04a2d911c..be8c8653ad9 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 285432f5ccd..48b566a943a 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 d0bbf1546f6..82d216822d0 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 00000000000..c2325bffa8a --- /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); +} + |