aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2016-12-13 20:43:08 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2016-12-13 20:43:08 +0000
commit5bfd81e7159a1d3a2e200f9f99bd0068bad7beb8 (patch)
tree24915d3755b3e9603ff9e056744214621d436522
parent2de1796a6bf6748e1b3d392056761d68df40dbd0 (diff)
downloadgcc-5bfd81e7159a1d3a2e200f9f99bd0068bad7beb8.zip
gcc-5bfd81e7159a1d3a2e200f9f99bd0068bad7beb8.tar.gz
gcc-5bfd81e7159a1d3a2e200f9f99bd0068bad7beb8.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/cp-tree.h37
-rw-r--r--gcc/cp/error.c10
-rw-r--r--gcc/cp/pt.c121
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr69481.C26
6 files changed, 131 insertions, 81 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 56803bf..24ceb04 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f7da76a..cc7ca87 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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. */
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 5f8fb2a..d025fcb 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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);
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 97d0b48..bae96ec 100644
--- a/gcc/cp/pt.c
+++ b/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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 072e617..4378e36 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr69481.C b/gcc/testsuite/g++.dg/cpp0x/pr69481.C
new file mode 100644
index 0000000..bab166b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr69481.C
@@ -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();
+}