For ENTER/EXIT DATA (both OpenMP and OpenACC), avoid creating a
GOMP_MAP_POINTER mapping for variables that are only pointer types
at tree level due to Fortran pass-by-reference semantics, but are
not actual POINTER, ALLOCATABLE, or Cray pointee variables.

Previously, the frontend would generate a mapping that takes the
address of the reference slot (&var where var is already a reference),
which incorrectly maps the local stack frame address instead of the
referenced data.  When the subroutine returns and the stack is reused,
this causes conflicts in libgomp's splay tree structures:

  libgomp: Trying to map into device [...] object when [...] is
  already mapped

The fix refines the condition for creating node4 (the pointer mapping)
to only apply when the variable is an actual POINTER/ALLOCATABLE (at
Fortran level), not just pass-by-reference.

        PR fortran/103276

gcc/fortran/ChangeLog:

        * trans-openmp.cc (gfc_trans_omp_clauses): For ENTER/EXIT DATA,
        skip GOMP_MAP_POINTER mapping for pass-by-reference scalars that
        are not actual POINTER/ALLOCATABLE variables.

gcc/testsuite/ChangeLog:

        * gfortran.dg/goacc/pr103276.f90: New test.

Co-authored-by: Tobias Burnus <[email protected]>
Signed-off-by: Christopher Albert <[email protected]>
---
 gcc/fortran/trans-openmp.cc                  | 18 ++++++++++---
 gcc/testsuite/gfortran.dg/goacc/pr103276.f90 | 27 ++++++++++++++++++++
 2 files changed, 42 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/goacc/pr103276.f90

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index d7f3c281823..7f98b934191 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -4247,9 +4247,21 @@ gfc_trans_omp_clauses (stmtblock_t *block, 
gfc_omp_clauses *clauses,
                                                             cond, tmp,
                                                             NULL_TREE));
                        }
-                     /* For descriptor types, the unmapping happens below.  */
-                     if (op != EXEC_OMP_TARGET_EXIT_DATA
-                         || !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
+                     /* For descriptor types, the unmapping happens below.
+                        For ENTER/EXIT DATA on pass-by-reference scalars
+                        that are not actual POINTER/ALLOCATABLE, skip the
+                        pointer mapping - it would incorrectly map the
+                        local reference slot instead of the data.  */
+                     if ((op != EXEC_OMP_TARGET_EXIT_DATA
+                          && op != EXEC_OMP_TARGET_ENTER_DATA
+                          && op != EXEC_OACC_ENTER_DATA
+                          && op != EXEC_OACC_EXIT_DATA)
+                         || (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
+                             && (GFC_DECL_GET_SCALAR_POINTER (decl)
+                                 || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
+                                 || GFC_DECL_CRAY_POINTEE (decl)
+                                 || pointer
+                                 || allocatable)))
                        {
                          enum gomp_map_kind gmk = GOMP_MAP_POINTER;
                          if (op == EXEC_OMP_TARGET_EXIT_DATA
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr103276.f90 
b/gcc/testsuite/gfortran.dg/goacc/pr103276.f90
new file mode 100644
index 00000000000..8eb2f85bccb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/pr103276.f90
@@ -0,0 +1,27 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenacc -fdump-tree-omplower" }
+!
+! PR fortran/103276
+! OpenACC ENTER DATA on a derived-type dummy argument must not take the
+! address of the reference slot (which lives on the current stack frame).
+! The mapping should use the reference value directly, not &var.
+
+module m
+  implicit none
+
+  type :: t
+    integer :: v
+  end type t
+
+contains
+
+  subroutine copyin_scalar (var)
+    type(t), intent(inout) :: var
+    !$acc enter data copyin(var)
+  end subroutine copyin_scalar
+
+end module m
+
+! Verify that the lowered code does not contain "&var" assignment to
+! .omp_data_arr, which would indicate taking address of reference slot.
+! { dg-final { scan-tree-dump-not "\\.omp_data_arr\\..*= &var" "omplower" } }
-- 
2.52.0

Reply via email to