While testing my fix for 83871 (handling attributes on explicit specializations) I noticed another old regression: while GCC 4.4 would diagnose declarations of explicit soecializations of all primary templates declared deprecated, GCC 4.5 and later only diagnose declarations of explicit soecializations of class templates but not those of function or variable templates.
The root cause of this regression is different than 83871 so I prefer to fix each separately. The attached patch does that. Because there is an opportunity to share code between the two fixes I expect to integrate one into the other (whichever is approved/committed last). Martin
PR c++/84318 - attribute deprecated on function templates different than class templates gcc/cp/ChangeLog: PR c++/84318 * pt.c (check_explicit_specialization): Warn for explicit specializations of deprecated primary templates. gcc/testsuite/ChangeLog: PR c++/84318 * g++.dg/ext/attr-deprecated-2.C: New test. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b58c60f..aa5f0dd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3104,6 +3104,20 @@ check_explicit_specialization (tree declarator, else if (VAR_P (decl)) DECL_COMDAT (decl) = false; + if (TREE_CODE (gen_tmpl) != TYPE_DECL) + { + tree tmpl = gen_tmpl; + if (DECL_FUNCTION_TEMPLATE_P (tmpl) + || TREE_CODE (tmpl) == TEMPLATE_DECL) + tmpl = DECL_TEMPLATE_RESULT (tmpl); + + /* Diagnose declarations of specializations of + a deprecated primary template. */ + if (TREE_DEPRECATED (tmpl) + || lookup_attribute ("deprecated", DECL_ATTRIBUTES (tmpl))) + warn_deprecated_use (tmpl, NULL_TREE); + } + /* If this is a full specialization, register it so that we can find it again. Partial specializations will be registered in process_partial_specialization. */ diff --git a/gcc/testsuite/g++.dg/ext/attr-deprecated-2.C b/gcc/testsuite/g++.dg/ext/attr-deprecated-2.C new file mode 100644 index 0000000..f639a73 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-deprecated-2.C @@ -0,0 +1,63 @@ +// PR c++/84318 - attribute deprecated on function templates different +// than class templates +// { dg-do compile } +// { dg-options "-Wall" } + +#define DEPRECATED __attribute__ ((deprecated)) + +template <typename T> +struct DEPRECATED +ClassPartial { }; // { dg-message "declared here" } + +// Verify that a partial specialization is diagnosed. +template <typename T> +struct ClassPartial<const T> { }; // { dg-warning ".template *<class T> struct ClassPartial. is deprecated" } + + +template <typename T> +struct +ClassPartialDeprecated { }; + +template <typename T> +struct DEPRECATED +ClassPartialDeprecated<T*> { }; + +ClassPartialDeprecated<int> cpdi; +ClassPartialDeprecated<int*> cpdci; // { dg-warning "is deprecated" "bug 84347" { xfail *-*-* } } + + +template <typename T> +struct DEPRECATED +ClassExplicit { }; // { dg-message "declared here" } + +template <> +struct +ClassExplicit<int> { }; // { dg-warning ".template *<class T> struct ClassExplicit. is deprecated" } + + +template <typename T> +void DEPRECATED +FuncExplicit (); // { dg-message "declared here" } + +template <> +void +FuncExplicit<int>(); // { dg-warning ".void FuncExplicit\\\(\\\). is deprecated" } + + +template <typename T> +int DEPRECATED +VarPartial; // { dg-message "declared here" } + +template <class T> +int +VarPartial<const T>; // { dg-warning ".VarPartial<T>. is deprecated" } + +template <typename T> +int DEPRECATED +VarExplicit; // { dg-message "declared here" } + +template <> +int +VarExplicit<int>; // { dg-warning ".VarExplicit<T>. is deprecated" } + +// { dg-prune-output "variable templates only available" }