From: Jason Merrill Date: Sat, 8 Nov 2014 06:06:42 +0000 (-0500) Subject: DR 1558 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=31cb2db0b28fe254d07194fb68bd95f8372a0457;p=gcc.git DR 1558 DR 1558 * pt.c (dependent_alias_template_spec_p): New. (dependent_type_p_r): Handle dependent alias template specialization. (template_args_equal): A dependent alias template specializations is not equal to its underlying type as a template argument. * tree.c (strip_typedefs): Don't strip a dependent alias template-id. From-SVN: r217250 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 132b9e1b859..a831d62d8c2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2014-11-07 Jason Merrill + DR 1558 + * pt.c (dependent_alias_template_spec_p): New. + (dependent_type_p_r): Handle dependent alias template specialization. + (template_args_equal): A dependent alias template specializations + is not equal to its underlying type as a template argument. + * tree.c (strip_typedefs): Don't strip a dependent alias + template-id. + * parser.c (cp_parser_unqualified_id): Handle __func__ here. (cp_parser_primary_expression): Not here. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index abc3d6fd19f..74636dfbf8f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5692,6 +5692,7 @@ extern tree fold_non_dependent_expr (tree); extern tree fold_non_dependent_expr_sfinae (tree, tsubst_flags_t); extern bool alias_type_or_template_p (tree); extern bool alias_template_specialization_p (const_tree); +extern bool dependent_alias_template_spec_p (const_tree); extern bool explicit_class_specialization_p (tree); extern bool push_tinst_level (tree); extern bool push_tinst_level_loc (tree, location_t); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 2cf10f442f6..fa9652f748c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5268,7 +5268,7 @@ alias_type_or_template_p (tree t) || DECL_ALIAS_TEMPLATE_P (t)); } -/* Return TRUE iff is a specialization of an alias template. */ +/* Return TRUE iff T is a specialization of an alias template. */ bool alias_template_specialization_p (const_tree t) @@ -5282,6 +5282,16 @@ alias_template_specialization_p (const_tree t) && DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t))); } +/* Return TRUE iff T is a specialization of an alias template with + dependent template-arguments. */ + +bool +dependent_alias_template_spec_p (const_tree t) +{ + return (alias_template_specialization_p (t) + && any_dependent_template_arguments_p (TYPE_TI_ARGS (t))); +} + /* Return the number of innermost template parameters in TMPL. */ static int @@ -7217,7 +7227,24 @@ template_args_equal (tree ot, tree nt) return template_args_equal (ot, nt); } else if (TYPE_P (nt)) - return TYPE_P (ot) && same_type_p (ot, nt); + { + if (!TYPE_P (ot)) + return false; + /* Don't treat an alias template specialization with dependent + arguments as equivalent to its underlying type when used as a + template argument; we need them to hash differently. */ + bool ndep = dependent_alias_template_spec_p (nt); + ++processing_template_decl; + bool odep = dependent_alias_template_spec_p (ot); + --processing_template_decl; + if (ndep != odep) + return false; + else if (ndep) + return (TYPE_TI_TEMPLATE (nt) == TYPE_TI_TEMPLATE (ot) + && template_args_equal (TYPE_TI_ARGS (nt), TYPE_TI_ARGS (ot))); + else + return same_type_p (ot, nt); + } else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot)) return 0; else @@ -20719,8 +20746,10 @@ dependent_type_p_r (tree type) if (TREE_CODE (type) == TYPENAME_TYPE) return true; /* -- a cv-qualified type where the cv-unqualified type is - dependent. */ - type = TYPE_MAIN_VARIANT (type); + dependent. + No code is necessary for this bullet; the code below handles + cv-qualified types, and we don't want to strip aliases with + TYPE_MAIN_VARIANT because of DR 1558. */ /* -- a compound type constructed from any dependent type. */ if (TYPE_PTRMEM_P (type)) return (dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type)) @@ -20763,9 +20792,9 @@ dependent_type_p_r (tree type) return true; /* ... or any of the template arguments is a dependent type or an expression that is type-dependent or value-dependent. */ - else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type) + else if (TYPE_TEMPLATE_INFO (type) && (any_dependent_template_arguments_p - (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type))))) + (INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (type))))) return true; /* All TYPEOF_TYPEs, DECLTYPE_TYPEs, and UNDERLYING_TYPEs are diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 32e7bd5499d..e0c2af1576c 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1244,6 +1244,11 @@ strip_typedefs (tree t) if (t == TYPE_CANONICAL (t)) return t; + if (dependent_alias_template_spec_p (t)) + /* DR 1558: However, if the template-id is dependent, subsequent + template argument substitution still applies to the template-id. */ + return t; + switch (TREE_CODE (t)) { case POINTER_TYPE: diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1558.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1558.C new file mode 100644 index 00000000000..2bbb138ec22 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1558.C @@ -0,0 +1,14 @@ +// DR 1558 still applies when using void_t as a template-argument. +// { dg-do compile { target c++11 } } + +template using void_t = void; +template struct A { }; +struct B { typedef int foo; }; +template A> f(); // { dg-error "int" } +template A g(); +int main() +{ + f(); + g(); + f(); // { dg-error "no match" } +}