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:
parent
2de1796a6b
commit
5bfd81e715
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
}
|
||||
|
121
gcc/cp/pt.c
121
gcc/cp/pt.c
@ -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
|
||||
|
@ -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
|
||||
|
26
gcc/testsuite/g++.dg/cpp0x/pr69481.C
Normal file
26
gcc/testsuite/g++.dg/cpp0x/pr69481.C
Normal 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();
|
||||
}
|
Loading…
Reference in New Issue
Block a user