https://gcc.gnu.org/g:539875dc1fa11a189da11105d004baf8aa218e7e
commit r14-12579-g539875dc1fa11a189da11105d004baf8aa218e7e Author: Paul Thomas <[email protected]> Date: Tue May 12 18:21:38 2026 +0100 Author: Christopher Albert <[email protected]> Date: Sat Apr 11 15:13:19 2026 +0200 fortran: Fix ICE in remap_type with deferred-length character in OMP target [PR101760, PR102314] For deferred-length character types such as character(:), allocatable, TYPE_SIZE and TYPE_SIZE_UNIT contain SAVE_EXPRs wrapping the string length variable (created by variable_size in finalize_type_size). In gfc_omp_finish_clause, when computing OMP_CLAUSE_SIZE for implicitly mapped variables, the code previously used TYPE_SIZE_UNIT directly. Gimplifying this shared SAVE_EXPR resolves it in place, embedding a gimple temporary into the type's size expression. When the enclosing function is later inlined, remap_type_1 walks TYPE_SIZE and encounters the stale temporary as an unmappable SSA name, causing an ICE in make_ssa_name_fn. Fix by computing the clause size from the array domain bounds and element size rather than using the type's SAVE_EXPR directly, so that the type's size expressions remain untouched. PR fortran/101760 PR fortran/102314 gcc/fortran/ChangeLog: * trans-openmp.cc (gfc_omp_finish_clause): Compute OMP_CLAUSE_SIZE from the array domain bounds and element size for VLA types instead of using TYPE_SIZE_UNIT directly, to avoid corrupting the type. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/pr101760.f90: New test. * gfortran.dg/gomp/pr102314.f90: New test. Signed-off-by: Christopher Albert <[email protected]> Diff: --- gcc/fortran/trans-openmp.cc | 36 ++++++++++++++++++++++++++--- gcc/testsuite/gfortran.dg/gomp/pr101760.f90 | 14 +++++++++++ gcc/testsuite/gfortran.dg/gomp/pr102314.f90 | 19 +++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 6efa1bd1d851..988b011282f9 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -1763,9 +1763,39 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool openacc) } tree last = c; if (OMP_CLAUSE_SIZE (c) == NULL_TREE) - OMP_CLAUSE_SIZE (c) - = DECL_P (decl) ? DECL_SIZE_UNIT (decl) - : TYPE_SIZE_UNIT (TREE_TYPE (decl)); + { + if (DECL_P (decl)) + OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl); + else + { + tree type = TREE_TYPE (decl); + tree size = TYPE_SIZE_UNIT (type); + /* For variable-length character types, TYPE_SIZE_UNIT is a + SAVE_EXPR. Gimplifying the SAVE_EXPR (here or elsewhere) + resolves it in place, embedding a gimple temporary that + later causes an ICE in remap_type during inlining because + the temporary is not in scope (PR101760, PR102314). + Compute the size from the array domain and element size + to decouple completely from the type's SAVE_EXPRs. */ + if (size + && TREE_CODE (type) == ARRAY_TYPE + && TYPE_DOMAIN (type) + && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) + && !TREE_CONSTANT (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))) + { + tree len = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); + tree lb = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); + tree eltsz = TYPE_SIZE_UNIT (TREE_TYPE (type)); + len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len, lb); + len = fold_build2 (PLUS_EXPR, TREE_TYPE (len), len, + build_one_cst (TREE_TYPE (len))); + size = fold_build2 (MULT_EXPR, sizetype, + fold_convert (sizetype, len), + fold_convert (sizetype, eltsz)); + } + OMP_CLAUSE_SIZE (c) = size; + } + } if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p, NULL, is_gimple_val, fb_rvalue) == GS_ERROR) OMP_CLAUSE_SIZE (c) = size_int (0); diff --git a/gcc/testsuite/gfortran.dg/gomp/pr101760.f90 b/gcc/testsuite/gfortran.dg/gomp/pr101760.f90 new file mode 100644 index 000000000000..ab7bf515a8ce --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr101760.f90 @@ -0,0 +1,14 @@ +! PR fortran/101760 +! { dg-do compile } +! { dg-options "-fopenmp -O1" } + +! Verify that deferred-length character variables with the TARGET attribute +! in OpenMP target regions do not ICE during inlining. + +program p + character(:), allocatable, target :: x + logical :: l + !$omp target map(from: l) + l = allocated (x) + !$omp end target +end diff --git a/gcc/testsuite/gfortran.dg/gomp/pr102314.f90 b/gcc/testsuite/gfortran.dg/gomp/pr102314.f90 new file mode 100644 index 000000000000..6e8a45487f3a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr102314.f90 @@ -0,0 +1,19 @@ +! PR fortran/102314 +! { dg-do compile } +! { dg-options "-fopenmp -O2" } + +! Verify that deferred-length character allocatables used inside +! OpenMP target regions do not ICE during SSA verification or inlining. + +program p + character(:), allocatable :: y + call s(y) + !$omp target + y = 'abc' + !$omp end target +contains + subroutine s(x) + character(:), allocatable :: x + x = '123' + end +end
