Commit ef3b7b17 by Jason Merrill

re PR c++/30897 (ICE with default argument in template template parameter)

        PR c++/30897
        * pt.c (push_template_decl_real): Set DECL_CONTEXT on template
        template parms.
        (lookup_template_class): Use it to get the outer template args
        for instantiating one.

        PR c++/29236
        * pt.c (reduce_template_parm_level): tsubst the parameters
        of a template template parm.

From-SVN: r129844
parent e1a18c68
2007-11-01 Jason Merrill <jason@redhat.com>
PR c++/30897
* pt.c (push_template_decl_real): Set DECL_CONTEXT on template
template parms.
(lookup_template_class): Use it to get the outer template args
for instantiating one.
PR c++/29236
* pt.c (reduce_template_parm_level): tsubst the parameters
of a template template parm.
2007-11-01 Douglas Gregor <doug.gregor@gmail.com> 2007-11-01 Douglas Gregor <doug.gregor@gmail.com>
PR c++/33955 PR c++/33955
...@@ -33,7 +45,7 @@ ...@@ -33,7 +45,7 @@
Mark Mitchell <mark@codesourcery.com> Mark Mitchell <mark@codesourcery.com>
PR c++/19531 PR c++/19531
* cp/typeck.c (check_return_expr): Don't set named_return_value_okay_p * typeck.c (check_return_expr): Don't set named_return_value_okay_p
if retval is volatile. if retval is volatile.
2007-10-30 Jakub Jelinek <jakub@redhat.com> 2007-10-30 Jakub Jelinek <jakub@redhat.com>
......
...@@ -132,7 +132,7 @@ static bool inline_needs_template_parms (tree); ...@@ -132,7 +132,7 @@ static bool inline_needs_template_parms (tree);
static void push_inline_template_parms_recursive (tree, int); static void push_inline_template_parms_recursive (tree, int);
static tree retrieve_local_specialization (tree); static tree retrieve_local_specialization (tree);
static void register_local_specialization (tree, tree); static void register_local_specialization (tree, tree);
static tree reduce_template_parm_level (tree, tree, int); static tree reduce_template_parm_level (tree, tree, int, tree, tsubst_flags_t);
static int mark_template_parm (tree, void *); static int mark_template_parm (tree, void *);
static int template_parm_this_level_p (tree, void *); static int template_parm_this_level_p (tree, void *);
static tree tsubst_friend_function (tree, tree); static tree tsubst_friend_function (tree, tree);
...@@ -2878,7 +2878,8 @@ canonical_type_parameter (tree type) ...@@ -2878,7 +2878,8 @@ canonical_type_parameter (tree type)
new one is created. */ new one is created. */
static tree static tree
reduce_template_parm_level (tree index, tree type, int levels) reduce_template_parm_level (tree index, tree type, int levels, tree args,
tsubst_flags_t complain)
{ {
if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
|| (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index)) || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))
...@@ -2903,9 +2904,10 @@ reduce_template_parm_level (tree index, tree type, int levels) ...@@ -2903,9 +2904,10 @@ reduce_template_parm_level (tree index, tree type, int levels)
= TEMPLATE_PARM_PARAMETER_PACK (index); = TEMPLATE_PARM_PARAMETER_PACK (index);
/* Template template parameters need this. */ /* Template template parameters need this. */
if (TREE_CODE (decl) != CONST_DECL) if (TREE_CODE (decl) == TEMPLATE_DECL)
DECL_TEMPLATE_PARMS (decl) DECL_TEMPLATE_PARMS (decl) = tsubst_template_parms
= DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)); (DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)),
args, complain);
} }
return TEMPLATE_PARM_DESCENDANTS (index); return TEMPLATE_PARM_DESCENDANTS (index);
...@@ -4000,10 +4002,13 @@ template arguments to %qD do not match original template %qD", ...@@ -4000,10 +4002,13 @@ template arguments to %qD do not match original template %qD",
if (primary) if (primary)
{ {
tree parms = DECL_TEMPLATE_PARMS (tmpl);
int i;
DECL_PRIMARY_TEMPLATE (tmpl) = tmpl; DECL_PRIMARY_TEMPLATE (tmpl) = tmpl;
if (DECL_CONV_FN_P (tmpl)) if (DECL_CONV_FN_P (tmpl))
{ {
int depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)); int depth = TMPL_PARMS_DEPTH (parms);
/* It is a conversion operator. See if the type converted to /* It is a conversion operator. See if the type converted to
depends on innermost template operands. */ depends on innermost template operands. */
...@@ -4012,6 +4017,16 @@ template arguments to %qD do not match original template %qD", ...@@ -4012,6 +4017,16 @@ template arguments to %qD do not match original template %qD",
depth)) depth))
DECL_TEMPLATE_CONV_FN_P (tmpl) = 1; DECL_TEMPLATE_CONV_FN_P (tmpl) = 1;
} }
/* Give template template parms a DECL_CONTEXT of the template
for which they are a parameter. */
parms = INNERMOST_TEMPLATE_PARMS (parms);
for (i = TREE_VEC_LENGTH (parms) - 1; i >= 0; --i)
{
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
if (TREE_CODE (parm) == TEMPLATE_DECL)
DECL_CONTEXT (parm) = tmpl;
}
} }
/* The DECL_TI_ARGS of DECL contains full set of arguments referring /* The DECL_TI_ARGS of DECL contains full set of arguments referring
...@@ -5392,6 +5407,7 @@ lookup_template_class (tree d1, ...@@ -5392,6 +5407,7 @@ lookup_template_class (tree d1,
tree parm; tree parm;
tree arglist2; tree arglist2;
tree outer;
parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template); parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
...@@ -5404,15 +5420,23 @@ lookup_template_class (tree d1, ...@@ -5404,15 +5420,23 @@ lookup_template_class (tree d1,
instantiation `TT<int>' is seen, we need to build the full instantiation `TT<int>' is seen, we need to build the full
arguments containing {int} as the innermost level. Outer levels, arguments containing {int} as the innermost level. Outer levels,
available when not appearing as default template argument, can be available when not appearing as default template argument, can be
obtained from `current_template_args ()'. obtained from the arguments of the enclosing template.
Suppose that TT is later substituted with std::vector. The above Suppose that TT is later substituted with std::vector. The above
instantiation is `TT<int, std::allocator<T> >' with TT at instantiation is `TT<int, std::allocator<T> >' with TT at
level 1, and T at level 2, while the template arguments at level 1 level 1, and T at level 2, while the template arguments at level 1
becomes {std::vector} and the inner level 2 is {int}. */ becomes {std::vector} and the inner level 2 is {int}. */
if (current_template_parms) outer = DECL_CONTEXT (template);
arglist = add_to_template_args (current_template_args (), arglist); if (outer)
outer = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (outer)));
else if (current_template_parms)
/* This is an argument of the current template, so we haven't set
DECL_CONTEXT yet. */
outer = current_template_args ();
if (outer)
arglist = add_to_template_args (outer, arglist);
arglist2 = coerce_template_parms (parmlist, arglist, template, arglist2 = coerce_template_parms (parmlist, arglist, template,
complain, complain,
...@@ -8829,7 +8853,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -8829,7 +8853,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
r = copy_type (t); r = copy_type (t);
TEMPLATE_TYPE_PARM_INDEX (r) TEMPLATE_TYPE_PARM_INDEX (r)
= reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t), = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
r, levels); r, levels, args, complain);
TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r); TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
TYPE_MAIN_VARIANT (r) = r; TYPE_MAIN_VARIANT (r) = r;
TYPE_POINTER_TO (r) = NULL_TREE; TYPE_POINTER_TO (r) = NULL_TREE;
...@@ -8863,7 +8887,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -8863,7 +8887,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
break; break;
case TEMPLATE_PARM_INDEX: case TEMPLATE_PARM_INDEX:
r = reduce_template_parm_level (t, type, levels); r = reduce_template_parm_level (t, type, levels, args, complain);
break; break;
default: default:
......
// PR c++/29236
template <typename T> struct A {};
template <template <typename> class P>
struct B {
template <template <typename> class Q>
friend bool foo (const B<Q>& a);
};
template <template <typename> class Q>
bool foo (const B<Q>& a);
void bar () {
B<A> a;
foo (a);
}
// PR c++/30897
template<template <typename T, typename = T > class U> struct A
{
template<int> U<int> foo();
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment