[llvm] [openmp] [OpenMP][DeviceRTL] Report the source location in __kmpc_error diagnostics (PR #224298)
Caroline Newcombe via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 29 05:39:17 PDT 2026
https://github.com/cenewcombe updated https://github.com/llvm/llvm-project/pull/224298
>From f6cc762124e12ccb702192d93e73e5c018c25c5a Mon Sep 17 00:00:00 2001
From: Caroline Newcombe <caroline.newcombe at hpe.com>
Date: Thu, 3 Sep 2026 11:46:15 -0500
Subject: [PATCH 1/2] [OpenMP][DeviceRTL] Report the source location in
__kmpc_error diagnostics
---
offload/test/offloading/error_directive.c | 6 +-
.../offloading/fortran/error_directive.f90 | 13 ++++-
openmp/device/src/Misc.cpp | 55 ++++++++++++++++++-
3 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/offload/test/offloading/error_directive.c b/offload/test/offloading/error_directive.c
index bf8c8a7bf98be..0291b2fe473c3 100644
--- a/offload/test/offloading/error_directive.c
+++ b/offload/test/offloading/error_directive.c
@@ -34,6 +34,8 @@ int main(void) {
// Device output is flushed after host output, so host prints are not checked.
// The fatal case checks only the exit status: its message is lost when the trap
// aborts before the buffered stdout is flushed.
+//
+// clang fills in the ident location from the AST, so it is present without -g
-// CHECK: user-directed warning: warning message.
-// CHECK: user-directed warning.
+// CHECK: {{.*}}error_directive.c:{{[0-9]+}}:{{[0-9]+}}: Encountered user-directed warning: warning message.
+// CHECK: {{.*}}error_directive.c:{{[0-9]+}}:{{[0-9]+}}: Encountered user-directed warning.
diff --git a/offload/test/offloading/fortran/error_directive.f90 b/offload/test/offloading/fortran/error_directive.f90
index 2b2ece3d42ffc..c65d75418a4e8 100644
--- a/offload/test/offloading/fortran/error_directive.f90
+++ b/offload/test/offloading/fortran/error_directive.f90
@@ -6,7 +6,9 @@
! UNSUPPORTED: nvptx64-nvidia-cuda-LTO
! RUN: %libomptarget-compile-fortran-generic -fopenmp-version=51 && \
-! RUN: %libomptarget-run-generic 2>&1 | %fcheck-generic
+! RUN: %libomptarget-run-generic 2>&1 | %fcheck-generic --check-prefix=NOLOC
+! RUN: %libomptarget-compile-fortran-generic -fopenmp-version=51 -g && \
+! RUN: %libomptarget-run-generic 2>&1 | %fcheck-generic --check-prefix=LOC
program error_directive
implicit none
@@ -22,6 +24,11 @@ program error_directive
end program error_directive
! Device output is flushed after host output, so host prints are not checked.
+! Without -g the ident holds no location and is reported as "unknown:0:0", the
+! same as the host runtime.
-! CHECK: user-directed warning: warning message.
-! CHECK: user-directed warning.
+! NOLOC: OMP: unknown:0:0: Encountered user-directed warning: warning message.
+! NOLOC: OMP: unknown:0:0: Encountered user-directed warning.
+
+! LOC: {{.*}}error_directive.f90:{{[0-9]+}}:{{[0-9]+}}: Encountered user-directed warning: warning message.
+! LOC: {{.*}}error_directive.f90:{{[0-9]+}}:{{[0-9]+}}: Encountered user-directed warning.
diff --git a/openmp/device/src/Misc.cpp b/openmp/device/src/Misc.cpp
index 3393d935bc356..812d0b3beeee6 100644
--- a/openmp/device/src/Misc.cpp
+++ b/openmp/device/src/Misc.cpp
@@ -61,6 +61,46 @@ static FnPtrTy indirectCallLookup(FnPtrTy HstPtr) {
return HstPtr;
}
+/// Split the ";file;function;line;column;;" string carried by an ident into its
+/// filename and line/column. \p File is not NUL-terminated, so \p FileLen gives
+/// its length. Returns false only if the string is missing or malformed; calls
+/// with no debug location parse successfully as "unknown" at 0:0, which the
+/// host runtime also reports.
+static bool getSourceLocation(const IdentTy *Loc, const char *&File,
+ int32_t &FileLen, int32_t &Line,
+ int32_t &Column) {
+ if (!Loc || !Loc->psource || *Loc->psource != ';')
+ return false;
+
+ const char *P = Loc->psource + 1;
+
+ File = P;
+ while (*P && *P != ';')
+ ++P;
+ FileLen = static_cast<int32_t>(P - File);
+ if (*P != ';')
+ return false;
+ ++P;
+
+ // Skip the function name field; it is the mangled kernel name.
+ while (*P && *P != ';')
+ ++P;
+ if (*P != ';')
+ return false;
+ ++P;
+
+ for (Line = 0; *P >= '0' && *P <= '9'; ++P)
+ Line = Line * 10 + (*P - '0');
+ if (*P != ';')
+ return false;
+ ++P;
+
+ for (Column = 0; *P >= '0' && *P <= '9'; ++P)
+ Column = Column * 10 + (*P - '0');
+
+ return true;
+}
+
/// The openmp client instance used to communicate with the server.
[[gnu::visibility("protected"),
gnu::weak]] rpc::Client Client asm("__llvm_rpc_client");
@@ -77,10 +117,19 @@ int32_t __kmpc_cancellationpoint(IdentTy *, int32_t, int32_t) { return 0; }
int32_t __kmpc_cancel(IdentTy *, int32_t, int32_t) { return 0; }
-// TODO: Report the source location from Loc->psource like the host runtime.
-void __kmpc_error(IdentTy *, int32_t Severity, const char *Message) {
+void __kmpc_error(IdentTy *Loc, int32_t Severity, const char *Message) {
const char *Kind = Severity == 1 ? "warning" : "error";
- if (Message)
+ const char *File;
+ int32_t FileLen, Line, Column;
+ bool HasLoc = ompx::impl::getSourceLocation(Loc, File, FileLen, Line, Column);
+
+ if (HasLoc && Message)
+ ompx::printf("OMP: %.*s:%d:%d: Encountered user-directed %s: %s.\n",
+ FileLen, File, Line, Column, Kind, Message);
+ else if (HasLoc)
+ ompx::printf("OMP: %.*s:%d:%d: Encountered user-directed %s.\n", FileLen,
+ File, Line, Column, Kind);
+ else if (Message)
ompx::printf("OMP: Encountered user-directed %s: %s.\n", Kind, Message);
else
ompx::printf("OMP: Encountered user-directed %s.\n", Kind);
>From 992264fb7083f57cf7fe4efc0a35d2c520cb85b9 Mon Sep 17 00:00:00 2001
From: Caroline Newcombe <caroline.newcombe at hpe.com>
Date: Tue, 29 Sep 2026 07:38:58 -0500
Subject: [PATCH 2/2] Add comment
---
openmp/device/src/Misc.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/openmp/device/src/Misc.cpp b/openmp/device/src/Misc.cpp
index 812d0b3beeee6..c7f5da8f50eb6 100644
--- a/openmp/device/src/Misc.cpp
+++ b/openmp/device/src/Misc.cpp
@@ -65,7 +65,8 @@ static FnPtrTy indirectCallLookup(FnPtrTy HstPtr) {
/// filename and line/column. \p File is not NUL-terminated, so \p FileLen gives
/// its length. Returns false only if the string is missing or malformed; calls
/// with no debug location parse successfully as "unknown" at 0:0, which the
-/// host runtime also reports.
+/// host runtime also reports. offload's SourceInfo parses the same format but
+/// needs std::string, which is unavailable here.
static bool getSourceLocation(const IdentTy *Loc, const char *&File,
int32_t &FileLen, int32_t &Line,
int32_t &Column) {
More information about the llvm-commits
mailing list