Testing of the 'declare mapper' and 'declare reduction'
showed that the current code didn't handle renaming of
the derived type via module use.
That's now fixed by this commit r17-1523-g5d4b953d53ee9f.
Besides not properly checking for renamings, the CLASS
part was broken. First, by syntax ('+ : t : omp_out...' and 't :: var'),
only derived types are possible - secondly, the actual declared-type
has to be found differently.
That's now fixed, but I bet that polymorphic types will be mishandled,
before and after this change - something to look into in a later patch.
Tobias
commit 5d4b953d53ee9ff6376f67e572d6308bbd977f75
Author: Tobias Burnus <[email protected]>
Date: Fri Jun 12 23:30:35 2026 +0200
OpenMP/Fortran: Fix module-use renaming with declare mapper/reduction
Use the same logic as in gfc_compare_derived_types to compare the
types. Additionally, the 'declare' part only permits derived types
(per syntax) and not class - while using the mapper/reduction with
CLASS variables is possible.
gcc/fortran/ChangeLog:
* openmp.cc (gfc_omp_udm_find, gfc_omp_udr_find): Fix
to handle derived-type renaming via module use.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/declare-mapper-6.f90: New test.
* gfortran.dg/gomp/declare-mapper-7.f90: New test.
* gfortran.dg/gomp/declare-reduction-3.f90: New test.
* gfortran.dg/gomp/declare-reduction-4.f90: New test.
---
gcc/fortran/openmp.cc | 37 +++++++++++++----
.../gfortran.dg/gomp/declare-mapper-6.f90 | 43 ++++++++++++++++++++
.../gfortran.dg/gomp/declare-mapper-7.f90 | 29 +++++++++++++
.../gfortran.dg/gomp/declare-reduction-3.f90 | 47 ++++++++++++++++++++++
.../gfortran.dg/gomp/declare-reduction-4.f90 | 28 +++++++++++++
5 files changed, 176 insertions(+), 8 deletions(-)
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 3d7d12de0c2..4f5e0a8e344 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -5976,11 +5976,21 @@ gfc_omp_udm_find (gfc_symtree *st, gfc_typespec *ts)
if (st == NULL)
return NULL;
+ gfc_symbol *dt = (ts->type == BT_CLASS
+ ? CLASS_DATA (ts->u.derived)->ts.u.derived
+ : ts->u.derived);
for (omp_udm = st->n.omp_udm; omp_udm; omp_udm = omp_udm->next)
- if ((omp_udm->ts.type == BT_DERIVED || omp_udm->ts.type == BT_CLASS)
- && (ts->type == BT_DERIVED || ts->type == BT_CLASS)
- && strcmp (omp_udm->ts.u.derived->name, ts->u.derived->name) == 0)
- return omp_udm;
+ {
+ if (dt == omp_udm->ts.u.derived)
+ return omp_udm;
+ /* Special case for comparing derived types across namespaces. If the
+ true names and module names are the same and the module name is
+ nonnull, then they are equal. */
+ if (dt->module && omp_udm->ts.u.derived->module
+ && strcmp (dt->name, omp_udm->ts.u.derived->name) == 0
+ && strcmp (dt->module, omp_udm->ts.u.derived->module) == 0)
+ return omp_udm;
+ }
return NULL;
}
@@ -6292,14 +6302,25 @@ gfc_omp_udr_find (gfc_symtree *st, gfc_typespec *ts)
if (st == NULL)
return NULL;
+ gfc_symbol *dt = NULL;
+ if (ts->type == BT_DERIVED || ts->type == BT_CLASS)
+ dt = (ts->type == BT_CLASS
+ ? CLASS_DATA (ts->u.derived)->ts.u.derived : ts->u.derived);
for (omp_udr = st->n.omp_udr; omp_udr; omp_udr = omp_udr->next)
if (omp_udr->ts.type == ts->type
- || ((omp_udr->ts.type == BT_DERIVED || omp_udr->ts.type == BT_CLASS)
- && (ts->type == BT_DERIVED || ts->type == BT_CLASS)))
+ || (dt && omp_udr->ts.type == BT_DERIVED))
{
- if (omp_udr->ts.type == BT_DERIVED || omp_udr->ts.type == BT_CLASS)
+ if (dt && omp_udr->ts.type == BT_DERIVED)
{
- if (strcmp (omp_udr->ts.u.derived->name, ts->u.derived->name) == 0)
+ gfc_symbol *dtu = omp_udr->ts.u.derived;
+ if (dt == dtu)
+ return omp_udr;
+ /* Special case for comparing derived types across namespaces. If
+ the true names and module names are the same and the module name
+ is nonnull, then they are equal. */
+ if (dt->module && dtu->module
+ && strcmp (dt->name, dtu->name) == 0
+ && strcmp (dt->module, dtu->module) == 0)
return omp_udr;
}
else if (omp_udr->ts.kind == ts->kind)
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-mapper-6.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-mapper-6.f90
new file mode 100644
index 00000000000..7e3e70627ec
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-mapper-6.f90
@@ -0,0 +1,43 @@
+! Check that type renaming via module use is properly handled.
+
+module first
+ implicit none
+ type t
+ integer, pointer :: x(:)
+ end type t
+ !$omp declare mapper(t :: v) map(v, v%x)
+end module
+
+module second
+ implicit none
+ type t
+ integer, pointer :: y(:)
+ integer, pointer :: z(:)
+ end type t
+ !$omp declare mapper(t :: v) map(v, v%y, v%z)
+end module
+
+subroutine sub2
+ use first, t1 => t
+ use second, t2 => t
+ implicit none
+ type(t1) :: var
+ type(t2) :: var2
+
+ allocate(var%x(1:20))
+ allocate(var2%y(1:3), var2%z(5))
+ var%x = 9
+ var2%y = 1
+ var2%z = 43
+
+ !$omp target map(tofrom: var) ! { dg-error "Sorry, declared mapper 'default', used for 'var' at .1., is not yet supported" }
+ block
+ var%x = 4
+ end block
+
+ !$omp target map(tofrom: var2) ! { dg-error "Sorry, declared mapper 'default', used for 'var2' at .1., is not yet supported" }
+ block
+ var2%y = 3
+ var2%z = 7
+ end block
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-mapper-7.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-mapper-7.f90
new file mode 100644
index 00000000000..2ed50e069a7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-mapper-7.f90
@@ -0,0 +1,29 @@
+! Check that type renaming via module use is properly handled.
+
+module zero
+ implicit none
+ type t
+ integer, pointer :: x(:)
+ integer, pointer :: y(:)
+ end type t
+end module zero
+
+module first
+ use zero, only: t1 => t
+ implicit none
+ !$omp declare mapper(t1 :: v1) map(v1, v1%x)
+end module
+
+module second
+ use zero, only: t2 => t
+ implicit none
+ !$omp declare mapper(t2 :: v2) map(v2, v2%x, v2%y)
+end module
+
+subroutine sub2
+ use first ! { dg-note "Previous !.OMP DECLARE MAPPER from module 'first'" }
+ use second ! { dg-error "Ambiguous !.OMP DECLARE MAPPER 'default' for type 't' from module 'second'" }
+ implicit none
+ ! type(t1) :: var1
+ ! type(t2) :: var2
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-reduction-3.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-reduction-3.f90
new file mode 100644
index 00000000000..aa5d5bc1b5a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-reduction-3.f90
@@ -0,0 +1,47 @@
+! Check that type renaming via module use is properly handled.
+
+module first
+ implicit none
+ type t
+ integer :: x = 0
+ end type t
+ !$omp declare reduction(+: t : omp_out%x = omp_out%x + omp_in%x)
+end module
+
+module second
+ implicit none
+ type t
+ integer :: y = 0
+ end type t
+ !$omp declare reduction(+: t : omp_out%y = omp_out%y + omp_in%y)
+end module
+
+subroutine sub2
+ use first, t1 => t
+ use second, t2 => t
+ implicit none
+ type(t1) :: var(5), sum1
+ type(t2) :: var2(3), sum2
+ integer :: i
+
+ var%x = [(2*i, i = 1,5)]
+ var2%y = [(5*i+1, i = 1,3)]
+ sum1%x = 0
+ sum2%y = 0
+
+ !$omp parallel do reduction(+:sum1)
+ do i = 1, size(var)
+ sum1%x = sum1%x + var(i)%x
+ end do
+
+ !$omp parallel do reduction(+:sum2)
+ do i = 1, size(var2)
+ sum2%y = sum2%y + var2(i)%y
+ end do
+
+ if (sum1%x /= sum(var%x)) stop 1
+ if (sum2%y /= sum(var2%y)) stop 2
+end
+
+call sub2
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-reduction-4.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-reduction-4.f90
new file mode 100644
index 00000000000..da8e87d4914
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-reduction-4.f90
@@ -0,0 +1,28 @@
+! Check that type renaming via module use is properly handled.
+
+module zero
+ implicit none
+ type t
+ integer :: x = 0
+ end type t
+end module zero
+
+module first
+ use zero, only: t1 => t
+ implicit none
+ !$omp declare reduction(+: t1 : omp_out%x = omp_out%x + omp_in%x)
+end module
+
+module second
+ use zero, only: t2 => t
+ implicit none
+ !$omp declare reduction(+: t2 : omp_out%x = omp_out%x + omp_in%x)
+end module
+
+subroutine sub2
+ use first ! { dg-note "Previous !.OMP DECLARE REDUCTION from module 'first'" }
+ use second ! { dg-error "Ambiguous !.OMP DECLARE REDUCTION 'operator \\+' for type 'TYPE\\(t\\)' from module 'second' at .1." }
+ implicit none
+ type(t1) :: var(5), sum1
+ type(t2) :: var2(3), sum2
+end