OSDN Git Service

PR c++/6256:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Apr 2002 08:37:23 +0000 (08:37 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Apr 2002 08:37:23 +0000 (08:37 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52661 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/friend5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/qual1.C [new file with mode: 0644]

index 67c67b8..f7ac920 100644 (file)
@@ -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,
index aa198a6..39c6bf6 100644 (file)
@@ -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))
index a928135..690df76 100644 (file)
@@ -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);
index ca26c2f..3c4635a 100644 (file)
@@ -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 (file)
index 0000000..1a63e71
--- /dev/null
@@ -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 (file)
index 0000000..3d512c1
--- /dev/null
@@ -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);
+}