PR c++/71738 - nested template friend
authorJason Merrill <jason@redhat.com>
Sun, 24 Jul 2016 02:39:41 +0000 (22:39 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 24 Jul 2016 02:39:41 +0000 (22:39 -0400)
* pt.c (lookup_template_class_1): Handle getting template from tsubst.

From-SVN: r238685

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

index e1e4506690e1179c70b161998a5d623cc1d101ec..c9a28aed253428ee0806d7c4afe6eedc91c1607f 100644 (file)
@@ -1,5 +1,8 @@
 2016-07-23  Jason Merrill  <jason@redhat.com>
 
+       PR c++/71738
+       * pt.c (lookup_template_class_1): Handle getting template from tsubst.
+
        PR c++/71350
        * decl.c (reshape_init_r): Check complain for missing braces warning.
 
index 3ee53d1b2f06715bc9caee143dfb37fee2bf41b9..a44beadd8afc57032e9589b7e7bd186ce88ffa31 100644 (file)
@@ -8601,7 +8601,9 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
             for parameters in the TYPE_DECL of the alias template
             done earlier.  So be careful while getting the template
             of FOUND.  */
-         found = TREE_CODE (found) == TYPE_DECL
+         found = TREE_CODE (found) == TEMPLATE_DECL
+           ? found
+           : TREE_CODE (found) == TYPE_DECL
            ? TYPE_TI_TEMPLATE (TREE_TYPE (found))
            : CLASSTYPE_TI_TEMPLATE (found);
        }
diff --git a/gcc/testsuite/g++.dg/template/friend63.C b/gcc/testsuite/g++.dg/template/friend63.C
new file mode 100644 (file)
index 0000000..f3a292c
--- /dev/null
@@ -0,0 +1,29 @@
+// PR c++/71738
+
+template < class > struct S
+{
+  template < class > struct A
+  { 
+    template < class > struct B
+    {
+      template <class Z>
+      void operator=(Z) { S::i = 0; }
+    };
+  };
+
+  // Note that this friend declaration is useless, since nested classes are
+  // already friends of their enclosing class.
+  template < class X >
+  template < class Y >
+  template < class Z >
+  friend void A < X >::B < Y >::operator= (Z);
+
+private:
+  static int i;
+};
+
+int main()
+{
+  S<int>::A<int>::B<int> b;
+  b = 0;
+}