re PR c++/50852 (ICE: internal compiler error: in tsubst, at cp/pt.c:11030)

PR c++/50852
	PR c++/53039
	* tree.c (strip_typedefs_expr): New.
	* cp-tree.h: Declare it.
	* pt.c (convert_template_argument, unify): Use it.
	* parser.c (cp_parser_template_declaration_after_export): Don't call
	fixup_template_parms.

	* cp-tree.h (TEMPLATE_PARM_NUM_SIBLINGS): Remove.
	(struct template_parm_index_s): Remove num_siblings.
	* pt.c (fixup_template_parms, fixup_template_parm_index): Remove.
	(fixup_template_type_parm_type): Remove.
	(build_template_parm_index): Remove num_siblings parm.
	(process_template_parm): Likewise.
	* parser.c (cp_parser_template_parameter_list): Adjust.
	* tree.c (cp_tree_equal): Don't compare num_siblings.
	* typeck.c (comp_template_parms_position): Likewise.

	* pt.c (arg_from_parm_pack_p): Go back to using same_type_p or
	cp_tree_equal.

From-SVN: r193955
This commit is contained in:
Jason Merrill 2012-11-29 15:16:46 -05:00 committed by Jason Merrill
parent 0c0d9de605
commit 1c44f40a48
11 changed files with 315 additions and 362 deletions

View File

@ -1,3 +1,27 @@
2012-11-29 Jason Merrill <jason@redhat.com>
PR c++/53039
* pt.c (arg_from_parm_pack_p): Go back to using same_type_p or
cp_tree_equal.
* cp-tree.h (TEMPLATE_PARM_NUM_SIBLINGS): Remove.
(struct template_parm_index_s): Remove num_siblings.
* pt.c (fixup_template_parms, fixup_template_parm_index): Remove.
(fixup_template_type_parm_type): Remove.
(build_template_parm_index): Remove num_siblings parm.
(process_template_parm): Likewise.
* parser.c (cp_parser_template_parameter_list): Adjust.
* tree.c (cp_tree_equal): Don't compare num_siblings.
* typeck.c (comp_template_parms_position): Likewise.
PR c++/50852
PR c++/53039
* tree.c (strip_typedefs_expr): New.
* cp-tree.h: Declare it.
* pt.c (convert_template_argument, unify): Use it.
* parser.c (cp_parser_template_declaration_after_export): Don't call
fixup_template_parms.
2012-11-29 Kai Tietz <ktietz@redhat.com>
PR target/53912

View File

@ -248,7 +248,6 @@ struct GTY(()) template_parm_index_s {
int index;
int level;
int orig_level;
int num_siblings;
tree decl;
};
typedef struct template_parm_index_s template_parm_index;
@ -4515,9 +4514,6 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
((template_parm_index*)TEMPLATE_PARM_INDEX_CHECK (NODE))
#define TEMPLATE_PARM_IDX(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->index)
#define TEMPLATE_PARM_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->level)
/* The Number of sibling parms this template parm has. */
#define TEMPLATE_PARM_NUM_SIBLINGS(NODE) \
(TEMPLATE_PARM_INDEX_CAST (NODE)->num_siblings)
#define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (NODE))
#define TEMPLATE_PARM_ORIG_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->orig_level)
#define TEMPLATE_PARM_DECL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->decl)
@ -5288,9 +5284,8 @@ extern void append_type_to_template_for_access_check (tree, tree, tree,
extern tree splice_late_return_type (tree, tree);
extern bool is_auto (const_tree);
extern tree process_template_parm (tree, location_t, tree,
bool, bool, unsigned);
bool, bool);
extern tree end_template_parm_list (tree);
void fixup_template_parms (void);
extern void end_template_decl (void);
extern tree maybe_update_decl_type (tree, tree);
extern bool check_default_tmpl_args (tree, tree, int, int, int);
@ -5663,6 +5658,7 @@ extern bool type_has_nontrivial_copy_init (const_tree);
extern bool class_tmpl_impl_spec_p (const_tree);
extern int zero_init_p (const_tree);
extern tree strip_typedefs (tree);
extern tree strip_typedefs_expr (tree);
extern tree copy_binfo (tree, tree, tree,
tree *, int);
extern int member_p (const_tree);

View File

@ -11967,8 +11967,7 @@ cp_parser_template_parameter_list (cp_parser* parser)
parm_loc,
parameter,
is_non_type,
is_parameter_pack,
0);
is_parameter_pack);
else
{
tree err_parm = build_tree_list (parameter, parameter);
@ -21134,7 +21133,6 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
{
/* Parse the template parameters. */
parameter_list = cp_parser_template_parameter_list (parser);
fixup_template_parms ();
}
/* Get the deferred access checks from the parameter list. These

View File

@ -148,7 +148,7 @@ static tree convert_template_argument (tree, tree, tree,
static int for_each_template_parm (tree, tree_fn_t, void*,
struct pointer_set_t*, bool);
static tree expand_template_argument_pack (tree);
static tree build_template_parm_index (int, int, int, int, tree, tree);
static tree build_template_parm_index (int, int, int, tree, tree);
static bool inline_needs_template_parms (tree);
static void push_inline_template_parms_recursive (tree, int);
static tree retrieve_local_specialization (tree);
@ -205,8 +205,6 @@ static tree listify_autos (tree, tree);
static tree template_parm_to_arg (tree t);
static bool arg_from_parm_pack_p (tree, tree);
static tree current_template_args (void);
static tree fixup_template_type_parm_type (tree, int);
static tree fixup_template_parm_index (tree, tree, int);
static tree tsubst_template_parm (tree, tree, tsubst_flags_t);
/* Make the current scope suitable for access checking when we are
@ -3430,14 +3428,12 @@ check_template_shadow (tree decl)
}
/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
ORIG_LEVEL, DECL, and TYPE. NUM_SIBLINGS is the total number of
template parameters. */
ORIG_LEVEL, DECL, and TYPE. */
static tree
build_template_parm_index (int index,
int level,
int orig_level,
int num_siblings,
tree decl,
tree type)
{
@ -3445,7 +3441,6 @@ build_template_parm_index (int index,
TEMPLATE_PARM_IDX (t) = index;
TEMPLATE_PARM_LEVEL (t) = level;
TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level;
TEMPLATE_PARM_NUM_SIBLINGS (t) = num_siblings;
TEMPLATE_PARM_DECL (t) = decl;
TREE_TYPE (t) = type;
TREE_CONSTANT (t) = TREE_CONSTANT (decl);
@ -3511,7 +3506,6 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args,
t = build_template_parm_index (TEMPLATE_PARM_IDX (index),
TEMPLATE_PARM_LEVEL (index) - levels,
TEMPLATE_PARM_ORIG_LEVEL (index),
TEMPLATE_PARM_NUM_SIBLINGS (index),
decl, type);
TEMPLATE_PARM_DESCENDANTS (index) = t;
TEMPLATE_PARM_PARAMETER_PACK (t)
@ -3539,8 +3533,7 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args,
tree
process_template_parm (tree list, location_t parm_loc, tree parm,
bool is_non_type, bool is_parameter_pack,
unsigned num_template_parms)
bool is_non_type, bool is_parameter_pack)
{
tree decl = 0;
tree defval;
@ -3615,7 +3608,6 @@ process_template_parm (tree list, location_t parm_loc, tree parm,
DECL_INITIAL (parm) = DECL_INITIAL (decl)
= build_template_parm_index (idx, processing_template_decl,
processing_template_decl,
num_template_parms,
decl, TREE_TYPE (parm));
TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))
@ -3649,7 +3641,6 @@ process_template_parm (tree list, location_t parm_loc, tree parm,
TEMPLATE_TYPE_PARM_INDEX (t)
= build_template_parm_index (idx, processing_template_decl,
processing_template_decl,
num_template_parms,
decl, TREE_TYPE (parm));
TEMPLATE_TYPE_PARAMETER_PACK (t) = is_parameter_pack;
TYPE_CANONICAL (t) = canonical_type_parameter (t);
@ -3689,305 +3680,6 @@ end_template_parm_list (tree parms)
return saved_parmlist;
}
/* Create a new type almost identical to TYPE but which has the
following differences:
1/ T has a new TEMPLATE_PARM_INDEX that carries the new number of
template sibling parameters of T.
2/ T has a new canonical type that matches the new number
of sibling parms.
3/ From now on, T is going to be what lookups referring to the
name of TYPE will return. No lookup should return TYPE anymore.
NUM_PARMS is the new number of sibling parms TYPE belongs to.
This is a subroutine of fixup_template_parms. */
static tree
fixup_template_type_parm_type (tree type, int num_parms)
{
tree orig_idx = TEMPLATE_TYPE_PARM_INDEX (type), idx;
tree t;
/* This is the decl which name is inserted into the symbol table for
the template parm type. So whenever we lookup the type name, this
is the DECL we get. */
tree decl;
/* Do not fix up the type twice. */
if (orig_idx && TEMPLATE_PARM_NUM_SIBLINGS (orig_idx) != 0)
return type;
t = copy_type (type);
decl = TYPE_NAME (t);
TYPE_MAIN_VARIANT (t) = t;
TYPE_NEXT_VARIANT (t)= NULL_TREE;
TYPE_POINTER_TO (t) = 0;
TYPE_REFERENCE_TO (t) = 0;
idx = build_template_parm_index (TEMPLATE_PARM_IDX (orig_idx),
TEMPLATE_PARM_LEVEL (orig_idx),
TEMPLATE_PARM_ORIG_LEVEL (orig_idx),
num_parms,
decl, t);
TEMPLATE_PARM_DESCENDANTS (idx) = TEMPLATE_PARM_DESCENDANTS (orig_idx);
TEMPLATE_PARM_PARAMETER_PACK (idx) = TEMPLATE_PARM_PARAMETER_PACK (orig_idx);
TEMPLATE_TYPE_PARM_INDEX (t) = idx;
TYPE_STUB_DECL (t) = decl;
TEMPLATE_TYPE_DECL (t) = decl;
if (TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
TREE_TYPE (DECL_TEMPLATE_RESULT (decl)) = t;
/* Update the type associated to the type name stored in the symbol
table. Now, whenever the type name is looked up, the resulting
type is properly fixed up. */
TREE_TYPE (decl) = t;
TYPE_CANONICAL (t) = canonical_type_parameter (t);
return t;
}
/* Create and return a new TEMPLATE_PARM_INDEX that is almost
identical to I, but that is fixed up as to:
1/ carry the number of sibling parms (NUM_PARMS) of the template
parm represented by I.
2/ replace all references to template parm types declared before I
(in the same template parm list as I) by references to template
parm types contained in ARGS. ARGS should contain the list of
template parms that have been fixed up so far, in a form suitable
to be passed to tsubst.
This is a subroutine of fixup_template_parms. */
static tree
fixup_template_parm_index (tree i, tree args, int num_parms)
{
tree index, decl, type;
if (i == NULL_TREE
|| TREE_CODE (i) != TEMPLATE_PARM_INDEX
/* Do not fix up the index twice. */
|| (TEMPLATE_PARM_NUM_SIBLINGS (i) != 0))
return i;
decl = TEMPLATE_PARM_DECL (i);
type = TREE_TYPE (decl);
index = build_template_parm_index (TEMPLATE_PARM_IDX (i),
TEMPLATE_PARM_LEVEL (i),
TEMPLATE_PARM_ORIG_LEVEL (i),
num_parms,
decl, type);
TEMPLATE_PARM_DESCENDANTS (index) = TEMPLATE_PARM_DESCENDANTS (i);
TEMPLATE_PARM_PARAMETER_PACK (index) = TEMPLATE_PARM_PARAMETER_PACK (i);
type = tsubst (type, args, tf_none, NULL_TREE);
TREE_TYPE (decl) = type;
TREE_TYPE (index) = type;
return index;
}
/*
This is a subroutine of fixup_template_parms.
It computes the canonical type of the type of the template
parameter PARM_DESC and update all references to that type so that
they use the newly computed canonical type. No access check is
performed during the fixup. PARM_DESC is a TREE_LIST which
TREE_VALUE is the template parameter and its TREE_PURPOSE is the
default argument of the template parm if any. IDX is the index of
the template parameter, starting at 0. NUM_PARMS is the number of
template parameters in the set PARM_DESC belongs to. ARGLIST is a
TREE_VEC containing the full set of template parameters in a form
suitable to be passed to substs functions as their ARGS
argument. This is what current_template_args returns for a given
template. The innermost vector of args in ARGLIST is the set of
template parms that have been fixed up so far. This function adds
the fixed up parameter into that vector. */
static void
fixup_template_parm (tree parm_desc,
int idx,
int num_parms,
tree arglist)
{
tree parm = TREE_VALUE (parm_desc);
tree fixedup_args = INNERMOST_TEMPLATE_ARGS (arglist);
push_deferring_access_checks (dk_no_check);
if (TREE_CODE (parm) == TYPE_DECL)
{
/* PARM is a template type parameter. Fix up its type, add
the fixed-up template parm to the vector of fixed-up
template parms so far, and substitute the fixed-up
template parms into the default argument of this
parameter. */
tree t =
fixup_template_type_parm_type (TREE_TYPE (parm), num_parms);
TREE_TYPE (parm) = t;
TREE_VEC_ELT (fixedup_args, idx) = template_parm_to_arg (parm_desc);
}
else if (TREE_CODE (parm) == TEMPLATE_DECL)
{
/* PARM is a template template parameter. This is going to
be interesting. */
tree tparms, targs, innermost_args, t;
int j;
/* First, fix up the parms of the template template parm
because the parms are involved in defining the new canonical
type of the template template parm. */
/* So we need to substitute the template parm types that have
been fixed up so far into the template parms of this template
template parm. E.g, consider this:
template<class T, template<T u> class TT> class S;
In this case we want to substitute T into the
template parameters of TT.
So let's walk the template parms of PARM here, and
tsubst ARGLIST into into each of the template
parms. */
/* For this substitution we need to build the full set of
template parameters and use that as arguments for the
tsubsting function. */
tparms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (parm));
/* This will contain the innermost parms of PARM into which
we have substituted so far. */
innermost_args = make_tree_vec (TREE_VEC_LENGTH (tparms));
targs = add_to_template_args (arglist, innermost_args);
for (j = 0; j < TREE_VEC_LENGTH (tparms); ++j)
{
tree parameter;
parameter = TREE_VEC_ELT (tparms, j);
/* INNERMOST_ARGS needs to have at least the same number
of elements as the index PARAMETER, ortherwise
tsubsting into PARAMETER will result in partially
instantiating it, reducing its tempate parm
level. Let's tactically fill INNERMOST_ARGS for that
purpose. */
TREE_VEC_ELT (innermost_args, j) =
template_parm_to_arg (parameter);
fixup_template_parm (parameter, j,
TREE_VEC_LENGTH (tparms),
targs);
}
/* Now fix up the type of the template template parm. */
t = fixup_template_type_parm_type (TREE_TYPE (parm), num_parms);
TREE_TYPE (parm) = t;
TREE_VEC_ELT (fixedup_args, idx) =
template_parm_to_arg (parm_desc);
}
else if (TREE_CODE (parm) == PARM_DECL)
{
/* PARM is a non-type template parameter. We need to:
* Fix up its TEMPLATE_PARM_INDEX to make it carry the
proper number of sibling parameters.
* Make lookups of the template parameter return a reference
to the fixed-up index. No lookup should return references
to the former index anymore.
* Substitute the template parms that got fixed up so far
* into the type of PARM. */
tree index = DECL_INITIAL (parm);
/* PUSHED_DECL is the decl added to the symbol table with
the name of the parameter. E,g:
template<class T, T u> //#0
auto my_function(T t) -> decltype(u); //#1
Here, when looking up u at //#1, we get the decl of u
resulting from the declaration in #0. This is what
PUSHED_DECL is. We need to replace the reference to the
old TEMPLATE_PARM_INDEX carried by PUSHED_DECL by the
fixed-up TEMPLATE_PARM_INDEX. */
tree pushed_decl = TEMPLATE_PARM_DECL (index);
/* Let's fix up the TEMPLATE_PARM_INDEX then. Note that we must
fixup the type of PUSHED_DECL as well and luckily
fixup_template_parm_index does it for us too. */
tree fixed_up_index =
fixup_template_parm_index (index, arglist, num_parms);
DECL_INITIAL (pushed_decl) = DECL_INITIAL (parm) = fixed_up_index;
/* Add this fixed up PARM to the template parms we've fixed
up so far and use that to substitute the fixed-up
template parms into the type of PARM. */
TREE_VEC_ELT (fixedup_args, idx) =
template_parm_to_arg (parm_desc);
TREE_TYPE (parm) = tsubst (TREE_TYPE (parm), arglist,
tf_none, NULL_TREE);
}
TREE_PURPOSE (parm_desc) =
tsubst_template_arg (TREE_PURPOSE (parm_desc),
arglist, tf_none, parm);
pop_deferring_access_checks ();
}
/* Walk the current template parms and properly compute the canonical
types of the dependent types created during
cp_parser_template_parameter_list. */
void
fixup_template_parms (void)
{
tree arglist;
tree parameter_vec;
tree fixedup_args;
int i, num_parms;
parameter_vec = INNERMOST_TEMPLATE_PARMS (current_template_parms);
if (parameter_vec == NULL_TREE)
return;
num_parms = TREE_VEC_LENGTH (parameter_vec);
/* This vector contains the current innermost template parms that
have been fixed up so far. The form of FIXEDUP_ARGS is suitable
to be passed to tsubst* functions as their ARGS argument. */
fixedup_args = make_tree_vec (num_parms);
/* This vector contains the full set of template parms in a form
suitable to be passed to substs functions as their ARGS
argument. */
arglist = current_template_args ();
arglist = add_outermost_template_args (arglist, fixedup_args);
/* Let's do the proper fixup now. */
for (i = 0; i < num_parms; ++i)
fixup_template_parm (TREE_VEC_ELT (parameter_vec, i),
i, num_parms, arglist);
}
/* end_template_decl is called after a template declaration is seen. */
void
@ -4091,34 +3783,13 @@ arg_from_parm_pack_p (tree arg_pack, tree parm_pack)
{
tree expansion = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg_pack), 0);
tree pattern = PACK_EXPANSION_PATTERN (expansion);
/* So we have an argument_pack<P...>. We want to test if P
is actually PARM_PACK. We will not use cp_tree_equal to
test P and PARM_PACK because during type fixup (by
fixup_template_parm) P can be a pre-fixup version of a
type and PARM_PACK be its post-fixup version.
cp_tree_equal would consider them as different even
though we would want to consider them compatible for our
precise purpose here.
Thus we are going to consider that P and PARM_PACK are
compatible if they have the same DECL. */
if ((/* If ARG_PACK is a type parameter pack named by the
same DECL as parm_pack ... */
(TYPE_P (pattern)
&& TYPE_P (parm_pack)
&& TYPE_NAME (pattern) == TYPE_NAME (parm_pack))
/* ... or if PARM_PACK is a non-type parameter named by the
same DECL as ARG_PACK. Note that PARM_PACK being a
non-type parameter means it's either a PARM_DECL or a
TEMPLATE_PARM_INDEX. */
|| (TREE_CODE (pattern) == TEMPLATE_PARM_INDEX
&& ((TREE_CODE (parm_pack) == PARM_DECL
&& (TEMPLATE_PARM_DECL (pattern)
== TEMPLATE_PARM_DECL (DECL_INITIAL (parm_pack))))
|| (TREE_CODE (parm_pack) == TEMPLATE_PARM_INDEX
&& (TEMPLATE_PARM_DECL (pattern)
== TEMPLATE_PARM_DECL (parm_pack))))))
&& template_parameter_pack_p (pattern))
if ((TYPE_P (pattern) && same_type_p (pattern, parm_pack))
|| (!TYPE_P (pattern) && cp_tree_equal (parm_pack, pattern)))
/* The argument pack that the parameter maps to is just an
expansion of the parameter itself, such as one would
find in the implicit typedef of a class inside the
class itself. Consider this parameter "unsubstituted",
so that we will maintain the outer pack expansion. */
return true;
}
return false;
@ -6609,7 +6280,7 @@ convert_template_argument (tree parm,
argument specification is valid. */
val = convert_nontype_argument (t, orig_arg, complain);
else
val = orig_arg;
val = strip_typedefs_expr (orig_arg);
if (val == NULL_TREE)
val = error_mark_node;
@ -16592,6 +16263,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
&& !TEMPLATE_PARM_PARAMETER_PACK (parm))
return unify_parameter_pack_mismatch (explain_p, parm, arg);
arg = strip_typedefs_expr (arg);
TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
return unify_success (explain_p);
@ -20325,7 +19997,7 @@ make_auto (void)
TYPE_STUB_DECL (au) = TYPE_NAME (au);
TEMPLATE_TYPE_PARM_INDEX (au) = build_template_parm_index
(0, processing_template_decl + 1, processing_template_decl + 1,
0, TYPE_NAME (au), NULL_TREE);
TYPE_NAME (au), NULL_TREE);
TYPE_CANONICAL (au) = canonical_type_parameter (au);
DECL_ARTIFICIAL (TYPE_NAME (au)) = 1;
SET_DECL_TEMPLATE_PARM_P (TYPE_NAME (au));

View File

@ -1097,7 +1097,7 @@ cv_unqualified (tree type)
* If T is a type that needs structural equality
its TYPE_CANONICAL (T) will be NULL.
* TYPE_CANONICAL (T) desn't carry type attributes
and looses template parameter names. */
and loses template parameter names. */
tree
strip_typedefs (tree t)
@ -1187,6 +1187,16 @@ strip_typedefs (tree t)
TYPENAME_TYPE_FULLNAME (t),
typename_type, tf_none);
break;
case DECLTYPE_TYPE:
result = strip_typedefs_expr (DECLTYPE_TYPE_EXPR (t));
if (result == DECLTYPE_TYPE_EXPR (t))
return t;
else
result = (finish_decltype_type
(result,
DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t),
tf_none));
break;
default:
break;
}
@ -1208,6 +1218,186 @@ strip_typedefs (tree t)
return cp_build_qualified_type (result, cp_type_quals (t));
}
/* Like strip_typedefs above, but works on expressions, so that in
template<class T> struct A
{
typedef T TT;
B<sizeof(TT)> b;
};
sizeof(TT) is replaced by sizeof(T). */
tree
strip_typedefs_expr (tree t)
{
unsigned i,n;
tree r, type, *ops;
enum tree_code code;
if (t == NULL_TREE || t == error_mark_node)
return t;
if (DECL_P (t) || CONSTANT_CLASS_P (t))
return t;
/* Some expressions have type operands, so let's handle types here rather
than check TYPE_P in multiple places below. */
if (TYPE_P (t))
return strip_typedefs (t);
code = TREE_CODE (t);
switch (code)
{
case IDENTIFIER_NODE:
case TEMPLATE_PARM_INDEX:
case OVERLOAD:
case BASELINK:
case ARGUMENT_PACK_SELECT:
return t;
case TRAIT_EXPR:
{
tree type1 = strip_typedefs (TRAIT_EXPR_TYPE1 (t));
tree type2 = strip_typedefs (TRAIT_EXPR_TYPE2 (t));
if (type1 == TRAIT_EXPR_TYPE1 (t)
&& type2 == TRAIT_EXPR_TYPE2 (t))
return t;
r = copy_node (t);
TRAIT_EXPR_TYPE1 (t) = type1;
TRAIT_EXPR_TYPE2 (t) = type2;
return r;
}
case TREE_LIST:
{
VEC(tree,gc) *vec = make_tree_vector ();
bool changed = false;
tree it;
for (it = t; it; it = TREE_CHAIN (it))
{
tree val = strip_typedefs_expr (TREE_VALUE (t));
VEC_safe_push (tree, gc, vec, val);
if (val != TREE_VALUE (t))
changed = true;
gcc_assert (TREE_PURPOSE (it) == NULL_TREE);
}
if (changed)
{
r = NULL_TREE;
FOR_EACH_VEC_ELT_REVERSE (tree, vec, i, it)
r = tree_cons (NULL_TREE, it, r);
}
else
r = t;
release_tree_vector (vec);
return r;
}
case TREE_VEC:
{
bool changed = false;
VEC(tree,gc)* vec = make_tree_vector ();
n = TREE_VEC_LENGTH (t);
VEC_reserve (tree, gc, vec, n);
for (i = 0; i < n; ++i)
{
tree op = strip_typedefs_expr (TREE_VEC_ELT (t, i));
VEC_quick_push (tree, vec, op);
if (op != TREE_VEC_ELT (t, i))
changed = true;
}
if (changed)
{
r = copy_node (t);
for (i = 0; i < n; ++i)
TREE_VEC_ELT (r, i) = VEC_index (tree, vec, i);
}
else
r = t;
release_tree_vector (vec);
return r;
}
case CONSTRUCTOR:
{
bool changed = false;
VEC(constructor_elt,gc) *vec
= VEC_copy (constructor_elt, gc, CONSTRUCTOR_ELTS (t));
n = CONSTRUCTOR_NELTS (t);
type = strip_typedefs (TREE_TYPE (t));
for (i = 0; i < n; ++i)
{
constructor_elt *e = VEC_index (constructor_elt, vec, i);
tree op = strip_typedefs_expr (e->value);
if (op != e->value)
{
changed = true;
e->value = op;
}
gcc_checking_assert (e->index == strip_typedefs_expr (e->index));
}
if (!changed && type == TREE_TYPE (t))
{
VEC_free (constructor_elt, gc, vec);
return t;
}
else
{
r = copy_node (t);
TREE_TYPE (r) = type;
CONSTRUCTOR_ELTS (r) = vec;
return r;
}
}
case LAMBDA_EXPR:
gcc_unreachable ();
default:
break;
}
gcc_assert (EXPR_P (t));
n = TREE_OPERAND_LENGTH (t);
ops = XALLOCAVEC (tree, n);
type = TREE_TYPE (t);
switch (code)
{
CASE_CONVERT:
case IMPLICIT_CONV_EXPR:
case DYNAMIC_CAST_EXPR:
case STATIC_CAST_EXPR:
case CONST_CAST_EXPR:
case REINTERPRET_CAST_EXPR:
case CAST_EXPR:
case NEW_EXPR:
type = strip_typedefs (type);
/* fallthrough */
default:
for (i = 0; i < n; ++i)
ops[i] = strip_typedefs_expr (TREE_OPERAND (t, i));
break;
}
/* If nothing changed, return t. */
for (i = 0; i < n; ++i)
if (ops[i] != TREE_OPERAND (t, i))
break;
if (i == n && type == TREE_TYPE (t))
return t;
r = copy_node (t);
TREE_TYPE (r) = type;
for (i = 0; i < n; ++i)
TREE_OPERAND (r, i) = ops[i];
return r;
}
/* Makes a copy of BINFO and TYPE, which is to be inherited into a
graph dominated by T. If BINFO is NULL, TYPE is a dependent base,
and we do a shallow copy. If BINFO is non-NULL, we do a deep copy.
@ -2381,9 +2571,6 @@ cp_tree_equal (tree t1, tree t2)
BASELINK_FUNCTIONS (t2)));
case TEMPLATE_PARM_INDEX:
if (TEMPLATE_PARM_NUM_SIBLINGS (t1)
!= TEMPLATE_PARM_NUM_SIBLINGS (t2))
return false;
return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
&& TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
&& (TEMPLATE_PARM_PARAMETER_PACK (t1)

View File

@ -1137,12 +1137,6 @@ comp_template_parms_position (tree t1, tree t2)
index1 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t1));
index2 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t2));
/* If T1 and T2 belong to template parm lists of different size,
let's assume they are different. */
if (TEMPLATE_PARM_NUM_SIBLINGS (index1)
!= TEMPLATE_PARM_NUM_SIBLINGS (index2))
return false;
/* Then compare their relative position. */
if (TEMPLATE_PARM_IDX (index1) != TEMPLATE_PARM_IDX (index2)
|| TEMPLATE_PARM_LEVEL (index1) != TEMPLATE_PARM_LEVEL (index2)

View File

@ -1,3 +1,15 @@
2012-11-29 Jason Merrill <jason@redhat.com>
PR c++/53858
* g++.dg/cpp0x/alias-decl-20.C: New.
PR c++/50852
* g++.dg/template/typedef39.C: New.
PR c++/53039
* g++.dg/cpp0x/variadic133.C: New.
* g++.dg/template/param1.C: Adjust.
2012-11-27 Richard Biener <rguenther@suse.de>
PR middle-end/55331

View File

@ -0,0 +1,9 @@
// PR c++/53858
// { dg-do compile { target c++11 } }
template <typename T> struct s0 { typedef T tdef0; };
template <typename T> struct s1 { typedef T tdef1; };
template <typename T> using us1 = typename s1<T>::tdef1;
template <typename T, typename TT = typename us1<T>::tdef0> struct s2 {};
int main () { return 0; }

View File

@ -0,0 +1,46 @@
// PR c++/53039
// { dg-do compile { target c++11 } }
template <class, class>
struct is_convertible
{
static const bool value = true;
};
template<bool, class T>
struct enable_if
{
typedef T type;
};
template <bool...>
struct Xs
{
static const bool value = true;
};
template<typename... BTs>
class BType
{
template <typename... BUs,
typename enable_if<
Xs<is_convertible<BUs, BTs>::value...>::value,
bool>::type = false>
void fooX(BUs&&...);
};
template <typename... ATs>
struct AType
{
template <typename... AUs,
typename enable_if<
Xs<is_convertible<AUs, ATs>::value...>::value,
bool>::type = false>
void foo(AUs&&...);
};
int main()
{
AType<int, int> t;
t.foo(1, 1);
}

View File

@ -2,11 +2,11 @@
// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
// { dg-do compile }
template<int> struct A // { dg-error "declaration" }
template<int> struct A
{
A();
};
template<int N, char> A<N>::A() {} // { dg-error "invalid use of incomplete type" }
template<int N, char> A<N>::A() {} // { dg-error "got 2 template parameters|1 required" }
A<0> a;

View File

@ -0,0 +1,15 @@
// PR c++/50852
template<int d> class A;
template<class T> struct B {typedef int K;typedef int L;};
template<class U,class V> struct C
{
typedef typename U::L X;
typedef A<X::a-1> W;
};
template<class U,int d> struct D
{
typedef typename U::L X;
typedef A<X::a-1> W; // { dg-error "not a member" }
};
template class D<B<A<1> >,3>;