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 +struct DEPRECATED +ClassPartial { }; // { dg-message "declared here" } + +// Verify that a partial specialization is diagnosed. +template +struct ClassPartial { }; // { dg-warning ".template * struct ClassPartial. is deprecated" } + + +template +struct +ClassPartialDeprecated { }; + +template +struct DEPRECATED +ClassPartialDeprecated { }; + +ClassPartialDeprecated cpdi; +ClassPartialDeprecated cpdci; // { dg-warning "is deprecated" "bug 84347" { xfail *-*-* } } + + +template +struct DEPRECATED +ClassExplicit { }; // { dg-message "declared here" } + +template <> +struct +ClassExplicit { }; // { dg-warning ".template * struct ClassExplicit. is deprecated" } + + +template +void DEPRECATED +FuncExplicit (); // { dg-message "declared here" } + +template <> +void +FuncExplicit(); // { dg-warning ".void FuncExplicit\\\(\\\). is deprecated" } + + +template +int DEPRECATED +VarPartial; // { dg-message "declared here" } + +template +int +VarPartial; // { dg-warning ".VarPartial. is deprecated" } + +template +int DEPRECATED +VarExplicit; // { dg-message "declared here" } + +template <> +int +VarExplicit; // { dg-warning ".VarExplicit. is deprecated" } + +// { dg-prune-output "variable templates only available" }