diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2013-11-12 09:21:45 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2013-11-12 09:21:45 +0000 |
commit | e4c04ff0e8852321a12bd02c520cdecef5dc2ac7 (patch) | |
tree | ac6149fb379cf7becabcda2af17d30fd50cfe1fe /gcc | |
parent | 801a661c44fdc05f6ad1edc3143386be4c7853b5 (diff) | |
download | gcc-e4c04ff0e8852321a12bd02c520cdecef5dc2ac7.zip gcc-e4c04ff0e8852321a12bd02c520cdecef5dc2ac7.tar.gz gcc-e4c04ff0e8852321a12bd02c520cdecef5dc2ac7.tar.bz2 |
re PR c++/57734 (Returning template alias to enum class fails with "invalid declarator")
/cp
2013-11-12 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57734
* pt.c (lookup_template_class_1): Handle alias template declarations
of enumeration types.
/testsuite
2013-11-12 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57734
* g++.dg/cpp0x/alias-decl-enum-1.C: New.
From-SVN: r204697
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 51 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alias-decl-enum-1.C | 47 |
4 files changed, 84 insertions, 25 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4934577..fc70bbd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-11-12 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/57734 + * pt.c (lookup_template_class_1): Handle alias template declarations + of enumeration types. + 2013-11-10 Paolo Carlini <paolo.carlini@oracle.com> * cvt.c (cp_convert_to_pointer): Call build_ptrmemfunc before diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8c1553f..d066c26 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 849597c..07106bc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-12 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/57734 + * g++.dg/cpp0x/alias-decl-enum-1.C: New. + 2013-11-11 Martin Liska <marxin.liska@gmail.com> * 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 0000000..260a193 --- /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<typename T, typename U> +struct same_type { static const bool value = false; }; + +template<typename T> +struct same_type<T, T> { static const bool value = true; }; + +enum e { zero }; +enum class eclass { one }; + +template<typename T> +using enum_alias = e; + +template<typename T> +using eclass_alias = eclass; + +typedef enum_alias<void> etest0; +typedef enum_alias<void> etest0; +typedef enum_alias<int> etest0; +typedef enum_alias<int> etest1; + +static_assert (same_type<etest0, etest1>::value, ""); + +typedef eclass_alias<void> ectest0; +typedef eclass_alias<void> ectest0; +typedef eclass_alias<int> ectest0; +typedef eclass_alias<int> ectest1; + +static_assert (same_type<ectest0, ectest1>::value, ""); + +template<typename T> +enum_alias<T> efoo(T f) { return enum_alias<T>::zero; } + +template<typename T> +constexpr enum_alias<T> cefoo(T f) { return enum_alias<T>::zero; } + +static_assert ( cefoo(1) == e::zero, ""); + +template<typename T> +eclass_alias<T> ecfoo(T f) { return eclass_alias<T>::one; } + +template<typename T> +constexpr eclass_alias<T> cecfoo(T f) { return eclass_alias<T>::one; } + +static_assert ( cecfoo(1) == eclass::one, ""); |