Skip to content

Conversation

@TIFitis
Copy link
Member

@TIFitis TIFitis commented May 21, 2025

This patch fixes unintentional OOB acess when mapping members of derived type.

When currentIndicesIdx is maxSize - 1, i.e, it is the last member mapping, we can break from the loop. This was already the intended behaviour but using continue instead of break resulted in OOB access of indices.

This fixes the following test case:

module mod
   implicit none
   type :: mattype
      real(4), pointer :: array(:, :, :)
      integer(4) :: scalar
   end type
   type :: data
      type(mattype) :: memb
   end type
contains
   subroutine us_gpumem(dat)
      implicit none
      type(data), pointer :: dat
      !$omp target enter data map(to:dat%memb)
   end subroutine us_gpumem
end module mod

This patch fixes unintentional OOB acess when mapping members of derived type.
@TIFitis TIFitis requested review from agozillon and Copilot May 21, 2025 18:49
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels May 21, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an out-of-bound access issue in derived type mapping used in OpenMP by altering the loop control flow.

  • Replaces a combined conditional check with two separate branches: one to break immediately when processing the final member and another to handle non-descriptor members.
  • Updates code comments to reflect the revised control flow in flang/lib/Lower/OpenMP/Utils.cpp.
Comments suppressed due to low confidence (2)

flang/lib/Lower/OpenMP/Utils.cpp:367

  • Using 'break' here correctly exits the loop when processing the final member, preventing out-of-bound access. Confirm that this early exit does not bypass any required cleanup or finalization steps needed in the loop.
if (currentIndicesIdx == indices.size() - 1)

flang/lib/Lower/OpenMP/Utils.cpp:376

  • Ensure that incrementing 'currentIndicesIdx' within this branch consistently maintains the expected mapping behavior, particularly when multiple non-descriptor members are encountered consecutively.
if (!fir::isTypeWithDescriptor(memberTy)) {

@llvmbot
Copy link
Member

llvmbot commented May 21, 2025

@llvm/pr-subscribers-flang-fir-hlfir

Author: Akash Banerjee (TIFitis)

Changes

This patch fixes unintentional OOB acess when mapping members of derived type.

When currentIndicesIdx is maxSize - 1, i.e, it is the last member mapping, we can break from the loop. This was already the intended behaviour but using continue instead of break resulted in OOB access of indices.

This fixes the following test case:

module mod
   implicit none
   type :: mattype
      real(4), pointer :: array(:, :, :)
      integer(4) :: scalar
   end type
   type :: data
      type(mattype) :: memb
   end type
contains
   subroutine us_gpumem(dat)
      implicit none
      type(data), pointer :: dat
      !$omp target enter data map(to:dat%memb)
   end subroutine us_gpumem
end module mod

Full diff: https://github.com/llvm/llvm-project/pull/140948.diff

1 Files Affected:

  • (modified) flang/lib/Lower/OpenMP/Utils.cpp (+12-10)
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index 173dceb07b193..711d4af287691 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -362,16 +362,18 @@ mlir::Value createParentSymAndGenIntermediateMaps(
           clauseLocation, firOpBuilder.getRefType(memberTy), curValue,
           llvm::SmallVector<fir::IntOrValue, 1>{idxConst});
 
-      // Skip mapping and the subsequent load if we're the final member or not
-      // a type with a descriptor such as a pointer/allocatable. If we're a
-      // final member, the map will be generated by the processMap call that
-      // invoked this function, and if we're not a type with a descriptor then
-      // we have no need of generating an intermediate map for it, as we only
-      // need to generate a map if a member is a descriptor type (and thus
-      // obscures the members it contains via a pointer in which it's data needs
-      // mapped)
-      if ((currentIndicesIdx == indices.size() - 1) ||
-          !fir::isTypeWithDescriptor(memberTy)) {
+      // If we're a final member, the map will be generated by the processMap
+      // call that invoked this function.
+      if (currentIndicesIdx == indices.size() - 1)
+        break;
+
+      // Skip mapping and the subsequent load if we're not
+      // a type with a descriptor such as a pointer/allocatable. If we're not a
+      // type with a descriptor then we have no need of generating an
+      // intermediate map for it, as we only need to generate a map if a member
+      // is a descriptor type (and thus obscures the members it contains via a
+      // pointer in which it's data needs mapped).
+      if (!fir::isTypeWithDescriptor(memberTy)) {
         currentIndicesIdx++;
         continue;
       }

@TIFitis TIFitis requested a review from dpalermo May 21, 2025 18:51
Copy link
Contributor

@agozillon agozillon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you for the catch/fix! :-)

@TIFitis TIFitis merged commit fbb11b4 into llvm:main May 22, 2025
14 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented May 22, 2025

LLVM Buildbot has detected a new failure on builder openmp-offload-sles-build-only running on rocm-worker-hw-04-sles while building flang at step 10 "Add check check-lld".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/140/builds/23576

Here is the relevant piece of the build log for the reference
Step 10 (Add check check-lld) failure: test (failure)
******************** TEST 'lld :: COFF/lto-cache-errors.ll' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
/home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/opt -module-hash -module-summary /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/lld/test/COFF/lto-cache-errors.ll -o /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.o # RUN: at line 5
+ /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/opt -module-hash -module-summary /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/lld/test/COFF/lto-cache-errors.ll -o /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.o
/home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/opt -module-hash -module-summary /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/lld/test/COFF/Inputs/lto-cache.ll -o /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp2.o # RUN: at line 6
+ /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/opt -module-hash -module-summary /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/lld/test/COFF/Inputs/lto-cache.ll -o /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp2.o
rm -Rf /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.cache && mkdir /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.cache # RUN: at line 7
+ rm -Rf /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.cache
+ mkdir /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.cache
chmod 444 /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.cache # RUN: at line 8
+ chmod 444 /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.cache
not /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/lld-link /lldltocache:/home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.cache/nonexistant/ /out:/home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp3 /entry:main /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp2.o /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.o 2>&1 | /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/FileCheck /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/lld/test/COFF/lto-cache-errors.ll # RUN: at line 11
+ /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/FileCheck /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/lld/test/COFF/lto-cache-errors.ll
+ not /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/lld-link /lldltocache:/home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.cache/nonexistant/ /out:/home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp3 /entry:main /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp2.o /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/tools/lld/test/COFF/Output/lto-cache-errors.ll.tmp.o

--

********************


@TIFitis TIFitis deleted the derived_type_fix branch July 2, 2025 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flang:fir-hlfir flang Flang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants