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

Reply via email to