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) 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).

Lightly tested so far.

2022-11-13  Jakub Jelinek  <ja...@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

Reply via email to