From 3ab7b731173156a56b52c191c9917c5b0fbb6e42 Mon Sep 17 00:00:00 2001 From: paolo Date: Tue, 12 Nov 2013 09:21:45 +0000 Subject: [PATCH] /cp 2013-11-12 Paolo Carlini PR c++/57734 * pt.c (lookup_template_class_1): Handle alias template declarations of enumeration types. /testsuite 2013-11-12 Paolo Carlini PR c++/57734 * g++.dg/cpp0x/alias-decl-enum-1.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204697 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 +++ gcc/cp/pt.c | 51 +++++++++++++------------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/cpp0x/alias-decl-enum-1.C | 47 ++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-enum-1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4934577ea2a..fc70bbdc8cb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-11-12 Paolo Carlini + + PR c++/57734 + * pt.c (lookup_template_class_1): Handle alias template declarations + of enumeration types. + 2013-11-10 Paolo Carlini * cvt.c (cp_convert_to_pointer): Call build_ptrmemfunc before diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8c1553feca2..d066c26dd88 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7458,30 +7458,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, context = global_namespace; /* Create the type. */ - if (TREE_CODE (template_type) == ENUMERAL_TYPE) - { - if (!is_dependent_type) - { - set_current_access_from_decl (TYPE_NAME (template_type)); - t = start_enum (TYPE_IDENTIFIER (template_type), NULL_TREE, - tsubst (ENUM_UNDERLYING_TYPE (template_type), - arglist, complain, in_decl), - SCOPED_ENUM_P (template_type), NULL); - } - else - { - /* We don't want to call start_enum for this type, since - the values for the enumeration constants may involve - template parameters. And, no one should be interested - in the enumeration constants for such a type. */ - t = cxx_make_type (ENUMERAL_TYPE); - SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type)); - } - SET_OPAQUE_ENUM_P (t, OPAQUE_ENUM_P (template_type)); - ENUM_FIXED_UNDERLYING_TYPE_P (t) - = ENUM_FIXED_UNDERLYING_TYPE_P (template_type); - } - else if (DECL_ALIAS_TEMPLATE_P (gen_tmpl)) + if (DECL_ALIAS_TEMPLATE_P (gen_tmpl)) { /* The user referred to a specialization of an alias template represented by GEN_TMPL. @@ -7505,6 +7482,29 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, if (t == error_mark_node) return t; } + else if (TREE_CODE (template_type) == ENUMERAL_TYPE) + { + if (!is_dependent_type) + { + set_current_access_from_decl (TYPE_NAME (template_type)); + t = start_enum (TYPE_IDENTIFIER (template_type), NULL_TREE, + tsubst (ENUM_UNDERLYING_TYPE (template_type), + arglist, complain, in_decl), + SCOPED_ENUM_P (template_type), NULL); + } + else + { + /* We don't want to call start_enum for this type, since + the values for the enumeration constants may involve + template parameters. And, no one should be interested + in the enumeration constants for such a type. */ + t = cxx_make_type (ENUMERAL_TYPE); + SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type)); + } + SET_OPAQUE_ENUM_P (t, OPAQUE_ENUM_P (template_type)); + ENUM_FIXED_UNDERLYING_TYPE_P (t) + = ENUM_FIXED_UNDERLYING_TYPE_P (template_type); + } else if (CLASS_TYPE_P (template_type)) { t = make_class_type (TREE_CODE (template_type)); @@ -7661,7 +7661,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, = tree_cons (arglist, t, DECL_TEMPLATE_INSTANTIATIONS (templ)); - if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type) + if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type + && !DECL_ALIAS_TEMPLATE_P (gen_tmpl)) /* Now that the type has been registered on the instantiations list, we set up the enumerators. Because the enumeration constants may involve the enumeration type itself, we make diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 849597c0d0c..07106bc31a7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-12 Paolo Carlini + + PR c++/57734 + * g++.dg/cpp0x/alias-decl-enum-1.C: New. + 2013-11-11 Martin Liska * gcc.dg/time-profiler-1.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-enum-1.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-enum-1.C new file mode 100644 index 00000000000..260a193a083 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-enum-1.C @@ -0,0 +1,47 @@ +// PR c++/57734 +// { dg-do compile { target c++11 } } + +template +struct same_type { static const bool value = false; }; + +template +struct same_type { static const bool value = true; }; + +enum e { zero }; +enum class eclass { one }; + +template +using enum_alias = e; + +template +using eclass_alias = eclass; + +typedef enum_alias etest0; +typedef enum_alias etest0; +typedef enum_alias etest0; +typedef enum_alias etest1; + +static_assert (same_type::value, ""); + +typedef eclass_alias ectest0; +typedef eclass_alias ectest0; +typedef eclass_alias ectest0; +typedef eclass_alias ectest1; + +static_assert (same_type::value, ""); + +template +enum_alias efoo(T f) { return enum_alias::zero; } + +template +constexpr enum_alias cefoo(T f) { return enum_alias::zero; } + +static_assert ( cefoo(1) == e::zero, ""); + +template +eclass_alias ecfoo(T f) { return eclass_alias::one; } + +template +constexpr eclass_alias cecfoo(T f) { return eclass_alias::one; } + +static_assert ( cecfoo(1) == eclass::one, ""); -- 2.11.4.GIT