]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Provide fixit hints for -Wdeprecated-openmp diagnostics from C FE
authorJakub Jelinek <jakub@redhat.com>
Sat, 13 Dec 2025 09:01:30 +0000 (10:01 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 13 Dec 2025 09:01:30 +0000 (10:01 +0100)
I think especially the linear clause -Wdeprecated-openmp diagnostics
will be complete nightmare for users, when they have
linear (ref (x, y, z))
or
linear (uval (a, b, c) : 2)
they will have no clue what the new syntax is.

Here is a so far lightly tested attempt to provide fixit hints for most
of these warnings, and even -fdiagnostics-generate-patch can then be
useful for porting.
And so far I've done just the C FE.

Some issues:
1) I have no idea what to do about
or their attribute variants, for pragmas the location_t one gets is
the omp keyword, not master or declare, and there is no other location_t
easily available to add a fixit hint that master -> masked or
begin inserted before declare.  And for attributes I have no idea what
location_t we get there.  Note, for omp parallel master or omp parallel
master taskloop I do emit fixit hints.
2) I think there is a missing warning for
(similar case to reduction clause with - identifier)
3) I think the map clause diagnostics for missing comma separation
will not diagnose
just missing commas in between multiple modifiers (and I've fixed it
not to emit diagnostics multiple times if only one comma is missing,
e.g.
would I think diagnose missing comma twice.

2025-12-13  Jakub Jelinek  <jakub@redhat.com>

* c-parser.cc (c_parser_omp_clause_reduction): Provide fixit hints
for -Wdeprecated-openmp diagnostics.
(c_parser_omp_clause_linear): Likewise.
(c_parser_omp_clause_depend): Likewise.  Add HERE argument.
(c_parser_omp_clause_map): Provide fixit hints for -Wdeprecated-openmp
diagnostics.  Reset num_commas after the diagnostics.
(c_parser_omp_clause_proc_bind): Provide fixit hints for
-Wdeprecated-openmp diagnostics.
(c_parser_omp_all_clauses): Move -Wdeprecated-openmp diagnostics
for to vs. enter here, add fixit hints for it.  Adjust
c_parser_omp_clause_depend caller.
(c_parser_omp_depobj): Adjust c_parser_omp_clause_depend caller.
(c_parser_omp_master): Add MASTER_LOC argument.  Provide fixit hints
for -Wdeprecated-openmp diagnostics.
(c_parser_omp_parallel): Adjust c_parser_omp_master caller.
(c_parser_omp_declare_target): Don't emit -Wdeprecated-openmp
warning for to vs. enter here.
(c_parser_omp_metadirective): Provide fixit hints for
-Wdeprecated-openmp diagnostics.
(c_parser_omp_construct): Adjust c_parser_omp_master caller.

* c-c++-common/gomp/52-deps.c: Change locations of 2 warnings for C.
* gcc.dg/gomp/deprecate-1.c: New test.

gcc/c/c-parser.cc
gcc/testsuite/c-c++-common/gomp/52-deps.c
gcc/testsuite/gcc.dg/gomp/deprecate-1.c [new file with mode: 0644]

index 669af6573cae9e5bdf497792ae661fa5a6a5006b..6e3c7bea3bc8cd10dcbaa7a6e0b93c7434f6b802 100644 (file)
@@ -18852,10 +18852,14 @@ c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
          break;
        case CPP_MINUS:
          if (is_omp)
-           warning_at (c_parser_peek_token (parser)->location,
-                       OPT_Wdeprecated_openmp,
-                       "%<-%> operator for reductions deprecated in "
-                       "OpenMP 5.2");
+           {
+             location_t loc = c_parser_peek_token (parser)->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:
@@ -19813,6 +19817,8 @@ static tree
 c_parser_omp_clause_linear (c_parser *parser, tree list)
 {
   location_t clause_loc = c_parser_peek_token (parser)->location;
+  location_t rm1_loc = UNKNOWN_LOCATION, rm2_loc = UNKNOWN_LOCATION;
+  location_t after_colon_loc = UNKNOWN_LOCATION;
   tree nl, c, step;
   enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
   bool old_linear_modifier = false;
@@ -19831,10 +19837,9 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
        kind = OMP_CLAUSE_LINEAR_DEFAULT;
       if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
        {
-         warning_at (clause_loc, OPT_Wdeprecated_openmp,
-                     "specifying the list items as arguments to the "
-                     "modifiers is deprecated since OpenMP 5.2");
          old_linear_modifier = true;
+         rm1_loc = make_location (tok->location, tok->location,
+                                  c_parser_peek_2nd_token (parser)->location);
          c_parser_consume_token (parser);
          c_parser_consume_token (parser);
        }
@@ -19844,12 +19849,17 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
                                   OMP_CLAUSE_LINEAR, list);
 
   if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
-    parens.skip_until_found_close (parser);
+    {
+      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+       rm2_loc = c_parser_peek_token (parser)->location;
+      parens.skip_until_found_close (parser);
+    }
 
   if (c_parser_next_token_is (parser, CPP_COLON))
     {
       c_parser_consume_token (parser);
       location_t expr_loc = c_parser_peek_token (parser)->location;
+      after_colon_loc = expr_loc;
       bool has_modifiers = false;
       if (kind == OMP_CLAUSE_LINEAR_DEFAULT
          && c_parser_next_token_is (parser, CPP_NAME))
@@ -19952,6 +19962,27 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
       OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
     }
 
+  if (old_linear_modifier)
+    {
+      gcc_rich_location richloc (clause_loc);
+      if (rm2_loc != UNKNOWN_LOCATION)
+       {
+         richloc.add_fixit_remove (rm1_loc);
+         if (after_colon_loc != UNKNOWN_LOCATION)
+           {
+             richloc.add_fixit_remove (rm2_loc);
+             richloc.add_fixit_insert_before (after_colon_loc, "val, step (");
+             location_t close_loc = c_parser_peek_token (parser)->location;
+             richloc.add_fixit_insert_before (close_loc, ")");
+           }
+         else
+           richloc.add_fixit_replace (rm2_loc, " : val");
+       }
+      warning_at (&richloc, OPT_Wdeprecated_openmp,
+                 "specifying the list items as arguments to the "
+                 "modifiers is deprecated since OpenMP 5.2");
+    }
+
   parens.skip_until_found_close (parser);
   return nl;
 }
@@ -20334,7 +20365,7 @@ c_parser_omp_clause_affinity (c_parser *parser, tree list)
      iterator ( iterators-definition )  */
 
 static tree
-c_parser_omp_clause_depend (c_parser *parser, tree list)
+c_parser_omp_clause_depend (c_parser *parser, tree list, location_t here)
 {
   location_t clause_loc = c_parser_peek_token (parser)->location;
   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
@@ -20371,14 +20402,18 @@ c_parser_omp_clause_depend (c_parser *parser, tree list)
        kind = OMP_CLAUSE_DEPEND_DEPOBJ;
       else if (strcmp ("sink", p) == 0)
        {
-         warning_at (clause_loc, OPT_Wdeprecated_openmp,
+         gcc_rich_location richloc (clause_loc);
+         richloc.add_fixit_replace (here, "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 (clause_loc, OPT_Wdeprecated_openmp,
+         gcc_rich_location richloc (clause_loc);
+         richloc.add_fixit_replace (here, "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;
@@ -20812,10 +20847,15 @@ c_parser_omp_clause_map (c_parser *parser, tree list, bool declare_mapper_p)
          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 (c_parser_next_token_is (parser, CPP_NAME)
@@ -21059,7 +21099,10 @@ c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
        kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
       else if (strcmp ("master", p) == 0)
        {
-         warning_at (clause_loc, OPT_Wdeprecated_openmp,
+         gcc_rich_location richloc (clause_loc);
+         richloc.add_fixit_replace (c_parser_peek_token (parser)->location,
+                                    "primary");
+         warning_at (&richloc, OPT_Wdeprecated_openmp,
                      "%<master%> affinity deprecated since OpenMP 5.1, "
                      "use %<primary%>");
          kind = OMP_CLAUSE_PROC_BIND_MASTER;
@@ -22280,6 +22323,11 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
        case PRAGMA_OMP_CLAUSE_TO:
          if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
            {
+             gcc_rich_location richloc (here);
+             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 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
                                                      clauses);
              for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
@@ -22329,7 +22377,7 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
          c_name = "affinity";
          break;
        case PRAGMA_OMP_CLAUSE_DEPEND:
-         clauses = c_parser_omp_clause_depend (parser, clauses);
+         clauses = c_parser_omp_clause_depend (parser, clauses, here);
          c_name = "depend";
          break;
        case PRAGMA_OMP_CLAUSE_DOACROSS:
@@ -24540,7 +24588,7 @@ c_parser_omp_depobj (c_parser *parser)
       c_parser_consume_token (parser);
       if (!strcmp ("depend", p))
        {
-         clause = c_parser_omp_clause_depend (parser, NULL_TREE);
+         clause = c_parser_omp_clause_depend (parser, NULL_TREE, c_loc);
          clause = c_finish_omp_clauses (clause, C_ORT_OMP);
          if (!clause)
            clause = error_mark_node;
@@ -25683,12 +25731,15 @@ static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
 static tree
 c_parser_omp_master (location_t loc, c_parser *parser,
                     char *p_name, omp_clause_mask mask, tree *cclauses,
-                    bool *if_p)
+                    bool *if_p, location_t master_loc)
 {
-  warning_at (loc, OPT_Wdeprecated_openmp,
+  tree block, clauses, ret;
+  gcc_rich_location richloc (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%>");
-  tree block, clauses, ret;
 
   strcat (p_name, " master");
 
@@ -26102,6 +26153,7 @@ c_parser_omp_parallel (location_t loc, c_parser *parser,
   else if (c_parser_next_token_is (parser, CPP_NAME))
     {
       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+      location_t ploc = c_parser_peek_token (parser)->location;
       if (cclauses == NULL && strcmp (p, "masked") == 0)
        {
          tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
@@ -26139,10 +26191,10 @@ c_parser_omp_parallel (location_t loc, c_parser *parser,
          c_parser_consume_token (parser);
          if (!flag_openmp)  /* flag_openmp_simd  */
            return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
-                                       if_p);
+                                       if_p, ploc);
          block = c_begin_omp_parallel ();
          tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
-                                         if_p);
+                                         if_p, ploc);
          stmt = c_finish_omp_parallel (loc,
                                        cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
                                        block);
@@ -28633,11 +28685,6 @@ c_parser_omp_declare_target (c_parser *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 (c_parser_peek_token (parser)->location,
-                   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)
@@ -30444,9 +30491,13 @@ c_parser_omp_metadirective (c_parser *parser, bool *if_p)
       location_t match_loc = c_parser_peek_token (parser)->location;
       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
       if (strcmp (p, "default") == 0)
-       warning_at (pragma_loc, OPT_Wdeprecated_openmp,
-                   "%<default%> clause on metadirectives deprecated since "
-                   "OpenMP 5.2, use %<otherwise%>");
+       {
+         gcc_rich_location richloc (pragma_loc);
+         richloc.add_fixit_replace (match_loc, "otherwise");
+         warning_at (&richloc, OPT_Wdeprecated_openmp,
+                     "%<default%> clause on metadirectives deprecated since "
+                     "OpenMP 5.2, use %<otherwise%>");
+       }
       c_parser_consume_token (parser);
       bool default_p
        = strcmp (p, "default") == 0 || strcmp (p, "otherwise") == 0;
@@ -30829,7 +30880,8 @@ c_parser_omp_construct (c_parser *parser, bool *if_p)
       break;
     case PRAGMA_OMP_MASTER:
       strcpy (p_name, "#pragma omp");
-      stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
+      stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p,
+                                 UNKNOWN_LOCATION);
       break;
     case PRAGMA_OMP_PARALLEL:
       strcpy (p_name, "#pragma omp");
index 35577fa53c2522137a864d397f27a4b2220c1a91..8838d979cbbf7e2e2ae53eca829e791f16d49d7d 100644 (file)
@@ -1,19 +1,15 @@
 // tests for deprecation of 'to' clause with 'declare target' and the '-'
 // operator when used in reductions.
-// { dg-warning "'to' clause with 'declare target' deprecated since OpenMP 5.2, use 'enter' \\\[-Wdeprecated-openmp\\\]" "" { target c } 12 }
-// { dg-warning "'to' clause with 'declare target' deprecated since OpenMP 5.2, use 'enter' \\\[-Wdeprecated-openmp\\\]" "" { target c } 18 }
-// { dg-warning "'to' clause with 'declare target' deprecated since OpenMP 5.2, use 'enter' \\\[-Wdeprecated-openmp\\\]" "" { target c++ } 10 }
-// { dg-warning "'to' clause with 'declare target' deprecated since OpenMP 5.2, use 'enter' \\\[-Wdeprecated-openmp\\\]" "" { target c++ } 16 }
 
 int x = 24;
 
-#pragma omp declare target to(x)
+#pragma omp declare target to(x)       // { dg-warning "'to' clause with 'declare target' deprecated since OpenMP 5.2, use 'enter' \\\[-Wdeprecated-openmp\\\]" }
 
 int foo(int x)
 {
   return x + 1;
 }
-#pragma omp declare target to(foo)
+#pragma omp declare target to(foo)     // { dg-warning "'to' clause with 'declare target' deprecated since OpenMP 5.2, use 'enter' \\\[-Wdeprecated-openmp\\\]" }
 
 int
 main()
diff --git a/gcc/testsuite/gcc.dg/gomp/deprecate-1.c b/gcc/testsuite/gcc.dg/gomp/deprecate-1.c
new file mode 100644 (file)
index 0000000..ff13801
--- /dev/null
@@ -0,0 +1,96 @@
+/* { 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);
+
+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 "" } */
+  ;
+}