diff options
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/pt.c | 35 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/friend5.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/qual1.C | 21 |
6 files changed, 70 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 67c67b8..f7ac920 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2002-04-23 Mark Mitchell <mark@codesourcery.com> + + 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 <neil@daikokuya.demon.co.uk> * cp-lang.c (LANG_HOOKS_FUNCTION_INIT, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index aa198a6..39c6bf6 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 <class T> - struct S { - template <class U> - 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<int>, `S' is bound to a TYPE_DECL - for `S<int>', 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 <class T> + struct S { + template <class U> + friend struct S; + }; + + Here, in the scope of (say) S<int>, `S' is bound to a TYPE_DECL + for `S<int>', 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 a928135..690df76 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 ca26c2f..3c4635a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2002-04-23 Mark Mitchell <mark@codesourcery.com> + + PR c++/6256: + * g++.dg/template/friend5.C: New test. + + PR c++/6331: + * g++.dg/template/qual1.C: Likewise. + 2002-04-22 Zack Weinberg <zack@codesourcery.com> * 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 0000000..1a63e71 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend5.C @@ -0,0 +1,9 @@ +// { dg-do compile } + +namespace NS { template <typename number> class C; } + +template <typename T> class X { + template <typename N> friend class NS::C; +}; + +template class X<int>; diff --git a/gcc/testsuite/g++.dg/template/qual1.C b/gcc/testsuite/g++.dg/template/qual1.C new file mode 100644 index 0000000..3d512c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qual1.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +template<class T> +class Link_array +{ +public: + void sort (int (*compare) (T *const&,T *const&)); +}; + +int shift_compare (int *const &, int *const &) {}; + +template<class T> void +Link_array<T>::sort (int (*compare) (T *const&,T *const&)) +{ +} + +void f () +{ + Link_array<int> clashes; + clashes.sort (shift_compare); +} |