aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-07-23 22:39:41 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-07-23 22:39:41 -0400
commit6970223f93ce9102cd95044f7c4d10a4ce695a77 (patch)
tree3ea5701e3e23d7cc56ebf0bf6e4f7c2fbae9a16c /gcc
parenta6c690f41e0e50ce67dd3d3e791ff9f266842748 (diff)
downloadgcc-6970223f93ce9102cd95044f7c4d10a4ce695a77.zip
gcc-6970223f93ce9102cd95044f7c4d10a4ce695a77.tar.gz
gcc-6970223f93ce9102cd95044f7c4d10a4ce695a77.tar.bz2
PR c++/71738 - nested template friend
* pt.c (lookup_template_class_1): Handle getting template from tsubst. From-SVN: r238685
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/testsuite/g++.dg/template/friend63.C29
3 files changed, 35 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e1e4506..c9a28ae 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3ee53d1..a44bead 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
index 0000000..f3a292c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend63.C
@@ -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;
+}