re PR c++/69481 (ICE with C++11 alias using with templates)

cp/
	PR c++/69481
	* cp-tree.h (TYPE_TEMPLATE_INFO): Remove alias type checking.
	(TYPE_ALIAS_TEMPLATE_INFO): New.
	(TYPE_TEMPLATE_INFO_MAYBE_ALIAS): New.  Use those macros.
	* error.c (dump_alias_template_specialization): Adjust.
	* pt.c (maybe_process_partial_specialization)
	iterative_has_template_arg, find_parameter_packs_r,
	alias_template_specialization_p, dependent_alias_template_spec_p,
	get_underlying_template, lookup_template_class_1, unify): Adjust
	template using decl access.

	testsuite/
	PR c++/69481
	* g++.dg/cpp0x/pr69481.C: New.
(--This line, and those below, will be ignored--

M    gcc/testsuite/ChangeLog
A    gcc/testsuite/g++.dg/cpp0x/pr69481.C
M    gcc/cp/cp-tree.h
M    gcc/cp/error.c
M    gcc/cp/ChangeLog
M    gcc/cp/pt.c

From-SVN: r243624
This commit is contained in:
Nathan Sidwell 2016-12-13 20:43:08 +00:00 committed by Nathan Sidwell
parent 2de1796a6b
commit 5bfd81e715
6 changed files with 131 additions and 81 deletions

View File

@ -1,3 +1,16 @@
2016-12-13 Nathan Sidwell <nathan@acm.org>
PR c++/69481
* cp-tree.h (TYPE_TEMPLATE_INFO): Remove alias type checking.
(TYPE_ALIAS_TEMPLATE_INFO): New.
(TYPE_TEMPLATE_INFO_MAYBE_ALIAS): New. Use those macros.
* error.c (dump_alias_template_specialization): Adjust.
* pt.c (maybe_process_partial_specialization,
iterative_has_template_arg, find_parameter_packs_r,
alias_template_specialization_p, dependent_alias_template_spec_p,
get_underlying_template, lookup_template_class_1, unify): Adjust
template using decl access.
2016-12-11 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/78637

View File

@ -3038,23 +3038,30 @@ extern void decl_shadowed_for_var_insert (tree, tree);
->template_info)
/* Template information for an ENUMERAL_, RECORD_, UNION_TYPE, or
BOUND_TEMPLATE_TEMPLATE_PARM type. Note that if NODE is a
specialization of an alias template, this accessor returns the
template info for the alias template, not the one (if any) for the
template of the underlying type. */
BOUND_TEMPLATE_TEMPLATE_PARM type. This ignores any alias
templateness of NODE. */
#define TYPE_TEMPLATE_INFO(NODE) \
((TYPE_ALIAS_P (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE))) \
? (DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \
? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \
: NULL_TREE) \
: ((TREE_CODE (NODE) == ENUMERAL_TYPE) \
? ENUM_TEMPLATE_INFO (NODE) \
: ((TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM) \
? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \
: (CLASS_TYPE_P (NODE) \
? CLASSTYPE_TEMPLATE_INFO (NODE) \
: NULL_TREE))))
(TREE_CODE (NODE) == ENUMERAL_TYPE \
? ENUM_TEMPLATE_INFO (NODE) \
: (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \
? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \
: (CLASS_TYPE_P (NODE) \
? CLASSTYPE_TEMPLATE_INFO (NODE) \
: NULL_TREE)))
/* Template information for an alias template type. */
#define TYPE_ALIAS_TEMPLATE_INFO(NODE) \
(DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \
? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \
: NULL_TREE)
/* If NODE is a specialization of an alias template, this accessor
returns the template info for the alias template. Otherwise behave
as TYPE_TEMPLATE_INFO. */
#define TYPE_TEMPLATE_INFO_MAYBE_ALIAS(NODE) \
(TYPE_ALIAS_P (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \
? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \
: TYPE_TEMPLATE_INFO (NODE))
/* Set the template information for an ENUMERAL_, RECORD_, or
UNION_TYPE to VAL. */

View File

@ -365,15 +365,13 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
static void
dump_alias_template_specialization (cxx_pretty_printer *pp, tree t, int flags)
{
tree name;
gcc_assert (alias_template_specialization_p (t));
tree decl = TYPE_NAME (t);
if (!(flags & TFF_UNQUALIFIED_NAME))
dump_scope (pp, CP_DECL_CONTEXT (TYPE_NAME (t)), flags);
name = TYPE_IDENTIFIER (t);
pp_cxx_tree_identifier (pp, name);
dump_template_parms (pp, TYPE_TEMPLATE_INFO (t),
dump_scope (pp, CP_DECL_CONTEXT (decl), flags);
pp_cxx_tree_identifier (pp, DECL_NAME (decl));
dump_template_parms (pp, DECL_TEMPLATE_INFO (decl),
/*primary=*/false,
flags & ~TFF_TEMPLATE_HEADER);
}

View File

@ -940,10 +940,11 @@ maybe_process_partial_specialization (tree type)
if (TYPE_ALIAS_P (type))
{
if (TYPE_TEMPLATE_INFO (type)
&& DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (type)))
tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (type);
if (tinfo && DECL_ALIAS_TEMPLATE_P (TI_TEMPLATE (tinfo)))
error ("specialization of alias template %qD",
TYPE_TI_TEMPLATE (type));
TI_TEMPLATE (tinfo));
else
error ("explicit specialization of non-template %qT", type);
return error_mark_node;
@ -1829,7 +1830,7 @@ iterative_hash_template_arg (tree arg, hashval_t val)
// left alone, or untouched specializations because
// coerce_template_parms returns the unconverted template
// arguments if it sees incomplete argument packs.
tree ti = TYPE_TEMPLATE_INFO (arg);
tree ti = TYPE_ALIAS_TEMPLATE_INFO (arg);
return hash_tmpl_and_args (TI_TEMPLATE (ti), TI_ARGS (ti));
}
if (TYPE_CANONICAL (arg))
@ -3459,8 +3460,8 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
/* Handle type aliases/typedefs. */
if (TYPE_ALIAS_P (t))
{
if (TYPE_TEMPLATE_INFO (t))
cp_walk_tree (&TYPE_TI_ARGS (t),
if (tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (t))
cp_walk_tree (&TI_ARGS (tinfo),
&find_parameter_packs_r,
ppd, ppd->visited);
*walk_subtrees = 0;
@ -5794,15 +5795,9 @@ alias_template_specialization_p (const_tree t)
/* It's an alias template specialization if it's an alias and its
TYPE_NAME is a specialization of a primary template. */
if (TYPE_ALIAS_P (t))
{
tree name = TYPE_NAME (t);
if (DECL_LANG_SPECIFIC (name))
if (tree ti = DECL_TEMPLATE_INFO (name))
{
tree tmpl = TI_TEMPLATE (ti);
return PRIMARY_TEMPLATE_P (tmpl);
}
}
if (tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (t))
return PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo));
return false;
}
@ -5854,10 +5849,18 @@ complex_alias_template_p (const_tree tmpl)
bool
dependent_alias_template_spec_p (const_tree t)
{
return (alias_template_specialization_p (t)
&& TEMPLATE_DECL_COMPLEX_ALIAS_P (DECL_TI_TEMPLATE (TYPE_NAME (t)))
&& (any_dependent_template_arguments_p
(INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (t)))));
if (!alias_template_specialization_p (t))
return false;
tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (t);
if (!TEMPLATE_DECL_COMPLEX_ALIAS_P (TI_TEMPLATE (tinfo)))
return false;
tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo));
if (!any_dependent_template_arguments_p (args))
return false;
return true;
}
/* Return the number of innermost template parameters in TMPL. */
@ -5879,26 +5882,27 @@ get_underlying_template (tree tmpl)
gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
while (DECL_ALIAS_TEMPLATE_P (tmpl))
{
tree result = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl));
if (TYPE_TEMPLATE_INFO (result))
{
tree sub = TYPE_TI_TEMPLATE (result);
if (PRIMARY_TEMPLATE_P (sub)
&& (num_innermost_template_parms (tmpl)
== num_innermost_template_parms (sub)))
{
tree alias_args = INNERMOST_TEMPLATE_ARGS
(template_parms_to_args (DECL_TEMPLATE_PARMS (tmpl)));
if (!comp_template_args (TYPE_TI_ARGS (result), alias_args))
break;
/* The alias type is equivalent to the pattern of the
underlying template, so strip the alias. */
tmpl = sub;
continue;
}
}
break;
/* Determine if the alias is equivalent to an underlying template. */
tree orig_type = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl));
tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (orig_type);
if (!tinfo)
break;
tree underlying = TI_TEMPLATE (tinfo);
if (!PRIMARY_TEMPLATE_P (underlying)
|| (num_innermost_template_parms (tmpl)
!= num_innermost_template_parms (underlying)))
break;
tree alias_args = INNERMOST_TEMPLATE_ARGS
(template_parms_to_args (DECL_TEMPLATE_PARMS (tmpl)));
if (!comp_template_args (TI_ARGS (tinfo), alias_args))
break;
/* Alias is equivalent. Strip it and repeat. */
tmpl = underlying;
}
return tmpl;
}
@ -8375,9 +8379,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
TEMPLATE will be `template <class T> template
<class U> struct S1<T>::S2'. We must fill in the missing
arguments. */
arglist
= add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (templ)),
arglist);
tree ti = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (TREE_TYPE (templ));
arglist = add_outermost_template_args (TI_ARGS (ti), arglist);
arg_depth = TMPL_ARGS_DEPTH (arglist);
}
@ -8407,13 +8410,15 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
the `C<T>' is just the same as `C'. Outside of the
class, however, such a reference is an instantiation. */
if ((entering_scope
|| !PRIMARY_TEMPLATE_P (gen_tmpl)
|| currently_open_class (template_type))
/* comp_template_args is expensive, check it last. */
&& comp_template_args (TYPE_TI_ARGS (template_type),
arglist))
return template_type;
if (entering_scope
|| !PRIMARY_TEMPLATE_P (gen_tmpl)
|| currently_open_class (template_type))
{
tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (template_type);
if (comp_template_args (TI_ARGS (tinfo), arglist))
return template_type;
}
/* If we already have this specialization, return it. */
elt.tmpl = gen_tmpl;
@ -8641,12 +8646,11 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
&& CLASS_TYPE_P (context)
&& !same_type_p (context, DECL_CONTEXT (gen_tmpl)))
{
tree partial_inst_args;
TREE_VEC_LENGTH (arglist)--;
++processing_template_decl;
partial_inst_args =
tsubst (INNERMOST_TEMPLATE_ARGS
(TYPE_TI_ARGS (TREE_TYPE (gen_tmpl))),
tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (TREE_TYPE (gen_tmpl));
tree partial_inst_args =
tsubst (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo)),
arglist, complain, NULL_TREE);
--processing_template_decl;
TREE_VEC_LENGTH (arglist)++;
@ -8678,11 +8682,11 @@ 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) == TEMPLATE_DECL
? found
: TREE_CODE (found) == TYPE_DECL
? TYPE_TI_TEMPLATE (TREE_TYPE (found))
: CLASSTYPE_TI_TEMPLATE (found);
found = (TREE_CODE (found) == TEMPLATE_DECL
? found
: (TREE_CODE (found) == TYPE_DECL
? DECL_TI_TEMPLATE (found)
: CLASSTYPE_TI_TEMPLATE (found)));
}
// Build template info for the new specialization.
@ -20035,9 +20039,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
return unify_template_deduction_failure (explain_p, parm, arg);
{
tree parmvec = TYPE_TI_ARGS (parm);
/* An alias template name is never deduced. */
if (TYPE_ALIAS_P (arg))
arg = strip_typedefs (arg);
tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg));
tree full_argvec = add_to_template_args (targs, argvec);
tree parm_parms

View File

@ -1,3 +1,8 @@
2016-12-13 Nathan Sidwell <nathan@acm.org>
PR c++/69481
* g++.dg/cpp0x/pr69481.C: New.
2016-12-13 Uros Bizjak <ubizjak@gmail.com>
PR target/78794

View File

@ -0,0 +1,26 @@
// PR c++/69481
// { dg-do compile { target c++11 } }
// ICE with canonical type verification
template <typename> struct Traits;
template <typename T>
struct Bob {
using Loc = Traits<T>;
using typename Loc::Thing;
Thing Foo ();
};
template <class V> struct tt
{
using ut = tt<V>;
ut Bob ();
};
template <class V>
tt<V> tt<V>::Bob ()
{
return tt();
}