This fixes an out-of-array-bounds access in the case that nappend < ninterop
Namely, the number of interop clauses to 'dispatch' exceeds the number of interop args accepted by the function/specified in the append_args clause to 'declare variant'. OpenMP does not allow this - hence, GCC diagnoses this error, but the append code was still executed, leading to the issue. Committed asr15-9063-gf3899e0fd3f9aa Thanks to Filip for testing with an ASAN-instrumentedGCC and reporting this issue! Tobias
commit f3899e0fd3f9aa6b579a21e87b50c61ea5c448df Author: Tobias Burnus <tbur...@baylibre.com> Date: Mon Mar 31 11:44:26 2025 +0200 OpenMP: modify_call_for_omp_dispatch - fix invalid memory access after 'error' [PR119541] OpenMP requires that the number of dispatch 'interop' clauses (ninterop) is less or equal to the number of declare variant 'append_args' interop objects (nappend). While 'nappend < ninterop' was diagnosed as error, the processing continues, which lead to an invalid out-of-bounds memory access. Solution: only process the first nappend 'interop' clauses. gcc/ChangeLog: PR middle-end/119541 * gimplify.cc (modify_call_for_omp_dispatch): Limit interop claues processing by the number of append_args arguments. --- gcc/gimplify.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 422ad1265a6..a8399dc8363 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -3940,47 +3940,48 @@ modify_call_for_omp_dispatch (tree expr, tree dispatch_clauses, if (nappend < ninterop) { error_at (OMP_CLAUSE_LOCATION (dispatch_interop), "number of list items in %<interop%> clause (%d) " "exceeds the number of %<append_args%> items (%d) for " "%<declare variant%> candidate %qD", ninterop, nappend, fndecl); inform (dispatch_append_args ? EXPR_LOCATION (TREE_PURPOSE (dispatch_append_args)) : DECL_SOURCE_LOCATION (fndecl), "%<declare variant%> candidate %qD declared here", fndecl); + ninterop = nappend; } } if (dispatch_interop && !dispatch_device_num) { gcc_checking_assert (ninterop > 1); error_at (OMP_CLAUSE_LOCATION (dispatch_interop), "the %<device%> clause must be present if the %<interop%> " "clause has more than one list item"); } else if (dispatch_append_args) { tree *buffer = XALLOCAVEC (tree, nargs + nappend); tree arg = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); /* Copy the first arguments; insert then the interop objects, and then copy the rest (nargs - nfirst_args) args. */ int i; for (i = 0; i < nfirst_args; i++) { arg = TREE_CHAIN (arg); buffer[i] = CALL_EXPR_ARG (expr, i); } int j = ninterop; - for (tree t = dispatch_interop; t; t = TREE_CHAIN (t)) + for (tree t = dispatch_interop; t && j > 0; t = TREE_CHAIN (t)) if (OMP_CLAUSE_CODE (t) == OMP_CLAUSE_INTEROP) buffer[i + --j] = OMP_CLAUSE_DECL (t); gcc_checking_assert (j == 0); /* Do we need to create additional interop objects? */ if (ninterop < nappend) { if (dispatch_device_num == NULL_TREE) /* Not remapping device number. */ dispatch_device_num = build_int_cst (integer_type_node, GOMP_DEVICE_DEFAULT_OMP_61); int nnew = nappend - ninterop;