Message ID | Y3IbNWSVE+Ydjk4u@tucnak |
---|---|
State | New |
Headers | show |
Series | c++: Allow attributes on concepts - DR 2428 | expand |
On 11/14/22 00:40, Jakub Jelinek wrote: > Hi! > > Working virtually out of Baker Island. > > The following patch adds parsing of attributes to concept definition, > allows deprecated attribute to be specified (some ugliness needed > because CONCEPT_DECL is a cp/*.def attribute and so can't be mentioned > in c-family/ directly; used what is used for objc method decls, > an alternative would be a langhook) Several of the codes in c-common.def are C++-only, you might just move it over? > and checks TREE_DEPRECATED in > build_standard_check (not sure if that is the right spot, or whether > it shouldn't be checked also for variable and function concepts and > how to write testcase coverage for that). I wouldn't bother with var/fn concepts, they're obsolete. > Lightly tested so far. > > 2022-11-13 Jakub Jelinek <jakub@redhat.com> > > gcc/c-family/ > * c-common.h (c_concept_decl): Declare. > * c-attribs.cc (handle_deprecated_attribute): Allow deprecated > attribute on CONCEPT_DECL if flag_concepts. > gcc/c/ > * c-decl.cc (c_concept_decl): New function. > gcc/cp/ > * cp-tree.h (finish_concept_definition): Add ATTRS parameter. > * parser.cc (cp_parser_concept_definition): Parse attributes in > between identifier and =. Adjust finish_concept_definition > caller. > * pt.cc (finish_concept_definition): Add ATTRS parameter. Call > cplus_decl_attributes. > * constraint.cc (build_standard_check): If CONCEPT_DECL is > TREE_DEPRECATED, emit -Wdeprecated-declaration warnings. > * tree.cc (c_concept_decl): New function. > gcc/testsuite/ > * g++.dg/cpp2a/concepts-dr2428.C: New test. > > --- gcc/c-family/c-common.h.jj 2022-10-27 21:00:53.698247586 -1200 > +++ gcc/c-family/c-common.h 2022-11-13 21:49:37.934598359 -1200 > @@ -831,6 +831,7 @@ extern tree (*make_fname_decl) (location > > /* In c-decl.cc and cp/tree.cc. FIXME. */ > extern void c_register_addr_space (const char *str, addr_space_t as); > +extern bool c_concept_decl (enum tree_code); > > /* In c-common.cc. */ > extern bool in_late_binary_op; > --- gcc/c-family/c-attribs.cc.jj 2022-10-09 19:31:57.177988375 -1200 > +++ gcc/c-family/c-attribs.cc 2022-11-13 21:52:37.920152731 -1200 > @@ -4211,7 +4211,8 @@ handle_deprecated_attribute (tree *node, > || VAR_OR_FUNCTION_DECL_P (decl) > || TREE_CODE (decl) == FIELD_DECL > || TREE_CODE (decl) == CONST_DECL > - || objc_method_decl (TREE_CODE (decl))) > + || objc_method_decl (TREE_CODE (decl)) > + || (flag_concepts && c_concept_decl (TREE_CODE (decl)))) > TREE_DEPRECATED (decl) = 1; > else if (TREE_CODE (decl) == LABEL_DECL) > { > --- gcc/c/c-decl.cc.jj 2022-11-12 23:29:08.181504470 -1200 > +++ gcc/c/c-decl.cc 2022-11-13 21:50:38.178779716 -1200 > @@ -12987,6 +12987,14 @@ c_register_addr_space (const char *word, > ridpointers [rid] = id; > } > > +/* C doesn't have CONCEPT_DECL. */ > + > +bool > +c_concept_decl (enum tree_code) > +{ > + return false; > +} > + > /* Return identifier to look up for omp declare reduction. */ > > tree > --- gcc/cp/cp-tree.h.jj 2022-11-11 20:30:10.138056914 -1200 > +++ gcc/cp/cp-tree.h 2022-11-13 20:58:39.443218815 -1200 > @@ -8324,7 +8324,7 @@ struct diagnosing_failed_constraint > extern cp_expr finish_constraint_or_expr (location_t, cp_expr, cp_expr); > extern cp_expr finish_constraint_and_expr (location_t, cp_expr, cp_expr); > extern cp_expr finish_constraint_primary_expr (cp_expr); > -extern tree finish_concept_definition (cp_expr, tree); > +extern tree finish_concept_definition (cp_expr, tree, tree); > extern tree combine_constraint_expressions (tree, tree); > extern tree append_constraint (tree, tree); > extern tree get_constraints (const_tree); > --- gcc/cp/parser.cc.jj 2022-11-08 22:39:13.325041007 -1200 > +++ gcc/cp/parser.cc 2022-11-13 20:58:15.692542640 -1200 > @@ -29672,6 +29672,8 @@ cp_parser_concept_definition (cp_parser > return NULL_TREE; > } > > + tree attrs = cp_parser_attributes_opt (parser); > + > if (!cp_parser_require (parser, CPP_EQ, RT_EQ)) > { > cp_parser_skip_to_end_of_statement (parser); > @@ -29688,7 +29690,7 @@ cp_parser_concept_definition (cp_parser > but continue as if it were. */ > cp_parser_consume_semicolon_at_end_of_statement (parser); > > - return finish_concept_definition (id, init); > + return finish_concept_definition (id, init, attrs); > } > > // -------------------------------------------------------------------------- // > --- gcc/cp/pt.cc.jj 2022-11-07 20:54:37.341399829 -1200 > +++ gcc/cp/pt.cc 2022-11-13 21:01:18.333053377 -1200 > @@ -29027,7 +29027,7 @@ placeholder_type_constraint_dependent_p > the TEMPLATE_DECL. */ > > tree > -finish_concept_definition (cp_expr id, tree init) > +finish_concept_definition (cp_expr id, tree init, tree attrs) > { > gcc_assert (identifier_p (id)); > gcc_assert (processing_template_decl); > @@ -29061,6 +29061,9 @@ finish_concept_definition (cp_expr id, t > DECL_CONTEXT (decl) = current_scope (); > DECL_INITIAL (decl) = init; > > + if (attrs) > + cplus_decl_attributes (&decl, attrs, 0); > + > set_originating_module (decl, false); > > /* Push the enclosing template. */ > --- gcc/cp/constraint.cc.jj 2022-11-04 05:11:41.491946435 -1200 > +++ gcc/cp/constraint.cc 2022-11-13 22:24:55.314809969 -1200 > @@ -1396,6 +1396,8 @@ build_standard_check (tree tmpl, tree ar > { > gcc_assert (standard_concept_p (tmpl)); > gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); > + if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl))) > + warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE); > tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl)); > args = coerce_template_parms (parms, args, tmpl, complain); > if (args == error_mark_node) > --- gcc/cp/tree.cc.jj 2022-11-08 22:39:13.318041103 -1200 > +++ gcc/cp/tree.cc 2022-11-13 21:51:21.851186254 -1200 > @@ -6103,6 +6103,14 @@ c_register_addr_space (const char * /*wo > { > } > > +/* Return true if CODE is CONCEPT_DECL. */ > + > +bool > +c_concept_decl (enum tree_code code) > +{ > + return code == CONCEPT_DECL; > +} > + > /* Return the number of operands in T that we care about for things like > mangling. */ > > --- gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C.jj 2022-11-13 22:27:56.977337907 -1200 > +++ gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C 2022-11-13 22:28:07.767191065 -1200 > @@ -0,0 +1,22 @@ > +// DR 2428 > +// { dg-do compile { target c++20 } } > + > +template<typename T> > +concept C1 [[deprecated]] = true; > + > +template<typename T> > +concept C2 __attribute__((deprecated)) = false; > + > +template<typename T> > +concept C3 [[deprecated]] = true; > + > +template<typename T> > +concept C4 __attribute__((deprecated)) = false; > + > +static_assert(C3<int>); // { dg-warning "'C3' is deprecated" } > +static_assert(C4<int>); // { dg-error "static assertion failed" } > + // { dg-warning "'C4' is deprecated" "" { target *-*-* } .-1 } > + > +template<typename T> > + requires C3<T> // { dg-warning "'C3' is deprecated" } > +int fn1(T t) { return 0; } > > Jakub >
On Mon, Nov 14, 2022 at 07:00:54PM -0500, Jason Merrill wrote: > > The following patch adds parsing of attributes to concept definition, > > allows deprecated attribute to be specified (some ugliness needed > > because CONCEPT_DECL is a cp/*.def attribute and so can't be mentioned > > in c-family/ directly; used what is used for objc method decls, > > an alternative would be a langhook) > > Several of the codes in c-common.def are C++-only, you might just move it > over? > > > and checks TREE_DEPRECATED in > > build_standard_check (not sure if that is the right spot, or whether > > it shouldn't be checked also for variable and function concepts and > > how to write testcase coverage for that). > > I wouldn't bother with var/fn concepts, they're obsolete. Ok, so like this? The previous version passed bootstrap/regtest on x86_64-linux and i686-linux, I'll of course test this one as well. Jakub
On Tue, Nov 15, 2022 at 09:54:00AM +0100, Jakub Jelinek via Gcc-patches wrote: > On Mon, Nov 14, 2022 at 07:00:54PM -0500, Jason Merrill wrote: > > > The following patch adds parsing of attributes to concept definition, > > > allows deprecated attribute to be specified (some ugliness needed > > > because CONCEPT_DECL is a cp/*.def attribute and so can't be mentioned > > > in c-family/ directly; used what is used for objc method decls, > > > an alternative would be a langhook) > > > > Several of the codes in c-common.def are C++-only, you might just move it > > over? > > > > > and checks TREE_DEPRECATED in > > > build_standard_check (not sure if that is the right spot, or whether > > > it shouldn't be checked also for variable and function concepts and > > > how to write testcase coverage for that). > > > > I wouldn't bother with var/fn concepts, they're obsolete. > > Ok, so like this? > The previous version passed bootstrap/regtest on x86_64-linux and i686-linux, > I'll of course test this one as well. Better with a patch. Sorry. 2022-11-15 Jakub Jelinek <jakub@redhat.com> gcc/c-family/ * c-common.def (CONCEPT_DECL): New tree, moved here from cp-tree.def. * c-common.cc (c_common_init_ts): Handle CONCEPT_DECL. * c-attribs.cc (handle_deprecated_attribute): Allow deprecated attribute on CONCEPT_DECL. gcc/cp/ * cp-tree.def (CONCEPT_DECL): Move to c-common.def. * cp-objcp-common.cc (cp_common_init_ts): Don't handle CONCEPT_DECL here. * cp-tree.h (finish_concept_definition): Add ATTRS parameter. * parser.cc (cp_parser_concept_definition): Parse attributes in between identifier and =. Adjust finish_concept_definition caller. * pt.cc (finish_concept_definition): Add ATTRS parameter. Call cplus_decl_attributes. * constraint.cc (build_standard_check): If CONCEPT_DECL is TREE_DEPRECATED, emit -Wdeprecated-declaration warnings. gcc/testsuite/ * g++.dg/cpp2a/concepts-dr2428.C: New test. --- gcc/c-family/c-common.def.jj 2022-10-14 09:28:27.975164491 +0200 +++ gcc/c-family/c-common.def 2022-11-15 09:34:01.384591076 +0100 @@ -81,6 +81,14 @@ DEFTREECODE (CONTINUE_STMT, "continue_st SWITCH_STMT_SCOPE, respectively. */ DEFTREECODE (SWITCH_STMT, "switch_stmt", tcc_statement, 4) +/* Extensions for C++ Concepts. */ + +/* Concept definition. This is not entirely different than a VAR_DECL + except that a) it must be a template, and b) doesn't have the wide + range of value and linkage options available to variables. Used + by C++ FE and in c-family attribute handling. */ +DEFTREECODE (CONCEPT_DECL, "concept_decl", tcc_declaration, 0) + /* Local variables: mode:c --- gcc/c-family/c-common.cc.jj 2022-11-13 12:29:08.165504692 +0100 +++ gcc/c-family/c-common.cc 2022-11-15 09:34:48.828950083 +0100 @@ -8497,6 +8497,8 @@ c_common_init_ts (void) MARK_TS_EXP (FOR_STMT); MARK_TS_EXP (SWITCH_STMT); MARK_TS_EXP (WHILE_STMT); + + MARK_TS_DECL_COMMON (CONCEPT_DECL); } /* Build a user-defined numeric literal out of an integer constant type VALUE --- gcc/c-family/c-attribs.cc.jj 2022-11-14 13:35:34.184160348 +0100 +++ gcc/c-family/c-attribs.cc 2022-11-15 09:30:57.370081060 +0100 @@ -4211,7 +4211,8 @@ handle_deprecated_attribute (tree *node, || VAR_OR_FUNCTION_DECL_P (decl) || TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == CONST_DECL - || objc_method_decl (TREE_CODE (decl))) + || objc_method_decl (TREE_CODE (decl)) + || TREE_CODE (decl) == CONCEPT_DECL) TREE_DEPRECATED (decl) = 1; else if (TREE_CODE (decl) == LABEL_DECL) { --- gcc/cp/cp-tree.def.jj 2022-09-29 18:11:34.836666800 +0200 +++ gcc/cp/cp-tree.def 2022-11-15 09:32:17.456996090 +0100 @@ -495,11 +495,6 @@ DEFTREECODE (OMP_DEPOBJ, "omp_depobj", t /* Extensions for Concepts. */ -/* Concept definition. This is not entirely different than a VAR_DECL - except that a) it must be a template, and b) doesn't have the wide - range of value and linkage options available to variables. */ -DEFTREECODE (CONCEPT_DECL, "concept_decl", tcc_declaration, 0) - /* Used to represent information associated with constrained declarations. */ DEFTREECODE (CONSTRAINT_INFO, "constraint_info", tcc_exceptional, 0) --- gcc/cp/cp-objcp-common.cc.jj 2022-09-30 18:38:55.349607203 +0200 +++ gcc/cp/cp-objcp-common.cc 2022-11-15 09:34:21.963313049 +0100 @@ -473,7 +473,6 @@ cp_common_init_ts (void) /* New decls. */ MARK_TS_DECL_COMMON (TEMPLATE_DECL); MARK_TS_DECL_COMMON (WILDCARD_DECL); - MARK_TS_DECL_COMMON (CONCEPT_DECL); MARK_TS_DECL_NON_COMMON (USING_DECL); --- gcc/cp/cp-tree.h.jj 2022-11-15 08:17:07.561388452 +0100 +++ gcc/cp/cp-tree.h 2022-11-15 09:30:57.371081046 +0100 @@ -8324,7 +8324,7 @@ struct diagnosing_failed_constraint extern cp_expr finish_constraint_or_expr (location_t, cp_expr, cp_expr); extern cp_expr finish_constraint_and_expr (location_t, cp_expr, cp_expr); extern cp_expr finish_constraint_primary_expr (cp_expr); -extern tree finish_concept_definition (cp_expr, tree); +extern tree finish_concept_definition (cp_expr, tree, tree); extern tree combine_constraint_expressions (tree, tree); extern tree append_constraint (tree, tree); extern tree get_constraints (const_tree); --- gcc/cp/parser.cc.jj 2022-11-14 13:35:34.380157682 +0100 +++ gcc/cp/parser.cc 2022-11-15 09:30:57.377080965 +0100 @@ -29672,6 +29672,8 @@ cp_parser_concept_definition (cp_parser return NULL_TREE; } + tree attrs = cp_parser_attributes_opt (parser); + if (!cp_parser_require (parser, CPP_EQ, RT_EQ)) { cp_parser_skip_to_end_of_statement (parser); @@ -29688,7 +29690,7 @@ cp_parser_concept_definition (cp_parser but continue as if it were. */ cp_parser_consume_semicolon_at_end_of_statement (parser); - return finish_concept_definition (id, init); + return finish_concept_definition (id, init, attrs); } // -------------------------------------------------------------------------- // --- gcc/cp/constraint.cc.jj 2022-11-14 13:35:34.269159192 +0100 +++ gcc/cp/constraint.cc 2022-11-15 09:30:57.382080897 +0100 @@ -1396,6 +1396,8 @@ build_standard_check (tree tmpl, tree ar { gcc_assert (standard_concept_p (tmpl)); gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); + if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl))) + warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE); tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl)); args = coerce_template_parms (parms, args, tmpl, complain); if (args == error_mark_node) --- gcc/cp/pt.cc.jj 2022-11-15 07:56:05.130350281 +0100 +++ gcc/cp/pt.cc 2022-11-15 09:30:57.381080911 +0100 @@ -29030,7 +29030,7 @@ placeholder_type_constraint_dependent_p the TEMPLATE_DECL. */ tree -finish_concept_definition (cp_expr id, tree init) +finish_concept_definition (cp_expr id, tree init, tree attrs) { gcc_assert (identifier_p (id)); gcc_assert (processing_template_decl); @@ -29064,6 +29064,9 @@ finish_concept_definition (cp_expr id, t DECL_CONTEXT (decl) = current_scope (); DECL_INITIAL (decl) = init; + if (attrs) + cplus_decl_attributes (&decl, attrs, 0); + set_originating_module (decl, false); /* Push the enclosing template. */ --- gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C.jj 2022-11-15 09:30:57.382080897 +0100 +++ gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C 2022-11-15 09:30:57.382080897 +0100 @@ -0,0 +1,22 @@ +// DR 2428 +// { dg-do compile { target c++20 } } + +template<typename T> +concept C1 [[deprecated]] = true; + +template<typename T> +concept C2 __attribute__((deprecated)) = false; + +template<typename T> +concept C3 [[deprecated]] = true; + +template<typename T> +concept C4 __attribute__((deprecated)) = false; + +static_assert(C3<int>); // { dg-warning "'C3' is deprecated" } +static_assert(C4<int>); // { dg-error "static assertion failed" } + // { dg-warning "'C4' is deprecated" "" { target *-*-* } .-1 } + +template<typename T> + requires C3<T> // { dg-warning "'C3' is deprecated" } +int fn1(T t) { return 0; } Jakub
On 11/14/22 22:54, Jakub Jelinek wrote: > On Tue, Nov 15, 2022 at 09:54:00AM +0100, Jakub Jelinek via Gcc-patches wrote: >> On Mon, Nov 14, 2022 at 07:00:54PM -0500, Jason Merrill wrote: >>>> The following patch adds parsing of attributes to concept definition, >>>> allows deprecated attribute to be specified (some ugliness needed >>>> because CONCEPT_DECL is a cp/*.def attribute and so can't be mentioned >>>> in c-family/ directly; used what is used for objc method decls, >>>> an alternative would be a langhook) >>> >>> Several of the codes in c-common.def are C++-only, you might just move it >>> over? >>> >>>> and checks TREE_DEPRECATED in >>>> build_standard_check (not sure if that is the right spot, or whether >>>> it shouldn't be checked also for variable and function concepts and >>>> how to write testcase coverage for that). >>> >>> I wouldn't bother with var/fn concepts, they're obsolete. >> >> Ok, so like this? >> The previous version passed bootstrap/regtest on x86_64-linux and i686-linux, >> I'll of course test this one as well. > > Better with a patch. Sorry. OK. > 2022-11-15 Jakub Jelinek <jakub@redhat.com> > > gcc/c-family/ > * c-common.def (CONCEPT_DECL): New tree, moved here from > cp-tree.def. > * c-common.cc (c_common_init_ts): Handle CONCEPT_DECL. > * c-attribs.cc (handle_deprecated_attribute): Allow deprecated > attribute on CONCEPT_DECL. > gcc/cp/ > * cp-tree.def (CONCEPT_DECL): Move to c-common.def. > * cp-objcp-common.cc (cp_common_init_ts): Don't handle CONCEPT_DECL > here. > * cp-tree.h (finish_concept_definition): Add ATTRS parameter. > * parser.cc (cp_parser_concept_definition): Parse attributes in > between identifier and =. Adjust finish_concept_definition > caller. > * pt.cc (finish_concept_definition): Add ATTRS parameter. Call > cplus_decl_attributes. > * constraint.cc (build_standard_check): If CONCEPT_DECL is > TREE_DEPRECATED, emit -Wdeprecated-declaration warnings. > gcc/testsuite/ > * g++.dg/cpp2a/concepts-dr2428.C: New test. > > --- gcc/c-family/c-common.def.jj 2022-10-14 09:28:27.975164491 +0200 > +++ gcc/c-family/c-common.def 2022-11-15 09:34:01.384591076 +0100 > @@ -81,6 +81,14 @@ DEFTREECODE (CONTINUE_STMT, "continue_st > SWITCH_STMT_SCOPE, respectively. */ > DEFTREECODE (SWITCH_STMT, "switch_stmt", tcc_statement, 4) > > +/* Extensions for C++ Concepts. */ > + > +/* Concept definition. This is not entirely different than a VAR_DECL > + except that a) it must be a template, and b) doesn't have the wide > + range of value and linkage options available to variables. Used > + by C++ FE and in c-family attribute handling. */ > +DEFTREECODE (CONCEPT_DECL, "concept_decl", tcc_declaration, 0) > + > /* > Local variables: > mode:c > --- gcc/c-family/c-common.cc.jj 2022-11-13 12:29:08.165504692 +0100 > +++ gcc/c-family/c-common.cc 2022-11-15 09:34:48.828950083 +0100 > @@ -8497,6 +8497,8 @@ c_common_init_ts (void) > MARK_TS_EXP (FOR_STMT); > MARK_TS_EXP (SWITCH_STMT); > MARK_TS_EXP (WHILE_STMT); > + > + MARK_TS_DECL_COMMON (CONCEPT_DECL); > } > > /* Build a user-defined numeric literal out of an integer constant type VALUE > --- gcc/c-family/c-attribs.cc.jj 2022-11-14 13:35:34.184160348 +0100 > +++ gcc/c-family/c-attribs.cc 2022-11-15 09:30:57.370081060 +0100 > @@ -4211,7 +4211,8 @@ handle_deprecated_attribute (tree *node, > || VAR_OR_FUNCTION_DECL_P (decl) > || TREE_CODE (decl) == FIELD_DECL > || TREE_CODE (decl) == CONST_DECL > - || objc_method_decl (TREE_CODE (decl))) > + || objc_method_decl (TREE_CODE (decl)) > + || TREE_CODE (decl) == CONCEPT_DECL) > TREE_DEPRECATED (decl) = 1; > else if (TREE_CODE (decl) == LABEL_DECL) > { > --- gcc/cp/cp-tree.def.jj 2022-09-29 18:11:34.836666800 +0200 > +++ gcc/cp/cp-tree.def 2022-11-15 09:32:17.456996090 +0100 > @@ -495,11 +495,6 @@ DEFTREECODE (OMP_DEPOBJ, "omp_depobj", t > > /* Extensions for Concepts. */ > > -/* Concept definition. This is not entirely different than a VAR_DECL > - except that a) it must be a template, and b) doesn't have the wide > - range of value and linkage options available to variables. */ > -DEFTREECODE (CONCEPT_DECL, "concept_decl", tcc_declaration, 0) > - > /* Used to represent information associated with constrained declarations. */ > DEFTREECODE (CONSTRAINT_INFO, "constraint_info", tcc_exceptional, 0) > > --- gcc/cp/cp-objcp-common.cc.jj 2022-09-30 18:38:55.349607203 +0200 > +++ gcc/cp/cp-objcp-common.cc 2022-11-15 09:34:21.963313049 +0100 > @@ -473,7 +473,6 @@ cp_common_init_ts (void) > /* New decls. */ > MARK_TS_DECL_COMMON (TEMPLATE_DECL); > MARK_TS_DECL_COMMON (WILDCARD_DECL); > - MARK_TS_DECL_COMMON (CONCEPT_DECL); > > MARK_TS_DECL_NON_COMMON (USING_DECL); > > --- gcc/cp/cp-tree.h.jj 2022-11-15 08:17:07.561388452 +0100 > +++ gcc/cp/cp-tree.h 2022-11-15 09:30:57.371081046 +0100 > @@ -8324,7 +8324,7 @@ struct diagnosing_failed_constraint > extern cp_expr finish_constraint_or_expr (location_t, cp_expr, cp_expr); > extern cp_expr finish_constraint_and_expr (location_t, cp_expr, cp_expr); > extern cp_expr finish_constraint_primary_expr (cp_expr); > -extern tree finish_concept_definition (cp_expr, tree); > +extern tree finish_concept_definition (cp_expr, tree, tree); > extern tree combine_constraint_expressions (tree, tree); > extern tree append_constraint (tree, tree); > extern tree get_constraints (const_tree); > --- gcc/cp/parser.cc.jj 2022-11-14 13:35:34.380157682 +0100 > +++ gcc/cp/parser.cc 2022-11-15 09:30:57.377080965 +0100 > @@ -29672,6 +29672,8 @@ cp_parser_concept_definition (cp_parser > return NULL_TREE; > } > > + tree attrs = cp_parser_attributes_opt (parser); > + > if (!cp_parser_require (parser, CPP_EQ, RT_EQ)) > { > cp_parser_skip_to_end_of_statement (parser); > @@ -29688,7 +29690,7 @@ cp_parser_concept_definition (cp_parser > but continue as if it were. */ > cp_parser_consume_semicolon_at_end_of_statement (parser); > > - return finish_concept_definition (id, init); > + return finish_concept_definition (id, init, attrs); > } > > // -------------------------------------------------------------------------- // > --- gcc/cp/constraint.cc.jj 2022-11-14 13:35:34.269159192 +0100 > +++ gcc/cp/constraint.cc 2022-11-15 09:30:57.382080897 +0100 > @@ -1396,6 +1396,8 @@ build_standard_check (tree tmpl, tree ar > { > gcc_assert (standard_concept_p (tmpl)); > gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); > + if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl))) > + warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE); > tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl)); > args = coerce_template_parms (parms, args, tmpl, complain); > if (args == error_mark_node) > --- gcc/cp/pt.cc.jj 2022-11-15 07:56:05.130350281 +0100 > +++ gcc/cp/pt.cc 2022-11-15 09:30:57.381080911 +0100 > @@ -29030,7 +29030,7 @@ placeholder_type_constraint_dependent_p > the TEMPLATE_DECL. */ > > tree > -finish_concept_definition (cp_expr id, tree init) > +finish_concept_definition (cp_expr id, tree init, tree attrs) > { > gcc_assert (identifier_p (id)); > gcc_assert (processing_template_decl); > @@ -29064,6 +29064,9 @@ finish_concept_definition (cp_expr id, t > DECL_CONTEXT (decl) = current_scope (); > DECL_INITIAL (decl) = init; > > + if (attrs) > + cplus_decl_attributes (&decl, attrs, 0); > + > set_originating_module (decl, false); > > /* Push the enclosing template. */ > --- gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C.jj 2022-11-15 09:30:57.382080897 +0100 > +++ gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C 2022-11-15 09:30:57.382080897 +0100 > @@ -0,0 +1,22 @@ > +// DR 2428 > +// { dg-do compile { target c++20 } } > + > +template<typename T> > +concept C1 [[deprecated]] = true; > + > +template<typename T> > +concept C2 __attribute__((deprecated)) = false; > + > +template<typename T> > +concept C3 [[deprecated]] = true; > + > +template<typename T> > +concept C4 __attribute__((deprecated)) = false; > + > +static_assert(C3<int>); // { dg-warning "'C3' is deprecated" } > +static_assert(C4<int>); // { dg-error "static assertion failed" } > + // { dg-warning "'C4' is deprecated" "" { target *-*-* } .-1 } > + > +template<typename T> > + requires C3<T> // { dg-warning "'C3' is deprecated" } > +int fn1(T t) { return 0; } > > > Jakub >
--- gcc/c-family/c-common.h.jj 2022-10-27 21:00:53.698247586 -1200 +++ gcc/c-family/c-common.h 2022-11-13 21:49:37.934598359 -1200 @@ -831,6 +831,7 @@ extern tree (*make_fname_decl) (location /* In c-decl.cc and cp/tree.cc. FIXME. */ extern void c_register_addr_space (const char *str, addr_space_t as); +extern bool c_concept_decl (enum tree_code); /* In c-common.cc. */ extern bool in_late_binary_op; --- gcc/c-family/c-attribs.cc.jj 2022-10-09 19:31:57.177988375 -1200 +++ gcc/c-family/c-attribs.cc 2022-11-13 21:52:37.920152731 -1200 @@ -4211,7 +4211,8 @@ handle_deprecated_attribute (tree *node, || VAR_OR_FUNCTION_DECL_P (decl) || TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == CONST_DECL - || objc_method_decl (TREE_CODE (decl))) + || objc_method_decl (TREE_CODE (decl)) + || (flag_concepts && c_concept_decl (TREE_CODE (decl)))) TREE_DEPRECATED (decl) = 1; else if (TREE_CODE (decl) == LABEL_DECL) { --- gcc/c/c-decl.cc.jj 2022-11-12 23:29:08.181504470 -1200 +++ gcc/c/c-decl.cc 2022-11-13 21:50:38.178779716 -1200 @@ -12987,6 +12987,14 @@ c_register_addr_space (const char *word, ridpointers [rid] = id; } +/* C doesn't have CONCEPT_DECL. */ + +bool +c_concept_decl (enum tree_code) +{ + return false; +} + /* Return identifier to look up for omp declare reduction. */ tree --- gcc/cp/cp-tree.h.jj 2022-11-11 20:30:10.138056914 -1200 +++ gcc/cp/cp-tree.h 2022-11-13 20:58:39.443218815 -1200 @@ -8324,7 +8324,7 @@ struct diagnosing_failed_constraint extern cp_expr finish_constraint_or_expr (location_t, cp_expr, cp_expr); extern cp_expr finish_constraint_and_expr (location_t, cp_expr, cp_expr); extern cp_expr finish_constraint_primary_expr (cp_expr); -extern tree finish_concept_definition (cp_expr, tree); +extern tree finish_concept_definition (cp_expr, tree, tree); extern tree combine_constraint_expressions (tree, tree); extern tree append_constraint (tree, tree); extern tree get_constraints (const_tree); --- gcc/cp/parser.cc.jj 2022-11-08 22:39:13.325041007 -1200 +++ gcc/cp/parser.cc 2022-11-13 20:58:15.692542640 -1200 @@ -29672,6 +29672,8 @@ cp_parser_concept_definition (cp_parser return NULL_TREE; } + tree attrs = cp_parser_attributes_opt (parser); + if (!cp_parser_require (parser, CPP_EQ, RT_EQ)) { cp_parser_skip_to_end_of_statement (parser); @@ -29688,7 +29690,7 @@ cp_parser_concept_definition (cp_parser but continue as if it were. */ cp_parser_consume_semicolon_at_end_of_statement (parser); - return finish_concept_definition (id, init); + return finish_concept_definition (id, init, attrs); } // -------------------------------------------------------------------------- // --- gcc/cp/pt.cc.jj 2022-11-07 20:54:37.341399829 -1200 +++ gcc/cp/pt.cc 2022-11-13 21:01:18.333053377 -1200 @@ -29027,7 +29027,7 @@ placeholder_type_constraint_dependent_p the TEMPLATE_DECL. */ tree -finish_concept_definition (cp_expr id, tree init) +finish_concept_definition (cp_expr id, tree init, tree attrs) { gcc_assert (identifier_p (id)); gcc_assert (processing_template_decl); @@ -29061,6 +29061,9 @@ finish_concept_definition (cp_expr id, t DECL_CONTEXT (decl) = current_scope (); DECL_INITIAL (decl) = init; + if (attrs) + cplus_decl_attributes (&decl, attrs, 0); + set_originating_module (decl, false); /* Push the enclosing template. */ --- gcc/cp/constraint.cc.jj 2022-11-04 05:11:41.491946435 -1200 +++ gcc/cp/constraint.cc 2022-11-13 22:24:55.314809969 -1200 @@ -1396,6 +1396,8 @@ build_standard_check (tree tmpl, tree ar { gcc_assert (standard_concept_p (tmpl)); gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); + if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl))) + warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE); tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl)); args = coerce_template_parms (parms, args, tmpl, complain); if (args == error_mark_node) --- gcc/cp/tree.cc.jj 2022-11-08 22:39:13.318041103 -1200 +++ gcc/cp/tree.cc 2022-11-13 21:51:21.851186254 -1200 @@ -6103,6 +6103,14 @@ c_register_addr_space (const char * /*wo { } +/* Return true if CODE is CONCEPT_DECL. */ + +bool +c_concept_decl (enum tree_code code) +{ + return code == CONCEPT_DECL; +} + /* Return the number of operands in T that we care about for things like mangling. */ --- gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C.jj 2022-11-13 22:27:56.977337907 -1200 +++ gcc/testsuite/g++.dg/cpp2a/concepts-dr2428.C 2022-11-13 22:28:07.767191065 -1200 @@ -0,0 +1,22 @@ +// DR 2428 +// { dg-do compile { target c++20 } } + +template<typename T> +concept C1 [[deprecated]] = true; + +template<typename T> +concept C2 __attribute__((deprecated)) = false; + +template<typename T> +concept C3 [[deprecated]] = true; + +template<typename T> +concept C4 __attribute__((deprecated)) = false; + +static_assert(C3<int>); // { dg-warning "'C3' is deprecated" } +static_assert(C4<int>); // { dg-error "static assertion failed" } + // { dg-warning "'C4' is deprecated" "" { target *-*-* } .-1 } + +template<typename T> + requires C3<T> // { dg-warning "'C3' is deprecated" } +int fn1(T t) { return 0; }