Commit c095a4f8 by Douglas Gregor Committed by Doug Gregor

re PR c++/33964 (internal compiler error: in dependent_type_p, at cp/pt.c:15319 (vararg templates))

2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>

       PR c++/33964
       * pt.c (process_partial_specialization): Don't mark template
       parameters that occur in non-deduced contexts.
       (struct pair_fn_data): Add include_nondeduced_p.
       (for_each_template_parm_r): Only visit non-deduced contexts if
       include_nondeduced_p is set.
       (for_each_template_parm): Added parameter include_nondeduced_p,
       which states whether template parameters found in non-deduced
       contexts should be visited.
       (uses_template_parms): Visit all template parameters, even those
       in non-deduced contexts.

2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>

       PR c++/33964
       * g++.dg/cpp0x/vt-33964.C: New.
       * g++.dg/template/partial5.C: New.

From-SVN: r131544
parent 85d85234
2008-01-15 Douglas Gregor <doug.gregor@gmail.com> 2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/33964
* pt.c (process_partial_specialization): Don't mark template
parameters that occur in non-deduced contexts.
(struct pair_fn_data): Add include_nondeduced_p.
(for_each_template_parm_r): Only visit non-deduced contexts if
include_nondeduced_p is set.
(for_each_template_parm): Added parameter include_nondeduced_p,
which states whether template parameters found in non-deduced
contexts should be visited.
(uses_template_parms): Visit all template parameters, even those
in non-deduced contexts.
2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/34052 PR c++/34052
* pt.c (check_default_tmpl_args): Check for parameter packs that * pt.c (check_default_tmpl_args): Check for parameter packs that
aren't at the end of a primary template. aren't at the end of a primary template.
......
...@@ -125,7 +125,7 @@ static tree convert_nontype_argument (tree, tree); ...@@ -125,7 +125,7 @@ static tree convert_nontype_argument (tree, tree);
static tree convert_template_argument (tree, tree, tree, static tree convert_template_argument (tree, tree, tree,
tsubst_flags_t, int, tree); tsubst_flags_t, int, tree);
static int for_each_template_parm (tree, tree_fn_t, void*, static int for_each_template_parm (tree, tree_fn_t, void*,
struct pointer_set_t*); struct pointer_set_t*, bool);
static tree expand_template_argument_pack (tree); static tree expand_template_argument_pack (tree);
static tree build_template_parm_index (int, int, int, tree, tree); static tree build_template_parm_index (int, int, int, tree, tree);
static bool inline_needs_template_parms (tree); static bool inline_needs_template_parms (tree);
...@@ -3378,7 +3378,8 @@ process_partial_specialization (tree decl) ...@@ -3378,7 +3378,8 @@ process_partial_specialization (tree decl)
for_each_template_parm (TREE_VEC_ELT (inner_args, i), for_each_template_parm (TREE_VEC_ELT (inner_args, i),
&mark_template_parm, &mark_template_parm,
&tpd, &tpd,
NULL); NULL,
/*include_nondeduced_p=*/false);
} }
for (i = 0; i < ntparms; ++i) for (i = 0; i < ntparms; ++i)
if (tpd.parms[i] == 0) if (tpd.parms[i] == 0)
...@@ -3501,7 +3502,8 @@ process_partial_specialization (tree decl) ...@@ -3501,7 +3502,8 @@ process_partial_specialization (tree decl)
for_each_template_parm (type, for_each_template_parm (type,
&mark_template_parm, &mark_template_parm,
&tpd2, &tpd2,
NULL); NULL,
/*include_nondeduced_p=*/false);
if (tpd2.arg_uses_template_parms [i]) if (tpd2.arg_uses_template_parms [i])
{ {
...@@ -5929,6 +5931,9 @@ struct pair_fn_data ...@@ -5929,6 +5931,9 @@ struct pair_fn_data
{ {
tree_fn_t fn; tree_fn_t fn;
void *data; void *data;
/* True when we should also visit template parameters that occur in
non-deduced contexts. */
bool include_nondeduced_p;
struct pointer_set_t *visited; struct pointer_set_t *visited;
}; };
...@@ -5943,7 +5948,9 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) ...@@ -5943,7 +5948,9 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
void *data = pfd->data; void *data = pfd->data;
if (TYPE_P (t) if (TYPE_P (t)
&& for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited)) && (pfd->include_nondeduced_p || TREE_CODE (t) != TYPENAME_TYPE)
&& for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited,
pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
switch (TREE_CODE (t)) switch (TREE_CODE (t))
...@@ -5958,15 +5965,18 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) ...@@ -5958,15 +5965,18 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
if (!TYPE_TEMPLATE_INFO (t)) if (!TYPE_TEMPLATE_INFO (t))
*walk_subtrees = 0; *walk_subtrees = 0;
else if (for_each_template_parm (TREE_VALUE (TYPE_TEMPLATE_INFO (t)), else if (for_each_template_parm (TREE_VALUE (TYPE_TEMPLATE_INFO (t)),
fn, data, pfd->visited)) fn, data, pfd->visited,
pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
break; break;
case INTEGER_TYPE: case INTEGER_TYPE:
if (for_each_template_parm (TYPE_MIN_VALUE (t), if (for_each_template_parm (TYPE_MIN_VALUE (t),
fn, data, pfd->visited) fn, data, pfd->visited,
pfd->include_nondeduced_p)
|| for_each_template_parm (TYPE_MAX_VALUE (t), || for_each_template_parm (TYPE_MAX_VALUE (t),
fn, data, pfd->visited)) fn, data, pfd->visited,
pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
break; break;
...@@ -5974,13 +5984,14 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) ...@@ -5974,13 +5984,14 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
/* Since we're not going to walk subtrees, we have to do this /* Since we're not going to walk subtrees, we have to do this
explicitly here. */ explicitly here. */
if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data, if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data,
pfd->visited)) pfd->visited, pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
/* Fall through. */ /* Fall through. */
case FUNCTION_TYPE: case FUNCTION_TYPE:
/* Check the return type. */ /* Check the return type. */
if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited)) if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
/* Check the parameter types. Since default arguments are not /* Check the parameter types. Since default arguments are not
...@@ -5994,7 +6005,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) ...@@ -5994,7 +6005,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm)) for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm))
if (for_each_template_parm (TREE_VALUE (parm), fn, data, if (for_each_template_parm (TREE_VALUE (parm), fn, data,
pfd->visited)) pfd->visited, pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
/* Since we've already handled the TYPE_ARG_TYPES, we don't /* Since we've already handled the TYPE_ARG_TYPES, we don't
...@@ -6004,8 +6015,10 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) ...@@ -6004,8 +6015,10 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
break; break;
case TYPEOF_TYPE: case TYPEOF_TYPE:
if (for_each_template_parm (TYPE_FIELDS (t), fn, data, if (pfd->include_nondeduced_p
pfd->visited)) && for_each_template_parm (TYPE_FIELDS (t), fn, data,
pfd->visited,
pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
break; break;
...@@ -6013,7 +6026,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) ...@@ -6013,7 +6026,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
case VAR_DECL: case VAR_DECL:
if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t) if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
&& for_each_template_parm (DECL_TI_ARGS (t), fn, data, && for_each_template_parm (DECL_TI_ARGS (t), fn, data,
pfd->visited)) pfd->visited, pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
/* Fall through. */ /* Fall through. */
...@@ -6021,17 +6034,19 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) ...@@ -6021,17 +6034,19 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
case CONST_DECL: case CONST_DECL:
if (TREE_CODE (t) == CONST_DECL && DECL_TEMPLATE_PARM_P (t) if (TREE_CODE (t) == CONST_DECL && DECL_TEMPLATE_PARM_P (t)
&& for_each_template_parm (DECL_INITIAL (t), fn, data, && for_each_template_parm (DECL_INITIAL (t), fn, data,
pfd->visited)) pfd->visited, pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
if (DECL_CONTEXT (t) if (DECL_CONTEXT (t)
&& pfd->include_nondeduced_p
&& for_each_template_parm (DECL_CONTEXT (t), fn, data, && for_each_template_parm (DECL_CONTEXT (t), fn, data,
pfd->visited)) pfd->visited, pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
break; break;
case BOUND_TEMPLATE_TEMPLATE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM:
/* Record template parameters such as `T' inside `TT<T>'. */ /* Record template parameters such as `T' inside `TT<T>'. */
if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited)) if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited,
pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
/* Fall through. */ /* Fall through. */
...@@ -6047,7 +6062,8 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) ...@@ -6047,7 +6062,8 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
case TEMPLATE_DECL: case TEMPLATE_DECL:
/* A template template parameter is encountered. */ /* A template template parameter is encountered. */
if (DECL_TEMPLATE_TEMPLATE_PARM_P (t) if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
&& for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited)) && for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
/* Already substituted template template parameter */ /* Already substituted template template parameter */
...@@ -6057,15 +6073,17 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) ...@@ -6057,15 +6073,17 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
case TYPENAME_TYPE: case TYPENAME_TYPE:
if (!fn if (!fn
|| for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn, || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn,
data, pfd->visited)) data, pfd->visited,
pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
break; break;
case CONSTRUCTOR: case CONSTRUCTOR:
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)) if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))
&& pfd->include_nondeduced_p
&& for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE && for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE
(TREE_TYPE (t)), fn, data, (TREE_TYPE (t)), fn, data,
pfd->visited)) pfd->visited, pfd->include_nondeduced_p))
return error_mark_node; return error_mark_node;
break; break;
...@@ -6106,11 +6124,16 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) ...@@ -6106,11 +6124,16 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
for_each_template_parm returns 1. Otherwise, the iteration for_each_template_parm returns 1. Otherwise, the iteration
continues. If FN never returns a nonzero value, the value continues. If FN never returns a nonzero value, the value
returned by for_each_template_parm is 0. If FN is NULL, it is returned by for_each_template_parm is 0. If FN is NULL, it is
considered to be the function which always returns 1. */ considered to be the function which always returns 1.
If INCLUDE_NONDEDUCED_P, then this routine will also visit template
parameters that occur in non-deduced contexts. When false, only
visits those template parameters that can be deduced. */
static int static int
for_each_template_parm (tree t, tree_fn_t fn, void* data, for_each_template_parm (tree t, tree_fn_t fn, void* data,
struct pointer_set_t *visited) struct pointer_set_t *visited,
bool include_nondeduced_p)
{ {
struct pair_fn_data pfd; struct pair_fn_data pfd;
int result; int result;
...@@ -6118,6 +6141,7 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data, ...@@ -6118,6 +6141,7 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data,
/* Set up. */ /* Set up. */
pfd.fn = fn; pfd.fn = fn;
pfd.data = data; pfd.data = data;
pfd.include_nondeduced_p = include_nondeduced_p;
/* Walk the tree. (Conceptually, we would like to walk without /* Walk the tree. (Conceptually, we would like to walk without
duplicates, but for_each_template_parm_r recursively calls duplicates, but for_each_template_parm_r recursively calls
...@@ -6189,7 +6213,8 @@ uses_template_parms (tree t) ...@@ -6189,7 +6213,8 @@ uses_template_parms (tree t)
int int
uses_template_parms_level (tree t, int level) uses_template_parms_level (tree t, int level)
{ {
return for_each_template_parm (t, template_parm_this_level_p, &level, NULL); return for_each_template_parm (t, template_parm_this_level_p, &level, NULL,
/*include_nondeduced_p=*/true);
} }
static int tinst_depth; static int tinst_depth;
......
2008-01-15 Douglas Gregor <doug.gregor@gmail.com> 2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/33964
* g++.dg/cpp0x/vt-33964.C: New.
* g++.dg/template/partial5.C: New.
2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/34052 PR c++/34052
* g++.dg/cpp0x/vt-34052.C: New. * g++.dg/cpp0x/vt-34052.C: New.
* g++.dg/template/ttp26.C: New. * g++.dg/template/ttp26.C: New.
// { dg-options "-std=c++0x" }
template<typename ... Args>
struct foo
{
static bool const value = true;
};
template<typename ... Args>
struct foo< typename Args::is_applied... > // { dg-error "not used|Args" }
{
static bool const value = false;
};
struct not_applied { typedef void is_applied; };
struct applied { typedef applied is_applied; };
int main()
{
foo<applied, applied> i;
}
// PR c++/33964
template<typename T>
struct X { };
template<typename T>
struct X<typename T::foo> { }; // { dg-error "not used|T" }
template<int N>
struct X<int[N]> {}; // okay
template<typename T, typename T::foo V>
struct Y { };
template<typename T, typename U, U v>
struct Y<T, v> { }; // { dg-error "not used|U" }
template<typename T, T V>
struct Z { };
template<typename T>
struct Z<T, (T)0> { }; // { dg-error "involves template parameter" }
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