diff options
author | Jason Merrill <jason@redhat.com> | 2018-03-01 11:00:34 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2018-03-01 11:00:34 -0500 |
commit | 303a1e75148a5628bf705c154c62c5ffa6c03542 (patch) | |
tree | 268ac9d8cc511d1f9c3009f4e88be1836fe97011 | |
parent | 99daa7a9eeffa553d3fd3b8dcf6dd721441921c6 (diff) | |
download | gcc-303a1e75148a5628bf705c154c62c5ffa6c03542.zip gcc-303a1e75148a5628bf705c154c62c5ffa6c03542.tar.gz gcc-303a1e75148a5628bf705c154c62c5ffa6c03542.tar.bz2 |
PR c++/71569 - ICE with redundant args on member variable template.
* decl.c (start_decl): Handle partial specialization of member
variable template.
* pt.c (determine_specialization): Allow partial specialization
of member variable template without specializing enclosing class.
(process_partial_specialization): Improve error message.
Co-Authored-By: Alexandre Oliva <aoliva@redhat.com>
From-SVN: r258102
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/decl.c | 20 | ||||
-rw-r--r-- | gcc/cp/pt.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ58.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ58a.C | 14 |
5 files changed, 52 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index be9b3fdc..a6deacb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2018-03-01 Jason Merrill <jason@redhat.com> + Alexandre Oliva <aoliva@redhat.com> + + PR c++/71569 - ICE with redundant args on member variable template. + * decl.c (start_decl): Handle partial specialization of member + variable template. + * pt.c (determine_specialization): Allow partial specialization + of member variable template without specializing enclosing class. + (process_partial_specialization): Improve error message. + 2018-02-28 Jason Merrill <jason@redhat.com> PR c++/71784 - ICE with ref-qualifier and explicit specialization. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f1be229..db64d12 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5080,19 +5080,17 @@ start_decl (const cp_declarator *declarator, if (field == NULL_TREE || !(VAR_P (field) || variable_template_p (field))) error ("%q+#D is not a static data member of %q#T", decl, context); + else if (variable_template_p (field) + && (DECL_LANG_SPECIFIC (decl) + && DECL_TEMPLATE_SPECIALIZATION (decl))) + /* OK, specialization was already checked. */; else if (variable_template_p (field) && !this_tmpl) { - if (DECL_LANG_SPECIFIC (decl) - && DECL_TEMPLATE_SPECIALIZATION (decl)) - /* OK, specialization was already checked. */; - else - { - error_at (DECL_SOURCE_LOCATION (decl), - "non-member-template declaration of %qD", decl); - inform (DECL_SOURCE_LOCATION (field), "does not match " - "member template declaration here"); - return error_mark_node; - } + error_at (DECL_SOURCE_LOCATION (decl), + "non-member-template declaration of %qD", decl); + inform (DECL_SOURCE_LOCATION (field), "does not match " + "member template declaration here"); + return error_mark_node; } else { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7345119..e07d77b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2060,7 +2060,8 @@ determine_specialization (tree template_id, /* We shouldn't be specializing a member template of an unspecialized class template; we already gave an error in check_specialization_scope, now avoid crashing. */ - if (template_count && DECL_CLASS_SCOPE_P (decl) + if (!VAR_P (decl) + && template_count && DECL_CLASS_SCOPE_P (decl) && template_class_depth (DECL_CONTEXT (decl)) > 0) { gcc_assert (errorcount); @@ -4840,10 +4841,13 @@ process_partial_specialization (tree decl) { if (!flag_concepts) error ("partial specialization %q+D does not specialize " - "any template arguments", decl); + "any template arguments; to define the primary template, " + "remove the template argument list", decl); else error ("partial specialization %q+D does not specialize any " - "template arguments and is not more constrained than", decl); + "template arguments and is not more constrained than " + "the primary template; to define the primary template, " + "remove the template argument list", decl); inform (DECL_SOURCE_LOCATION (maintmpl), "primary template here"); } diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ58.C b/gcc/testsuite/g++.dg/cpp1y/var-templ58.C new file mode 100644 index 0000000..f9095f6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ58.C @@ -0,0 +1,12 @@ +// PR c++/71569 +// { dg-do compile { target c++14 } } + +template <class T> +struct A { + template <class U> + static const U u; +}; + +template <class T> +template <class U> +const U A<T>::u<U> = 0; // { dg-error "does not specialize" } diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ58a.C b/gcc/testsuite/g++.dg/cpp1y/var-templ58a.C new file mode 100644 index 0000000..850a2c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ58a.C @@ -0,0 +1,14 @@ +// PR c++/71569 +// { dg-do compile { target c++14 } } + +template <class T> +struct A { + template <class U> + static const U u; +}; + +template <class T> +template <class U> +const U* A<T>::u<U*> = 0; + +const int *p = A<char>::u<int*>; |