re PR c++/59956 (internal compiler error: unexpected expression ‘P_S’ of kind template_parm_index)
PR c++/59956 * friend.c (do_friend): Pass the TEMPLATE_DECL to add_friend if we have a friend template in a class template. * pt.c (tsubst_friend_function): Look through it. (push_template_decl_real): A friend member template is primary. From-SVN: r207281
This commit is contained in:
parent
d530142ddb
commit
7651c65685
4 changed files with 45 additions and 4 deletions
|
@ -1,3 +1,12 @@
|
|||
2014-01-29 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/59956
|
||||
* friend.c (do_friend): Pass the TEMPLATE_DECL to add_friend if we
|
||||
have a friend template in a class template.
|
||||
* pt.c (tsubst_friend_function): Look through it.
|
||||
(push_template_decl_real): A friend member template is
|
||||
primary.
|
||||
|
||||
2014-01-29 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/58846
|
||||
|
|
|
@ -501,7 +501,13 @@ do_friend (tree ctype, tree declarator, tree decl,
|
|||
? current_template_parms
|
||||
: NULL_TREE);
|
||||
|
||||
if (template_member_p && decl && TREE_CODE (decl) == FUNCTION_DECL)
|
||||
if ((template_member_p
|
||||
/* Always pull out the TEMPLATE_DECL if we have a friend
|
||||
template in a class template so that it gets tsubsted
|
||||
properly later on (59956). tsubst_friend_function knows
|
||||
how to tell this apart from a member template. */
|
||||
|| (class_template_depth && friend_depth))
|
||||
&& decl && TREE_CODE (decl) == FUNCTION_DECL)
|
||||
decl = DECL_TI_TEMPLATE (decl);
|
||||
|
||||
if (decl)
|
||||
|
|
14
gcc/cp/pt.c
14
gcc/cp/pt.c
|
@ -4615,7 +4615,8 @@ push_template_decl_real (tree decl, bool is_friend)
|
|||
DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
|
||||
|
||||
/* See if this is a primary template. */
|
||||
if (is_friend && ctx)
|
||||
if (is_friend && ctx
|
||||
&& uses_template_parms_level (ctx, processing_template_decl))
|
||||
/* A friend template that specifies a class context, i.e.
|
||||
template <typename T> friend void A<T>::f();
|
||||
is not primary. */
|
||||
|
@ -8424,10 +8425,17 @@ tsubst_friend_function (tree decl, tree args)
|
|||
|
||||
if (COMPLETE_TYPE_P (context))
|
||||
{
|
||||
tree fn = new_friend;
|
||||
/* do_friend adds the TEMPLATE_DECL for any member friend
|
||||
template even if it isn't a member template, i.e.
|
||||
template <class T> friend A<T>::f();
|
||||
Look through it in that case. */
|
||||
if (TREE_CODE (fn) == TEMPLATE_DECL
|
||||
&& !PRIMARY_TEMPLATE_P (fn))
|
||||
fn = DECL_TEMPLATE_RESULT (fn);
|
||||
/* Check to see that the declaration is really present, and,
|
||||
possibly obtain an improved declaration. */
|
||||
tree fn = check_classfn (context,
|
||||
new_friend, NULL_TREE);
|
||||
fn = check_classfn (context, fn, NULL_TREE);
|
||||
|
||||
if (fn)
|
||||
new_friend = fn;
|
||||
|
|
18
gcc/testsuite/g++.dg/template/friend55.C
Normal file
18
gcc/testsuite/g++.dg/template/friend55.C
Normal file
|
@ -0,0 +1,18 @@
|
|||
// PR c++/59956
|
||||
|
||||
template <int I> struct A;
|
||||
template <int I> class B {
|
||||
int i;
|
||||
template <int A_S> friend void A<A_S>::impl();
|
||||
};
|
||||
|
||||
B<0> b1;
|
||||
template<int I>struct A { void impl(); };
|
||||
B<1> b2;
|
||||
|
||||
template<int I> void A<I>::impl() { ++b1.i; ++b2.i; }
|
||||
|
||||
int main()
|
||||
{
|
||||
A<0>().impl();
|
||||
}
|
Loading…
Add table
Reference in a new issue