https://gcc.gnu.org/g:b8cf80fd274cc88404a53762d243b059bfb5bf70

commit r15-11149-gb8cf80fd274cc88404a53762d243b059bfb5bf70
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]>
    (cherry picked from commit e41fd0a99aee94734537c067f96e3502628125c6)

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 08cd74fcaacf..6edeef66408b 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -1839,9 +1839,39 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool 
openacc)
   else
     {
       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;
+           }
+       }
 
       tree type = TREE_TYPE (decl);
       if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE (type)))
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

Reply via email to