Hi! 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. I can do C++ FE next. Some issues: 1) I have no idea what to do about #pragma omp master #pragma omp master taskloop #pragma omp declare target 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 #pragma omp declare reduction (-:struct S:omp_out.s += omp_in.s) (similar case to reduction clause with - identifier) 3) I think the map clause diagnostics for missing comma separation will not diagnose #pragma omp target map (always tofrom: x) 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. #pragma omp target map (always present, close, tofrom: x) would I think diagnose missing comma twice. 2025-12-12 Jakub Jelinek <[email protected]> * 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.jj 2025-12-11 21:29:28.614228231 +0100 +++ gcc/c/c-parser.cc 2025-12-12 12:01:56.793216348 +0100 @@ -18850,10 +18850,14 @@ c_parser_omp_clause_reduction (c_parser 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: @@ -19584,6 +19588,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; @@ -19602,10 +19608,9 @@ c_parser_omp_clause_linear (c_parser *pa 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); } @@ -19615,12 +19620,17 @@ c_parser_omp_clause_linear (c_parser *pa 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)) @@ -19723,6 +19733,27 @@ c_parser_omp_clause_linear (c_parser *pa 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; } @@ -20105,7 +20136,7 @@ c_parser_omp_clause_affinity (c_parser * 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; @@ -20142,14 +20173,18 @@ c_parser_omp_clause_depend (c_parser *pa 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; @@ -20583,10 +20618,15 @@ c_parser_omp_clause_map (c_parser *parse 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) @@ -20830,7 +20870,10 @@ c_parser_omp_clause_proc_bind (c_parser 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; @@ -22051,6 +22094,11 @@ c_parser_omp_all_clauses (c_parser *pars 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)) @@ -22096,7 +22144,7 @@ c_parser_omp_all_clauses (c_parser *pars 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: @@ -24307,7 +24355,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; @@ -25450,12 +25498,15 @@ static tree c_parser_omp_taskloop (locat 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"); @@ -25869,6 +25920,7 @@ c_parser_omp_parallel (location_t loc, c 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]; @@ -25906,10 +25958,10 @@ c_parser_omp_parallel (location_t loc, c 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); @@ -28399,11 +28451,6 @@ c_parser_omp_declare_target (c_parser *p } 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) @@ -30210,9 +30257,13 @@ c_parser_omp_metadirective (c_parser *pa 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; @@ -30595,7 +30646,8 @@ c_parser_omp_construct (c_parser *parser 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"); --- gcc/testsuite/c-c++-common/gomp/52-deps.c.jj 2025-12-11 19:33:57.695486865 +0100 +++ gcc/testsuite/c-c++-common/gomp/52-deps.c 2025-12-12 12:21:37.024899739 +0100 @@ -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() --- gcc/testsuite/gcc.dg/gomp/deprecate-1.c.jj 2025-12-12 12:15:23.368347569 +0100 +++ gcc/testsuite/gcc.dg/gomp/deprecate-1.c 2025-12-12 12:33:11.568854333 +0100 @@ -0,0 +1,95 @@ +/* { 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 "" } */ + ; +} Jakub
