https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123251
Bug ID: 123251
Summary: OpenACC: derived-type scalar component has wrong value
in device kernel when only array component is mapped
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: albert at tugraz dot at
Target Milestone: ---
current trunk; repo base upstream/master at
769041822723208bf85a91ac409b9b0bdae3fff0 (2025-12-22)
COLLECT_GCC=/opt/gcc16/bin/gfortran
COLLECT_LTO_WRAPPER=/opt/gcc16/libexec/gcc/x86_64-pc-linux-gnu/16.0.0/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
Target: x86_64-pc-linux-gnu
Configured with: ../../gcc/configure --prefix=/opt/gcc16
--enable-languages=c,c++,fortran,lto --disable-multilib --disable-nls
--enable-checking=release
--disable-bootstrap --enable-offload-targets=nvptx-none CFLAGS='-O2 -pipe'
CXXFLAGS='-O2 -pipe' : (reconfigured) ../../gcc/configure --prefix=/opt/gcc16
--disable-multilib --disable-nls --enable-checking=release
--disable-bootstrap --enable-offload-targets=nvptx-none CFLAGS='-O2 -pipe'
CXXFLAGS='-O2 -pipe'
--enable-languages=c,c++,fortran,lto --no-create --no-recursion
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 16.0.0 20251222 (experimental) (GCC)
If only an allocatable array component of a derived type is mapped with !$acc
enter data copyin(c%arr(…)), then a later OpenACC kernel reading a scalar
component c%flag can observe the wrong value on the device (behaves as
false/garbage), even though c%flag is .true. on the host.
Reproducer:
program mre
use, intrinsic :: iso_fortran_env, only: dp => real64
implicit none
type :: container_t
real(dp), allocatable :: arr(:)
logical :: flag
integer :: n
end type container_t
type(container_t) :: c
real(dp), allocatable :: result(:)
integer :: i
real(dp) :: diff
c%n = 100
c%flag = .true.
allocate(c%arr(c%n))
do i = 1, c%n
c%arr(i) = real(i, dp)
end do
!$acc enter data copyin(c%arr(1:c%n))
allocate(result(c%n))
result = 0.0_dp
!$acc data copy(result)
!$acc parallel loop present(c%arr)
do i = 1, c%n
if (c%flag) then
result(i) = c%arr(i) * 2.0_dp
else
result(i) = c%arr(i)
end if
end do
!$acc end parallel loop
!$acc end data
diff = maxval(abs(result - 2.0_dp * c%arr))
if (diff > 1.0e-10_dp) then
print *, "FAIL: max diff = ", diff
stop 1
end if
print *, "PASS"
end program mre
gfortran -v -save-temps -O2 -cpp -fopenacc -foffload=nvptx-none mre.F90 -o mre
ACC_DEVICE_TYPE=nvidia ./mre
The OpenACC regions are lowered with maps that include map(struct:c [len: 1])
and the array component, but the device kernel still reads flag incorrectly.
#pragma omp target oacc_enter_data map(struct:c [len: 1]) map(to:c.arr [pointer
set, len: 64]) ...
#pragma omp target oacc_parallel map(struct:c [len: 1]) map(to:c.arr [pointer
set, len: 64]) ...
...
D.4871 = D.4960->flag;
if (D.4871 != 0) goto ...