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
