diff options
author | Jason Merrill <jason@redhat.com> | 2016-07-23 22:39:41 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-07-23 22:39:41 -0400 |
commit | 6970223f93ce9102cd95044f7c4d10a4ce695a77 (patch) | |
tree | 3ea5701e3e23d7cc56ebf0bf6e4f7c2fbae9a16c | |
parent | a6c690f41e0e50ce67dd3d3e791ff9f266842748 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/pt.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/friend63.C | 29 |
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; +} |