https://gcc.gnu.org/g:b28a16af7fa7fea6a16f4c45024efdd863d82393
commit r17-4506-gb28a16af7fa7fea6a16f4c45024efdd863d82393 Author: Tobias Burnus <[email protected]> Date: Mon Sep 21 08:16:58 2026 +0200 OpenMP/Fortran: Permit comma between directive and clause This was added in OpenMP 5.2 when the syntax between Fortran and C/C++ was aligned a bit more. In C/C++ it was added presumably to have a nicer attribute syntax. gcc/fortran/ChangeLog: * openmp.cc (gfc_match_omp_clauses): Rename argument 'first' to first_no_comma for clarity. (match_omp, gfc_match_omp_allocate, gfc_match_omp_assume, gfc_match_omp_assumes, gfc_match_omp_critical, gfc_match_omp_depobj, gfc_match_omp_flush, gfc_match_omp_declare_simd, gfc_match_omp_declare_mapper, gfc_match_omp_declare_reduction, gfc_match_omp_declare_target, gfc_match_omp_thread_group_private, gfc_match_omp_requires, gfc_match_omp_scan, gfc_match_omp_atomic, gfc_match_omp_cancel_kind, gfc_match_omp_end_nowait, gfc_match_omp_end_single): Permit comma between directive name and clause name. libgomp/ChangeLog: * libgomp.texi (OpenMP 5.2 Impl. Status): Mark comma between directive name and first clause as implemented in Fortran. Diff: --- gcc/fortran/openmp.cc | 50 +++++++++++++++++++++++++++----------------------- libgomp/libgomp.texi | 2 +- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 6737e1e3796c..d49fa79b3b4f 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -2586,7 +2586,7 @@ gfc_find_omp_udm (gfc_namespace *ns, const char *mapper_id, gfc_typespec *ts) static match gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, - bool first = true, bool needs_space = true, + bool first_no_comma = true, bool needs_space = true, bool openacc = false, bool openmp_target = false, gfc_omp_map_op default_map_op = OMP_MAP_TOFROM) { @@ -2606,11 +2606,11 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, while (1) { match m = MATCH_NO; - if ((first || (m = gfc_match_char (',')) != MATCH_YES) + if ((first_no_comma || (m = gfc_match_char (',')) != MATCH_YES) && (needs_space && gfc_match_space () != MATCH_YES)) break; needs_space = false; - first = false; + first_no_comma = false; gfc_gobble_whitespace (); bool end_colon; gfc_omp_namelist **head; @@ -5776,7 +5776,7 @@ static match match_omp (gfc_exec_op op, const omp_mask mask) { gfc_omp_clauses *c; - if (gfc_match_omp_clauses (&c, mask, true, true, false, + if (gfc_match_omp_clauses (&c, mask, false, true, false, op == EXEC_OMP_TARGET) != MATCH_YES) return MATCH_ERROR; new_st.op = op; @@ -5801,7 +5801,6 @@ match gfc_match_omp_allocate (void) { match m; - bool first = true; gfc_omp_namelist *vars = NULL; gfc_expr *align = NULL; gfc_expr *allocator = NULL; @@ -5818,9 +5817,7 @@ gfc_match_omp_allocate (void) gfc_gobble_whitespace (); if (gfc_match_omp_eos () == MATCH_YES) break; - if (!first) - gfc_match (", "); - first = false; + gfc_match (", "); /* optionally */ if ((m = gfc_match_dupl_check (!align, "align", true, &align)) != MATCH_NO) { @@ -5896,7 +5893,7 @@ gfc_match_omp_assume (void) { gfc_omp_clauses *c; locus loc = gfc_current_locus; - if ((gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_ASSUMPTIONS)) + if ((gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_ASSUMPTIONS), false) != MATCH_YES) || (omp_verify_merge_absent_contains (ST_OMP_ASSUME, c->assume, NULL, &loc) != MATCH_YES)) @@ -5921,7 +5918,7 @@ gfc_match_omp_assumes (void) "subprogram or module"); return MATCH_ERROR; } - if ((gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_ASSUMPTIONS)) + if ((gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_ASSUMPTIONS), false) != MATCH_YES) || (omp_verify_merge_absent_contains (ST_OMP_ASSUMES, c->assume, gfc_current_ns->omp_assumes, &loc) @@ -5965,8 +5962,8 @@ gfc_match_omp_critical (void) if (gfc_match (" ( %n )", n) != MATCH_YES) n[0] = '\0'; - if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_HINT), - /* first = */ n[0] == '\0') != MATCH_YES) + if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_HINT), false, + /* needs_space = */ n[0] == '\0') != MATCH_YES) return MATCH_ERROR; new_st.op = EXEC_OMP_CRITICAL; @@ -6011,6 +6008,7 @@ gfc_match_omp_depobj (void) gfc_error ("Expected %<( depobj )%> at %C"); return MATCH_ERROR; } + gfc_match (", "); /* optionally */ if (gfc_match ("update ( ") == MATCH_YES) { c = gfc_get_omp_clauses (); @@ -6046,7 +6044,7 @@ gfc_match_omp_depobj (void) gfc_free_expr (destroyobj); } } - else if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_DEPEND), true, false) + else if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_DEPEND), false, false) != MATCH_YES) goto error; @@ -6249,6 +6247,7 @@ gfc_match_omp_flush (void) enum gfc_omp_memorder mo = OMP_MEMORDER_UNSET; if (gfc_match_omp_eos () == MATCH_NO && gfc_peek_ascii_char () != '(') { + gfc_match (", "); /* optionally */ if (gfc_match ("seq_cst") == MATCH_YES) mo = OMP_MEMORDER_SEQ_CST; else if (gfc_match ("acq_rel") == MATCH_YES) @@ -6308,7 +6307,7 @@ gfc_match_omp_declare_simd (void) case MATCH_ERROR: return MATCH_ERROR; } - if (gfc_match_omp_clauses (&c, OMP_DECLARE_SIMD_CLAUSES, true, + if (gfc_match_omp_clauses (&c, OMP_DECLARE_SIMD_CLAUSES, false, needs_space) != MATCH_YES) return MATCH_ERROR; @@ -6450,7 +6449,7 @@ gfc_match_omp_declare_mapper (void) gfc_omp_clauses *clauses = NULL; - m = gfc_match_omp_clauses (&clauses, omp_mask (OMP_CLAUSE_MAP), true, true, + m = gfc_match_omp_clauses (&clauses, omp_mask (OMP_CLAUSE_MAP), false, false, false, false, OMP_MAP_UNSET); if (m != MATCH_YES) goto failure; @@ -6844,7 +6843,7 @@ gfc_match_omp_declare_reduction (void) gfc_free_omp_udr (omp_udr); return MATCH_ERROR; } - + gfc_match_char (','); /* optionally */ if (gfc_match (" initializer ( ") == MATCH_YES) { gfc_current_ns = combiner_ns->parent; @@ -6973,7 +6972,8 @@ gfc_match_omp_declare_target (void) goto cleanup; } } - else if (gfc_match_omp_clauses (&c, OMP_DECLARE_TARGET_CLAUSES) != MATCH_YES) + else if (gfc_match_omp_clauses (&c, OMP_DECLARE_TARGET_CLAUSES, false) + != MATCH_YES) return MATCH_ERROR; gfc_buffer_error (false); @@ -8116,7 +8116,7 @@ gfc_match_omp_thread_group_private (bool is_groupprivate) if (is_groupprivate) { gfc_omp_clauses *c; - m = gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_DEVICE_TYPE)); + m = gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_DEVICE_TYPE), false, false); if (m == MATCH_ERROR) return MATCH_ERROR; @@ -8459,7 +8459,7 @@ gfc_match_omp_requires (void) { old_loc = gfc_current_locus; gfc_omp_requires_kind requires_clause; - if ((first || gfc_match_char (',') != MATCH_YES) + if (gfc_match_char (',') != MATCH_YES && (first && gfc_match_space () != MATCH_YES)) goto error; first = false; @@ -8573,6 +8573,7 @@ gfc_match_omp_scan (void) bool incl; gfc_omp_clauses *c = gfc_get_omp_clauses (); gfc_gobble_whitespace (); + gfc_match (", "); /* optionally */ if ((incl = (gfc_match ("inclusive") == MATCH_YES)) || gfc_match ("exclusive") == MATCH_YES) { @@ -8959,7 +8960,7 @@ gfc_match_omp_atomic (void) gfc_omp_clauses *c; locus loc = gfc_current_locus; - if (gfc_match_omp_clauses (&c, OMP_ATOMIC_CLAUSES, true, true) != MATCH_YES) + if (gfc_match_omp_clauses (&c, OMP_ATOMIC_CLAUSES, false, true) != MATCH_YES) return MATCH_ERROR; if (c->atomic_op == GFC_OMP_ATOMIC_UNSET) @@ -9118,7 +9119,8 @@ gfc_match_omp_taskgroup (void) static enum gfc_omp_cancel_kind gfc_match_omp_cancel_kind (void) { - if (gfc_match_space () != MATCH_YES) + if (gfc_match (" , ") != MATCH_YES + && gfc_match_space () != MATCH_YES) return OMP_CANCEL_UNKNOWN; if (gfc_match ("parallel") == MATCH_YES) return OMP_CANCEL_PARALLEL; @@ -9177,7 +9179,8 @@ match gfc_match_omp_end_nowait (void) { bool nowait = false; - if (gfc_match ("% nowait") == MATCH_YES) + if (gfc_match ("% nowait ") == MATCH_YES + || gfc_match (" , nowait ") == MATCH_YES) nowait = true; if (gfc_match_omp_eos () != MATCH_YES) { @@ -9198,7 +9201,8 @@ gfc_match_omp_end_single (void) { gfc_omp_clauses *c; if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_COPYPRIVATE) - | OMP_CLAUSE_NOWAIT) != MATCH_YES) + | OMP_CLAUSE_NOWAIT, false) + != MATCH_YES) return MATCH_ERROR; new_st.op = EXEC_OMP_END_SINGLE; new_st.ext.omp_clauses = c; diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index b3700d7f1428..4a1069833082 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -442,7 +442,7 @@ to address of matching mapped list item per 5.1, Sect. 2.21.7.2 @tab N @tab @multitable @columnfractions .60 .10 .25 @headitem Description @tab Status @tab Comments -@item For Fortran, optional comma between directive and clause @tab N @tab +@item For Fortran, optional comma between directive and clause @tab Y @tab @item Conforming device numbers and @code{omp_initial_device} and @code{omp_invalid_device} enum/PARAMETER @tab Y @tab @item Initial value of @var{default-device-var} ICV with
