From 77adef8498fb09947e889abbacb1d2bd8ece0929 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 23 Apr 2002 08:37:23 +0000 Subject: [PATCH] re PR c++/6256 (Seg fault for template friends in namespaces, regression from 2.95) PR c++/6256: * pt.c (tsubst_friend_class): Handle templates with explicit nested names. PR c++/6331: * typeck.c (merge_types): Remember the cv-qualification of pointer types when merging them. PR c++/6256: * g++.dg/template/friend5.C: New test. PR c++/6331: * g++.dg/template/qual1.C: Likewise. From-SVN: r52661 --- gcc/cp/ChangeLog | 10 +++++++ gcc/cp/pt.c | 35 ++++++++++++++----------- gcc/cp/typeck.c | 2 ++ gcc/testsuite/ChangeLog | 8 ++++++ gcc/testsuite/g++.dg/template/friend5.C | 9 +++++++ gcc/testsuite/g++.dg/template/qual1.C | 21 +++++++++++++++ 6 files changed, 70 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/friend5.C create mode 100644 gcc/testsuite/g++.dg/template/qual1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 67c67b8682e..f7ac920401b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2002-04-23 Mark Mitchell + + PR c++/6256: + * pt.c (tsubst_friend_class): Handle templates with explicit + nested names. + + PR c++/6331: + * typeck.c (merge_types): Remember the cv-qualification of pointer + types when merging them. + 2002-04-20 Neil Booth * cp-lang.c (LANG_HOOKS_FUNCTION_INIT, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index aa198a68fbe..39c6bf695b3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4833,23 +4833,28 @@ tsubst_friend_class (friend_tmpl, args) tree tmpl; /* First, we look for a class template. */ - tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0); - - /* But, if we don't find one, it might be because we're in a - situation like this: + if (DECL_CONTEXT (friend_tmpl)) + tmpl = friend_tmpl; + else + { + tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0); - template - struct S { - template - friend struct S; - }; + /* But, if we don't find one, it might be because we're in a + situation like this: - Here, in the scope of (say) S, `S' is bound to a TYPE_DECL - for `S', not the TEMPLATE_DECL. */ - if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) - { - tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1); - tmpl = maybe_get_template_decl_from_type_decl (tmpl); + template + struct S { + template + friend struct S; + }; + + Here, in the scope of (say) S, `S' is bound to a TYPE_DECL + for `S', not the TEMPLATE_DECL. */ + if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) + { + tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1); + tmpl = maybe_get_template_decl_from_type_decl (tmpl); + } } if (tmpl && DECL_CLASS_TEMPLATE_P (tmpl)) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index a92813528a3..690df764bf5 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -592,12 +592,14 @@ merge_types (t1, t2) /* For two pointers, do this recursively on the target type. */ { tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2)); + int quals = cp_type_quals (t1); if (code1 == POINTER_TYPE) t1 = build_pointer_type (target); else t1 = build_reference_type (target); t1 = build_type_attribute_variant (t1, attributes); + t1 = cp_build_qualified_type (t1, quals); if (TREE_CODE (target) == METHOD_TYPE) t1 = build_ptrmemfunc_type (t1); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ca26c2f1d60..3c4635a06af 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2002-04-23 Mark Mitchell + + PR c++/6256: + * g++.dg/template/friend5.C: New test. + + PR c++/6331: + * g++.dg/template/qual1.C: Likewise. + 2002-04-22 Zack Weinberg * gcc.c-torture/execute/980707-1.c: Don't use isspace(). diff --git a/gcc/testsuite/g++.dg/template/friend5.C b/gcc/testsuite/g++.dg/template/friend5.C new file mode 100644 index 00000000000..1a63e71e32c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend5.C @@ -0,0 +1,9 @@ +// { dg-do compile } + +namespace NS { template class C; } + +template class X { + template friend class NS::C; +}; + +template class X; diff --git a/gcc/testsuite/g++.dg/template/qual1.C b/gcc/testsuite/g++.dg/template/qual1.C new file mode 100644 index 00000000000..3d512c1e1be --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qual1.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +template +class Link_array +{ +public: + void sort (int (*compare) (T *const&,T *const&)); +}; + +int shift_compare (int *const &, int *const &) {}; + +template void +Link_array::sort (int (*compare) (T *const&,T *const&)) +{ +} + +void f () +{ + Link_array clashes; + clashes.sort (shift_compare); +} -- 2.30.2