On Fri, Dec 12, 2025 at 12:59:17PM +0100, Jakub Jelinek wrote:
> I can do C++ FE next.

Here is the C++ FE counterpart of that.

2025-12-12  Jakub Jelinek  <[email protected]>

        * parser.cc (cp_parser_omp_clause_reduction): Provide fixit hints
        for -Wdeprecated-openmp diagnostics.
        (cp_parser_omp_clause_linear): Likewise.
        (cp_parser_omp_clause_depend): Likewise.
        (cp_parser_omp_clause_map): Likewise.  Reset num_commas after the
        diagnostics.
        (cp_parser_omp_clause_proc_bind): Provide fixit hints for
        -Wdeprecated-openmp diagnostics.
        (cp_parser_omp_all_clauses): Move -Wdeprecated-openmp diagnostics
        for to vs. enter here, add fixit hints for it.
        (cp_parser_omp_master):Add MASTER_LOC argument.  Provide fixit hints
        for -Wdeprecated-openmp diagnostics.
        (cp_parser_omp_parallel): Adjust cp_parser_omp_master caller.
        (cp_parser_omp_declare_target): Don't emit -Wdeprecated-openmp
        warning for to vs. enter here.
        (cp_parser_omp_metadirective): Provide fixit hints for
        -Wdeprecated-openmp diagnostics.
        (cp_parser_omp_construct): Adjust cp_parser_omp_master caller.

        * g++.dg/gomp/deprecate-1.C: New test.

--- gcc/cp/parser.cc.jj 2025-12-11 21:29:28.619228145 +0100
+++ gcc/cp/parser.cc    2025-12-12 14:56:02.436527569 +0100
@@ -42166,9 +42166,14 @@ cp_parser_omp_clause_reduction (cp_parse
     case CPP_MULT: code = MULT_EXPR; break;
     case CPP_MINUS:
       if (is_omp)
-       warning_at (cp_lexer_peek_token (parser->lexer)->location,
-                   OPT_Wdeprecated_openmp,
-                   "%<-%> operator for reductions deprecated in OpenMP 5.2");
+       {
+         location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+         gcc_rich_location richloc (loc);
+         richloc.add_fixit_replace ("+");
+         warning_at (&richloc, OPT_Wdeprecated_openmp,
+                     "%<-%> operator for reductions deprecated in "
+                     "OpenMP 5.2");
+       }
       code = MINUS_EXPR;
       break;
     case CPP_AND: code = BIT_AND_EXPR; break;
@@ -42846,6 +42851,9 @@ cp_parser_omp_clause_linear (cp_parser *
   bool colon;
   enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
   bool old_linear_modifier = false;
+  location_t mod_loc = UNKNOWN_LOCATION, after_colon_loc = UNKNOWN_LOCATION;
+  location_t rm1_loc = UNKNOWN_LOCATION, rm2_loc = UNKNOWN_LOCATION;
+  location_t close_loc = UNKNOWN_LOCATION;
 
   matching_parens parens;
   if (!parens.require_open (parser))
@@ -42864,12 +42872,12 @@ cp_parser_omp_clause_linear (cp_parser *
        kind = OMP_CLAUSE_LINEAR_UVAL;
       if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
        {
+         mod_loc = cp_lexer_peek_token (parser->lexer)->location;
+         rm1_loc = make_location (mod_loc, mod_loc,
+                                  cp_lexer_peek_nth_token (parser->lexer,
+                                                           2)->location);
          cp_lexer_consume_token (parser->lexer);
          old_linear_modifier = true;
-         warning_at (cp_lexer_peek_token (parser->lexer)->location,
-                     OPT_Wdeprecated_openmp,
-                     "specifying the list items as arguments to the "
-                     "modifiers is deprecated since OpenMP 5.2");
        }
       else
        kind = OMP_CLAUSE_LINEAR_DEFAULT;
@@ -42880,8 +42888,20 @@ cp_parser_omp_clause_linear (cp_parser *
                                            &colon);
   else
     {
+      size_t end = cp_parser_skip_balanced_tokens (parser, 1);
+      cp_token *next = UNKNOWN_LOCATION;
+      if (end > 1
+         && cp_lexer_nth_token_is (parser->lexer, end - 1, CPP_CLOSE_PAREN))
+       {
+         rm2_loc = cp_lexer_peek_nth_token (parser->lexer, end - 1)->location;
+         next = cp_lexer_peek_nth_token (parser->lexer, end);
+       }
       nlist = cp_parser_omp_var_list (parser, OMP_CLAUSE_LINEAR, list);
+      if (next && cp_lexer_peek_token (parser->lexer) != next)
+       rm2_loc = UNKNOWN_LOCATION;
       colon = cp_lexer_next_token_is (parser->lexer, CPP_COLON);
+      if (!colon && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
+       close_loc = cp_lexer_peek_token (parser->lexer)->location;
       if (colon)
        cp_parser_require (parser, CPP_COLON, RT_COLON);
       else if (!parens.require_close (parser))
@@ -42997,6 +43017,7 @@ cp_parser_omp_clause_linear (cp_parser *
               && cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN))
        {
          cp_token *token = cp_lexer_peek_token (parser->lexer);
+         after_colon_loc = token->location;
          cp_parser_parse_tentatively (parser);
          step = cp_parser_id_expression (parser, /*template_p=*/false,
                                          /*check_dependency_p=*/true,
@@ -43014,7 +43035,13 @@ cp_parser_omp_clause_linear (cp_parser *
            step = NULL_TREE;
        }
       if (!step)
-       step = cp_parser_assignment_expression (parser);
+       {
+         after_colon_loc = cp_lexer_peek_token (parser->lexer)->location;
+         step = cp_parser_assignment_expression (parser);
+       }
+
+      if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
+       close_loc = cp_lexer_peek_token (parser->lexer)->location;
 
       if (!parens.require_close (parser))
        cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
@@ -43032,6 +43059,42 @@ cp_parser_omp_clause_linear (cp_parser *
       OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
     }
 
+  if (old_linear_modifier)
+    {
+      gcc_rich_location richloc (mod_loc);
+      if (rm2_loc != UNKNOWN_LOCATION && close_loc != UNKNOWN_LOCATION)
+       {
+         richloc.add_fixit_remove (rm1_loc);
+         if (after_colon_loc != UNKNOWN_LOCATION)
+           {
+             richloc.add_fixit_remove (rm2_loc);
+             if (kind == OMP_CLAUSE_LINEAR_REF)
+               richloc.add_fixit_insert_before (after_colon_loc,
+                                                "ref, step (");
+             else if (kind == OMP_CLAUSE_LINEAR_VAL)
+               richloc.add_fixit_insert_before (after_colon_loc,
+                                                "val, step (");
+             else if (kind == OMP_CLAUSE_LINEAR_UVAL)
+               richloc.add_fixit_insert_before (after_colon_loc,
+                                                "uval, step (");
+             else
+               gcc_unreachable ();
+             richloc.add_fixit_insert_before (close_loc, ")");
+           }
+         else if (kind == OMP_CLAUSE_LINEAR_REF)
+           richloc.add_fixit_replace (rm2_loc, " : ref");
+         else if (kind == OMP_CLAUSE_LINEAR_VAL)
+           richloc.add_fixit_replace (rm2_loc, " : val");
+         else if (kind == OMP_CLAUSE_LINEAR_UVAL)
+           richloc.add_fixit_replace (rm2_loc, " : uval");
+         else
+           gcc_unreachable ();
+       }
+      warning_at (&richloc, OPT_Wdeprecated_openmp,
+                 "specifying the list items as arguments to the "
+                 "modifiers is deprecated since OpenMP 5.2");
+    }
+
   return nlist;
 }
 
@@ -43480,14 +43543,18 @@ cp_parser_omp_clause_depend (cp_parser *
        kind = OMP_CLAUSE_DEPEND_DEPOBJ;
       else if (strcmp ("sink", p) == 0)
        {
-         warning_at (loc, OPT_Wdeprecated_openmp,
+         gcc_rich_location richloc (loc);
+         richloc.add_fixit_replace ("doacross");
+         warning_at (&richloc, OPT_Wdeprecated_openmp,
                      "%<sink%> modifier with %<depend%> clause deprecated "
                      "since OpenMP 5.2, use with %<doacross%>");
          dkind = OMP_CLAUSE_DOACROSS_SINK;
        }
       else if (strcmp ("source", p) == 0)
        {
-         warning_at (loc, OPT_Wdeprecated_openmp,
+         gcc_rich_location richloc (loc);
+         richloc.add_fixit_replace ("doacross");
+         warning_at (&richloc, OPT_Wdeprecated_openmp,
                      "%<source%> modifier with %<depend%> clause deprecated "
                      "since OpenMP 5.2, use with %<doacross%>");
          dkind = OMP_CLAUSE_DOACROSS_SOURCE;
@@ -44076,10 +44143,15 @@ cp_parser_omp_clause_map (cp_parser *par
          return list;
        }
       ++num_identifiers;
-      if (num_identifiers - 1 != num_commas)
-       warning_at (clause_loc, OPT_Wdeprecated_openmp,
-                   "%<map%> clause modifiers without comma separation is "
-                   "deprecated since OpenMP 5.2");
+      if (num_identifiers - 1 > num_commas)
+       {
+         gcc_rich_location richloc (clause_loc);
+         richloc.add_fixit_insert_before (tok->location, ",");
+         warning_at (&richloc, OPT_Wdeprecated_openmp,
+                     "%<map%> clause modifiers without comma separation is "
+                     "deprecated since OpenMP 5.2");
+       }
+      num_commas = num_identifiers - 1;
     }
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
@@ -44322,7 +44394,11 @@ cp_parser_omp_clause_proc_bind (cp_parse
        kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
       else if (strcmp ("master", p) == 0)
        {
-         warning_at (location, OPT_Wdeprecated_openmp,
+         gcc_rich_location richloc (location);
+         location_t master_loc
+           = cp_lexer_peek_token (parser->lexer)->location;
+         richloc.add_fixit_replace (master_loc, "primary");
+         warning_at (&richloc, OPT_Wdeprecated_openmp,
                      "%<master%> affinity deprecated since OpenMP 5.1, "
                      "use %<primary%>");
          kind = OMP_CLAUSE_PROC_BIND_MASTER;
@@ -45408,6 +45484,11 @@ cp_parser_omp_all_clauses (cp_parser *pa
        case PRAGMA_OMP_CLAUSE_TO:
          if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
            {
+             gcc_rich_location richloc (token->location);
+             richloc.add_fixit_replace ("enter");
+             warning_at (&richloc, OPT_Wdeprecated_openmp,
+                         "%<to%> clause with %<declare target%> deprecated "
+                         "since OpenMP 5.2, use %<enter%>");
              tree nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_ENTER,
                                                clauses);
              for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
@@ -49037,12 +49118,15 @@ static tree cp_parser_omp_taskloop (cp_p
 static tree
 cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok,
                      char *p_name, omp_clause_mask mask, tree *cclauses,
-                     bool *if_p)
+                     bool *if_p, location_t master_loc)
 {
   tree clauses, sb, ret;
   unsigned int save;
   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
-  warning_at (loc, OPT_Wdeprecated_openmp,
+  gcc_rich_location richloc (master_loc ? master_loc : loc);
+  if (master_loc != UNKNOWN_LOCATION)
+    richloc.add_fixit_replace (master_loc, "masked");
+  warning_at (&richloc, OPT_Wdeprecated_openmp,
              "%<master%> construct deprecated since OpenMP 5.1, use "
              "%<masked%>");
 
@@ -49416,6 +49500,7 @@ cp_parser_omp_parallel (cp_parser *parse
     {
       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
       const char *p = IDENTIFIER_POINTER (id);
+      location_t ploc = cp_lexer_peek_token (parser->lexer)->location;
       if (cclauses == NULL && strcmp (p, "masked") == 0)
        {
          tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
@@ -49454,11 +49539,11 @@ cp_parser_omp_parallel (cp_parser *parse
          cp_lexer_consume_token (parser->lexer);
          if (!flag_openmp)  /* flag_openmp_simd  */
            return cp_parser_omp_master (parser, pragma_tok, p_name, mask,
-                                        cclauses, if_p);
+                                        cclauses, if_p, ploc);
          block = begin_omp_parallel ();
          save = cp_parser_begin_omp_structured_block (parser);
          tree ret = cp_parser_omp_master (parser, pragma_tok, p_name, mask,
-                                          cclauses, if_p);
+                                          cclauses, if_p, ploc);
          cp_parser_end_omp_structured_block (parser, save);
          stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
                                      block);
@@ -52793,10 +52878,6 @@ cp_parser_omp_declare_target (cp_parser
     }
   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
     {
-      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER && OMP_CLAUSE_ENTER_TO (c))
-       warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wdeprecated_openmp,
-                   "%<to%> clause with %<declare target%> deprecated since "
-                   "OpenMP 5.2, use %<enter%>");
       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
        device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
@@ -53218,9 +53299,13 @@ cp_parser_omp_metadirective (cp_parser *
       const char *p
        = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
       if (strcmp (p, "default") == 0)
-       warning_at (match_loc, OPT_Wdeprecated_openmp,
-                   "%<default%> clause on metadirectives deprecated since "
-                   "OpenMP 5.2, use %<otherwise%>");
+       {
+         gcc_rich_location richloc (match_loc);
+         richloc.add_fixit_replace ("otherwise");
+         warning_at (&richloc, OPT_Wdeprecated_openmp,
+                     "%<default%> clause on metadirectives deprecated since "
+                     "OpenMP 5.2, use %<otherwise%>");
+       }
       cp_lexer_consume_token (parser->lexer);
       bool default_p
        = strcmp (p, "default") == 0 || strcmp (p, "otherwise") == 0;
@@ -55009,7 +55094,7 @@ cp_parser_omp_construct (cp_parser *pars
     case PRAGMA_OMP_MASTER:
       strcpy (p_name, "#pragma omp");
       stmt = cp_parser_omp_master (parser, pragma_tok, p_name, mask, NULL,
-                                  if_p);
+                                  if_p, UNKNOWN_LOCATION);
       break;
     case PRAGMA_OMP_PARALLEL:
       strcpy (p_name, "#pragma omp");
--- gcc/testsuite/g++.dg/gomp/deprecate-1.C.jj  2025-12-12 14:46:29.587393576 
+0100
+++ gcc/testsuite/g++.dg/gomp/deprecate-1.C     2025-12-12 15:09:10.568930826 
+0100
@@ -0,0 +1,124 @@
+/* { dg-additional-options "-fdiagnostics-show-caret -Wdeprecated-openmp" } */
+
+#pragma omp declare simd linear (val(a) : 1)   /* { dg-warning "specifying the 
list items as arguments to the modifiers is deprecated since OpenMP 5.2" } */
+/* { dg-begin-multiline-output "" }
+ #pragma omp declare simd linear (val(a) : 1)
+                                  ^~~
+                                  ---- -   -
+                                           val, step (1)
+   { dg-end-multiline-output "" } */
+#pragma omp declare simd linear (val(b))       /* { dg-warning "specifying the 
list items as arguments to the modifiers is deprecated since OpenMP 5.2" } */
+/* { dg-begin-multiline-output "" }
+ #pragma omp declare simd linear (val(b))
+                                  ^~~
+                                  ---- -
+                                        : val
+   { dg-end-multiline-output "" } */
+int foo (int a, int b);
+
+#pragma omp declare simd linear (ref(a) : 1)   /* { dg-warning "specifying the 
list items as arguments to the modifiers is deprecated since OpenMP 5.2" } */
+/* { dg-begin-multiline-output "" }
+ #pragma omp declare simd linear (ref(a) : 1)
+                                  ^~~
+                                  ---- -   -
+                                           ref, step (1)
+   { dg-end-multiline-output "" } */
+#pragma omp declare simd linear (ref(b))       /* { dg-warning "specifying the 
list items as arguments to the modifiers is deprecated since OpenMP 5.2" } */
+/* { dg-begin-multiline-output "" }
+ #pragma omp declare simd linear (ref(b))
+                                  ^~~
+                                  ---- -
+                                        : ref
+   { dg-end-multiline-output "" } */
+int baz (int &a, int &b);
+
+#pragma omp declare simd linear (uval(a) : 1)  /* { dg-warning "specifying the 
list items as arguments to the modifiers is deprecated since OpenMP 5.2" } */
+/* { dg-begin-multiline-output "" }
+ #pragma omp declare simd linear (uval(a) : 1)
+                                  ^~~~
+                                  ----- -   -
+                                            uval, step (1)
+   { dg-end-multiline-output "" } */
+#pragma omp declare simd linear (uval(b))      /* { dg-warning "specifying the 
list items as arguments to the modifiers is deprecated since OpenMP 5.2" } */
+/* { dg-begin-multiline-output "" }
+ #pragma omp declare simd linear (uval(b))
+                                  ^~~~
+                                  ----- -
+                                         : uval
+   { dg-end-multiline-output "" } */
+int qux (int &a, int &b);
+
+int v;
+#pragma omp declare target to (v)              /* { dg-warning "'to' clause 
with 'declare target' deprecated since OpenMP 5.2, use 'enter'" } */
+/* { dg-begin-multiline-output "" }
+ #pragma omp declare target to (v)
+                            ^~
+                            enter
+   { dg-end-multiline-output "" } */
+
+void
+bar ()
+{
+  int r = 0;
+  #pragma omp parallel reduction (-:r)         /* { dg-warning "'-' operator 
for reductions deprecated in OpenMP 5.2" } */
+/* { dg-begin-multiline-output "" }
+   #pragma omp parallel reduction (-:r)
+                                   ^
+                                   +
+   { dg-end-multiline-output "" } */
+  ++r;
+  #pragma omp for ordered (1)
+  for (int i = 0; i < 64; i++)
+    {
+      #pragma omp ordered depend (sink: i - 1) /* { dg-warning "'sink' 
modifier with 'depend' clause deprecated since OpenMP 5.2, use with 'doacross'" 
} */
+/* { dg-begin-multiline-output "" }
+       #pragma omp ordered depend (sink: i - 1)
+                           ^~~~~~
+                           doacross
+   { dg-end-multiline-output "" } */
+      #pragma omp ordered depend (source)      /* { dg-warning "'source' 
modifier with 'depend' clause deprecated since OpenMP 5.2, use with 'doacross'" 
} */
+/* { dg-begin-multiline-output "" }
+       #pragma omp ordered depend (source)
+                           ^~~~~~
+                           doacross
+   { dg-end-multiline-output "" } */
+    }
+  #pragma omp target map (always close present, tofrom: r)     /* { dg-warning 
"'map' clause modifiers without comma separation is deprecated since OpenMP 
5.2" } */
+/* { dg-begin-multiline-output "" }
+   #pragma omp target map (always close present, tofrom: r)
+                          ^
+                                  ,
+   #pragma omp target map (always close present, tofrom: r)
+                          ^
+                                        ,
+   { dg-end-multiline-output "" } */
+  ;
+  #pragma omp parallel proc_bind (master)      /* { dg-warning "'master' 
affinity deprecated since OpenMP 5.1, use 'primary'" } */
+/* { dg-begin-multiline-output "" }
+   #pragma omp parallel proc_bind (master)
+                        ^~~~~~~~~
+                                   ------
+                                   primary
+   { dg-end-multiline-output "" } */
+  ;
+  #pragma omp parallel master                  /* { dg-warning "'master' 
construct deprecated since OpenMP 5.1, use 'masked'" } */
+/* { dg-begin-multiline-output "" }
+   #pragma omp parallel master
+                        ^~~~~~
+                        masked
+   { dg-end-multiline-output "" } */
+  ;
+  #pragma omp master                           /* { dg-warning "'master' 
construct deprecated since OpenMP 5.1, use 'masked'" } */
+/* { dg-begin-multiline-output "" }
+   #pragma omp master
+                                                                               
                                                     ^
+   { dg-end-multiline-output "" } */
+  ;
+  #pragma omp metadirective when (device={arch("blahblah")}: nothing) default 
(nothing)                /* { dg-warning "'default' clause on metadirectives 
deprecated since OpenMP 5.2, use 'otherwise'" } */
+/* { dg-begin-multiline-output "" }
+   #pragma omp metadirective when (device={arch("blahblah")}: nothing) default 
(nothing)
+                                                                       ^~~~~~~
+                                                                       
otherwise
+   { dg-end-multiline-output "" } */
+  ;
+}


        Jakub

Reply via email to