[clang] [flang] [clang][OpenMP] Diagnose invalid allocator in `#pragma omp allocate`; avoid null deref (PR #158146)
https://github.com/KrxGu updated
https://github.com/llvm/llvm-project/pull/158146
>From 1d2f9ac071d436e6be4d693833a3b630e4a7fc15 Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Wed, 10 Sep 2025 03:41:06 +0530
Subject: [PATCH 1/2] [flang][OpenMP] Add lowering test: lastprivate on DO is
scoped to wsloop (guards #157035)
---
.../Lower/OpenMP/lastprivate-alloc-scope.f90 | 22 +++
1 file changed, 22 insertions(+)
create mode 100644 flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
diff --git a/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
new file mode 100644
index 0..67d885ed5fb7a
--- /dev/null
+++ b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
@@ -0,0 +1,22 @@
+! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+program p
+ type y3; integer, allocatable :: x; end type
+ type(y3) :: v
+ integer :: s, n, i
+ s = 1; n = 10
+ allocate(v%x); v%x = 0
+!$omp parallel
+ if (.not. allocated(v%x)) print *, '101', allocated(v%x)
+!$omp do schedule(dynamic) lastprivate(v)
+ do i = s, n
+v%x = i
+ end do
+!$omp end do
+!$omp end parallel
+end program
+
+! CHECK: omp.parallel {
+! CHECK-NOT: private(
+! CHECK: omp.wsloop
+! CHECK-SAME: private(
>From 21c05116aab97cdccc6b34864000bd0b7a017a7b Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Fri, 12 Sep 2025 01:40:26 +0530
Subject: [PATCH 2/2] [clang][OpenMP] Avoid null deref in allocator
classification; diagnose missing in (fixes #157868)
---
clang/lib/Sema/SemaOpenMP.cpp| 4 +++-
clang/test/OpenMP/allocate-allocator-duplicate.c | 16
.../test/OpenMP/allocate-allocator-handle-diag.c | 13 +
3 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 clang/test/OpenMP/allocate-allocator-duplicate.c
create mode 100644 clang/test/OpenMP/allocate-allocator-handle-diag.c
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 63a56a6583efc..044edb509e895 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -3321,9 +3321,9 @@ SemaOpenMP::CheckOMPThreadPrivateDecl(SourceLocation Loc,
}
return D;
}
-
static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
+ // No allocator expression → Null mem alloc.
if (!Allocator)
return OMPAllocateDeclAttr::OMPNullMemAlloc;
if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
@@ -3337,6 +3337,8 @@ getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr
*Allocator) {
for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
auto AllocatorKind = static_cast(I);
const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
+if (!DefAllocator)
+ continue; // null-guard: predefined not populated
llvm::FoldingSetNodeID DAEId;
DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
/*Canonical=*/true);
diff --git a/clang/test/OpenMP/allocate-allocator-duplicate.c
b/clang/test/OpenMP/allocate-allocator-duplicate.c
new file mode 100644
index 0..91a294160992c
--- /dev/null
+++ b/clang/test/OpenMP/allocate-allocator-duplicate.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fopenmp -verify %s
+
+typedef enum omp_allocator_handle_t {
+ omp_default_mem_alloc = 1,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void foo(void) {
+ omp_allocator_handle_t my_handle;
+ int A[2];
+ // expected-error@+2 {{'omp_allocator_handle_t' type not found; include
}}
+ // expected-note@+1 {{previous allocator is specified here}}
+ #pragma omp allocate(A) allocator(my_handle)
+ // expected-warning@+1 {{allocate directive specifies 'my_handle' allocator
while previously used default}}
+ #pragma omp allocate(A) allocator(my_handle)
+}
diff --git a/clang/test/OpenMP/allocate-allocator-handle-diag.c
b/clang/test/OpenMP/allocate-allocator-handle-diag.c
new file mode 100644
index 0..07bf68bd9972d
--- /dev/null
+++ b/clang/test/OpenMP/allocate-allocator-handle-diag.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fopenmp -verify %s
+// No ; forge a typedef.
+typedef enum omp_allocator_handle_t {
+ omp_default_mem_alloc = 1,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void foo(void) {
+ omp_allocator_handle_t my_handle;
+ int A[2];
+ // expected-error@+1 {{'omp_allocator_handle_t' type not found; include
}}
+ #pragma omp allocate(A) allocator(my_handle)
+}
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [clang][OpenMP] Diagnose invalid allocator in `#pragma omp allocate`; avoid null deref (PR #158146)
https://github.com/KrxGu closed https://github.com/llvm/llvm-project/pull/158146 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [clang][OpenMP] Diagnose invalid allocator in `#pragma omp allocate`; avoid null deref (PR #158146)
https://github.com/KrxGu updated
https://github.com/llvm/llvm-project/pull/158146
>From 1d2f9ac071d436e6be4d693833a3b630e4a7fc15 Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Wed, 10 Sep 2025 03:41:06 +0530
Subject: [PATCH 1/2] [flang][OpenMP] Add lowering test: lastprivate on DO is
scoped to wsloop (guards #157035)
---
.../Lower/OpenMP/lastprivate-alloc-scope.f90 | 22 +++
1 file changed, 22 insertions(+)
create mode 100644 flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
diff --git a/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
new file mode 100644
index 0..67d885ed5fb7a
--- /dev/null
+++ b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
@@ -0,0 +1,22 @@
+! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+program p
+ type y3; integer, allocatable :: x; end type
+ type(y3) :: v
+ integer :: s, n, i
+ s = 1; n = 10
+ allocate(v%x); v%x = 0
+!$omp parallel
+ if (.not. allocated(v%x)) print *, '101', allocated(v%x)
+!$omp do schedule(dynamic) lastprivate(v)
+ do i = s, n
+v%x = i
+ end do
+!$omp end do
+!$omp end parallel
+end program
+
+! CHECK: omp.parallel {
+! CHECK-NOT: private(
+! CHECK: omp.wsloop
+! CHECK-SAME: private(
>From 21c05116aab97cdccc6b34864000bd0b7a017a7b Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Fri, 12 Sep 2025 01:40:26 +0530
Subject: [PATCH 2/2] [clang][OpenMP] Avoid null deref in allocator
classification; diagnose missing in (fixes #157868)
---
clang/lib/Sema/SemaOpenMP.cpp| 4 +++-
clang/test/OpenMP/allocate-allocator-duplicate.c | 16
.../test/OpenMP/allocate-allocator-handle-diag.c | 13 +
3 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 clang/test/OpenMP/allocate-allocator-duplicate.c
create mode 100644 clang/test/OpenMP/allocate-allocator-handle-diag.c
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 63a56a6583efc..044edb509e895 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -3321,9 +3321,9 @@ SemaOpenMP::CheckOMPThreadPrivateDecl(SourceLocation Loc,
}
return D;
}
-
static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
+ // No allocator expression → Null mem alloc.
if (!Allocator)
return OMPAllocateDeclAttr::OMPNullMemAlloc;
if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
@@ -3337,6 +3337,8 @@ getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr
*Allocator) {
for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
auto AllocatorKind = static_cast(I);
const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
+if (!DefAllocator)
+ continue; // null-guard: predefined not populated
llvm::FoldingSetNodeID DAEId;
DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
/*Canonical=*/true);
diff --git a/clang/test/OpenMP/allocate-allocator-duplicate.c
b/clang/test/OpenMP/allocate-allocator-duplicate.c
new file mode 100644
index 0..91a294160992c
--- /dev/null
+++ b/clang/test/OpenMP/allocate-allocator-duplicate.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fopenmp -verify %s
+
+typedef enum omp_allocator_handle_t {
+ omp_default_mem_alloc = 1,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void foo(void) {
+ omp_allocator_handle_t my_handle;
+ int A[2];
+ // expected-error@+2 {{'omp_allocator_handle_t' type not found; include
}}
+ // expected-note@+1 {{previous allocator is specified here}}
+ #pragma omp allocate(A) allocator(my_handle)
+ // expected-warning@+1 {{allocate directive specifies 'my_handle' allocator
while previously used default}}
+ #pragma omp allocate(A) allocator(my_handle)
+}
diff --git a/clang/test/OpenMP/allocate-allocator-handle-diag.c
b/clang/test/OpenMP/allocate-allocator-handle-diag.c
new file mode 100644
index 0..07bf68bd9972d
--- /dev/null
+++ b/clang/test/OpenMP/allocate-allocator-handle-diag.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fopenmp -verify %s
+// No ; forge a typedef.
+typedef enum omp_allocator_handle_t {
+ omp_default_mem_alloc = 1,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void foo(void) {
+ omp_allocator_handle_t my_handle;
+ int A[2];
+ // expected-error@+1 {{'omp_allocator_handle_t' type not found; include
}}
+ #pragma omp allocate(A) allocator(my_handle)
+}
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [clang][OpenMP] Diagnose invalid allocator in `#pragma omp allocate`; avoid null deref (PR #158146)
https://github.com/KrxGu created
https://github.com/llvm/llvm-project/pull/158146
Reproducer without (forged `omp_allocator_handle_t`) crashed in
SemaOpenMP
(null deref while classifying the allocator).
Fix:
- Null-guard predefined allocator lookup in getAllocatorKind.
- Keep user-defined as fallback; emit existing diagnostic for missing/invalid
handle.
Tests:
- OpenMP/allocate-allocator-handle-diag.c: expects the diagnostic.
- OpenMP/allocate-allocator-duplicate.c: single diagnostic, no crash.
https://github.com/user-attachments/assets/590242a7-0206-4ac5-b142-f595ddc0ac64";
/>
https://github.com/user-attachments/assets/8f68d398-d6ad-4dd7-a600-8b51b6cfab37";
/>
complete build check:
https://github.com/user-attachments/assets/2f5caa9d-312f-4580-aab6-c51297174460";
/>
no crash (error is expected):
https://github.com/user-attachments/assets/6bfee6e5-a5ed-4944-afce-428108a2fec4";
/>
Fixes #157868.
>From 1d2f9ac071d436e6be4d693833a3b630e4a7fc15 Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Wed, 10 Sep 2025 03:41:06 +0530
Subject: [PATCH 1/2] [flang][OpenMP] Add lowering test: lastprivate on DO is
scoped to wsloop (guards #157035)
---
.../Lower/OpenMP/lastprivate-alloc-scope.f90 | 22 +++
1 file changed, 22 insertions(+)
create mode 100644 flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
diff --git a/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
new file mode 100644
index 0..67d885ed5fb7a
--- /dev/null
+++ b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
@@ -0,0 +1,22 @@
+! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+program p
+ type y3; integer, allocatable :: x; end type
+ type(y3) :: v
+ integer :: s, n, i
+ s = 1; n = 10
+ allocate(v%x); v%x = 0
+!$omp parallel
+ if (.not. allocated(v%x)) print *, '101', allocated(v%x)
+!$omp do schedule(dynamic) lastprivate(v)
+ do i = s, n
+v%x = i
+ end do
+!$omp end do
+!$omp end parallel
+end program
+
+! CHECK: omp.parallel {
+! CHECK-NOT: private(
+! CHECK: omp.wsloop
+! CHECK-SAME: private(
>From 1055e5041aaa57281b032d11cbf7a4f23add52a7 Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Fri, 12 Sep 2025 01:40:26 +0530
Subject: [PATCH 2/2] [clang][OpenMP] Avoid null deref in allocator
classification; diagnose missing in (fixes #157868)
---
clang/lib/Sema/SemaOpenMP.cpp | 41 ++-
.../OpenMP/allocate-allocator-duplicate.c | 16
.../OpenMP/allocate-allocator-handle-diag.c | 13 ++
3 files changed, 51 insertions(+), 19 deletions(-)
create mode 100644 clang/test/OpenMP/allocate-allocator-duplicate.c
create mode 100644 clang/test/OpenMP/allocate-allocator-handle-diag.c
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 63a56a6583efc..1af8ed20f24e2 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -3321,27 +3321,33 @@ SemaOpenMP::CheckOMPThreadPrivateDecl(SourceLocation
Loc,
}
return D;
}
-
static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
+ // No allocator expression → Null mem alloc (matches existing tests).
if (!Allocator)
return OMPAllocateDeclAttr::OMPNullMemAlloc;
+
if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
Allocator->isInstantiationDependent() ||
Allocator->containsUnexpandedParameterPack())
return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
+
auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
+
llvm::FoldingSetNodeID AEId;
const Expr *AE = Allocator->IgnoreParenImpCasts();
- AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
+ AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
+
for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
-auto AllocatorKind = static_cast(I);
-const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
+auto K = static_cast(I);
+const Expr *Def = Stack->getAllocator(K);
+if (!Def)
+ continue;
llvm::FoldingSetNodeID DAEId;
-DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
-/*Canonical=*/true);
+Def->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
+ /*Canonical=*/true);
if (AEId == DAEId) {
- AllocatorKindRes = AllocatorKind;
+ AllocatorKindRes = K;
break;
}
}
@@ -3353,10 +3359,12 @@ static bool checkPreviousOMPAllocateAttribute(
OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
if (!VD->hasAttr())
return false;
+
const auto *A = VD->getAttr();
Expr *PrevAllocator = A->getAllocator();
OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
getAllocatorKind(S, Stack, PrevAllocator);
+
bool AllocatorsMatch = AllocatorKind == PrevAllocato
[clang] [flang] [clang][OpenMP] Diagnose invalid allocator in `#pragma omp allocate`; avoid null deref (PR #158146)
https://github.com/KrxGu updated
https://github.com/llvm/llvm-project/pull/158146
>From 1d2f9ac071d436e6be4d693833a3b630e4a7fc15 Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Wed, 10 Sep 2025 03:41:06 +0530
Subject: [PATCH 1/2] [flang][OpenMP] Add lowering test: lastprivate on DO is
scoped to wsloop (guards #157035)
---
.../Lower/OpenMP/lastprivate-alloc-scope.f90 | 22 +++
1 file changed, 22 insertions(+)
create mode 100644 flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
diff --git a/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
new file mode 100644
index 0..67d885ed5fb7a
--- /dev/null
+++ b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
@@ -0,0 +1,22 @@
+! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+program p
+ type y3; integer, allocatable :: x; end type
+ type(y3) :: v
+ integer :: s, n, i
+ s = 1; n = 10
+ allocate(v%x); v%x = 0
+!$omp parallel
+ if (.not. allocated(v%x)) print *, '101', allocated(v%x)
+!$omp do schedule(dynamic) lastprivate(v)
+ do i = s, n
+v%x = i
+ end do
+!$omp end do
+!$omp end parallel
+end program
+
+! CHECK: omp.parallel {
+! CHECK-NOT: private(
+! CHECK: omp.wsloop
+! CHECK-SAME: private(
>From 21c05116aab97cdccc6b34864000bd0b7a017a7b Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Fri, 12 Sep 2025 01:40:26 +0530
Subject: [PATCH 2/2] [clang][OpenMP] Avoid null deref in allocator
classification; diagnose missing in (fixes #157868)
---
clang/lib/Sema/SemaOpenMP.cpp| 4 +++-
clang/test/OpenMP/allocate-allocator-duplicate.c | 16
.../test/OpenMP/allocate-allocator-handle-diag.c | 13 +
3 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 clang/test/OpenMP/allocate-allocator-duplicate.c
create mode 100644 clang/test/OpenMP/allocate-allocator-handle-diag.c
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 63a56a6583efc..044edb509e895 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -3321,9 +3321,9 @@ SemaOpenMP::CheckOMPThreadPrivateDecl(SourceLocation Loc,
}
return D;
}
-
static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
+ // No allocator expression → Null mem alloc.
if (!Allocator)
return OMPAllocateDeclAttr::OMPNullMemAlloc;
if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
@@ -3337,6 +3337,8 @@ getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr
*Allocator) {
for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
auto AllocatorKind = static_cast(I);
const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
+if (!DefAllocator)
+ continue; // null-guard: predefined not populated
llvm::FoldingSetNodeID DAEId;
DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
/*Canonical=*/true);
diff --git a/clang/test/OpenMP/allocate-allocator-duplicate.c
b/clang/test/OpenMP/allocate-allocator-duplicate.c
new file mode 100644
index 0..91a294160992c
--- /dev/null
+++ b/clang/test/OpenMP/allocate-allocator-duplicate.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fopenmp -verify %s
+
+typedef enum omp_allocator_handle_t {
+ omp_default_mem_alloc = 1,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void foo(void) {
+ omp_allocator_handle_t my_handle;
+ int A[2];
+ // expected-error@+2 {{'omp_allocator_handle_t' type not found; include
}}
+ // expected-note@+1 {{previous allocator is specified here}}
+ #pragma omp allocate(A) allocator(my_handle)
+ // expected-warning@+1 {{allocate directive specifies 'my_handle' allocator
while previously used default}}
+ #pragma omp allocate(A) allocator(my_handle)
+}
diff --git a/clang/test/OpenMP/allocate-allocator-handle-diag.c
b/clang/test/OpenMP/allocate-allocator-handle-diag.c
new file mode 100644
index 0..07bf68bd9972d
--- /dev/null
+++ b/clang/test/OpenMP/allocate-allocator-handle-diag.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fopenmp -verify %s
+// No ; forge a typedef.
+typedef enum omp_allocator_handle_t {
+ omp_default_mem_alloc = 1,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void foo(void) {
+ omp_allocator_handle_t my_handle;
+ int A[2];
+ // expected-error@+1 {{'omp_allocator_handle_t' type not found; include
}}
+ #pragma omp allocate(A) allocator(my_handle)
+}
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [clang][OpenMP] Diagnose invalid allocator in `#pragma omp allocate`; avoid null deref (PR #158146)
https://github.com/KrxGu updated
https://github.com/llvm/llvm-project/pull/158146
>From 1d2f9ac071d436e6be4d693833a3b630e4a7fc15 Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Wed, 10 Sep 2025 03:41:06 +0530
Subject: [PATCH 1/2] [flang][OpenMP] Add lowering test: lastprivate on DO is
scoped to wsloop (guards #157035)
---
.../Lower/OpenMP/lastprivate-alloc-scope.f90 | 22 +++
1 file changed, 22 insertions(+)
create mode 100644 flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
diff --git a/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
new file mode 100644
index 0..67d885ed5fb7a
--- /dev/null
+++ b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
@@ -0,0 +1,22 @@
+! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+program p
+ type y3; integer, allocatable :: x; end type
+ type(y3) :: v
+ integer :: s, n, i
+ s = 1; n = 10
+ allocate(v%x); v%x = 0
+!$omp parallel
+ if (.not. allocated(v%x)) print *, '101', allocated(v%x)
+!$omp do schedule(dynamic) lastprivate(v)
+ do i = s, n
+v%x = i
+ end do
+!$omp end do
+!$omp end parallel
+end program
+
+! CHECK: omp.parallel {
+! CHECK-NOT: private(
+! CHECK: omp.wsloop
+! CHECK-SAME: private(
>From 21c05116aab97cdccc6b34864000bd0b7a017a7b Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Fri, 12 Sep 2025 01:40:26 +0530
Subject: [PATCH 2/2] [clang][OpenMP] Avoid null deref in allocator
classification; diagnose missing in (fixes #157868)
---
clang/lib/Sema/SemaOpenMP.cpp| 4 +++-
clang/test/OpenMP/allocate-allocator-duplicate.c | 16
.../test/OpenMP/allocate-allocator-handle-diag.c | 13 +
3 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 clang/test/OpenMP/allocate-allocator-duplicate.c
create mode 100644 clang/test/OpenMP/allocate-allocator-handle-diag.c
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 63a56a6583efc..044edb509e895 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -3321,9 +3321,9 @@ SemaOpenMP::CheckOMPThreadPrivateDecl(SourceLocation Loc,
}
return D;
}
-
static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
+ // No allocator expression → Null mem alloc.
if (!Allocator)
return OMPAllocateDeclAttr::OMPNullMemAlloc;
if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
@@ -3337,6 +3337,8 @@ getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr
*Allocator) {
for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
auto AllocatorKind = static_cast(I);
const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
+if (!DefAllocator)
+ continue; // null-guard: predefined not populated
llvm::FoldingSetNodeID DAEId;
DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
/*Canonical=*/true);
diff --git a/clang/test/OpenMP/allocate-allocator-duplicate.c
b/clang/test/OpenMP/allocate-allocator-duplicate.c
new file mode 100644
index 0..91a294160992c
--- /dev/null
+++ b/clang/test/OpenMP/allocate-allocator-duplicate.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fopenmp -verify %s
+
+typedef enum omp_allocator_handle_t {
+ omp_default_mem_alloc = 1,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void foo(void) {
+ omp_allocator_handle_t my_handle;
+ int A[2];
+ // expected-error@+2 {{'omp_allocator_handle_t' type not found; include
}}
+ // expected-note@+1 {{previous allocator is specified here}}
+ #pragma omp allocate(A) allocator(my_handle)
+ // expected-warning@+1 {{allocate directive specifies 'my_handle' allocator
while previously used default}}
+ #pragma omp allocate(A) allocator(my_handle)
+}
diff --git a/clang/test/OpenMP/allocate-allocator-handle-diag.c
b/clang/test/OpenMP/allocate-allocator-handle-diag.c
new file mode 100644
index 0..07bf68bd9972d
--- /dev/null
+++ b/clang/test/OpenMP/allocate-allocator-handle-diag.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fopenmp -verify %s
+// No ; forge a typedef.
+typedef enum omp_allocator_handle_t {
+ omp_default_mem_alloc = 1,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void foo(void) {
+ omp_allocator_handle_t my_handle;
+ int A[2];
+ // expected-error@+1 {{'omp_allocator_handle_t' type not found; include
}}
+ #pragma omp allocate(A) allocator(my_handle)
+}
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [clang][OpenMP] Diagnose invalid allocator in `#pragma omp allocate`; avoid null deref (PR #158146)
KrxGu wrote: @shafik reverted the comments, brought back `k`, have tested and built again everything working fine. https://github.com/llvm/llvm-project/pull/158146 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [clang][OpenMP] Diagnose invalid allocator in `#pragma omp allocate`; avoid null deref (PR #158146)
https://github.com/KrxGu updated
https://github.com/llvm/llvm-project/pull/158146
>From 1d2f9ac071d436e6be4d693833a3b630e4a7fc15 Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Wed, 10 Sep 2025 03:41:06 +0530
Subject: [PATCH 1/2] [flang][OpenMP] Add lowering test: lastprivate on DO is
scoped to wsloop (guards #157035)
---
.../Lower/OpenMP/lastprivate-alloc-scope.f90 | 22 +++
1 file changed, 22 insertions(+)
create mode 100644 flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
diff --git a/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
new file mode 100644
index 0..67d885ed5fb7a
--- /dev/null
+++ b/flang/test/Lower/OpenMP/lastprivate-alloc-scope.f90
@@ -0,0 +1,22 @@
+! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+program p
+ type y3; integer, allocatable :: x; end type
+ type(y3) :: v
+ integer :: s, n, i
+ s = 1; n = 10
+ allocate(v%x); v%x = 0
+!$omp parallel
+ if (.not. allocated(v%x)) print *, '101', allocated(v%x)
+!$omp do schedule(dynamic) lastprivate(v)
+ do i = s, n
+v%x = i
+ end do
+!$omp end do
+!$omp end parallel
+end program
+
+! CHECK: omp.parallel {
+! CHECK-NOT: private(
+! CHECK: omp.wsloop
+! CHECK-SAME: private(
>From 21c05116aab97cdccc6b34864000bd0b7a017a7b Mon Sep 17 00:00:00 2001
From: Krish Gupta
Date: Fri, 12 Sep 2025 01:40:26 +0530
Subject: [PATCH 2/2] [clang][OpenMP] Avoid null deref in allocator
classification; diagnose missing in (fixes #157868)
---
clang/lib/Sema/SemaOpenMP.cpp| 4 +++-
clang/test/OpenMP/allocate-allocator-duplicate.c | 16
.../test/OpenMP/allocate-allocator-handle-diag.c | 13 +
3 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 clang/test/OpenMP/allocate-allocator-duplicate.c
create mode 100644 clang/test/OpenMP/allocate-allocator-handle-diag.c
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 63a56a6583efc..044edb509e895 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -3321,9 +3321,9 @@ SemaOpenMP::CheckOMPThreadPrivateDecl(SourceLocation Loc,
}
return D;
}
-
static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
+ // No allocator expression → Null mem alloc.
if (!Allocator)
return OMPAllocateDeclAttr::OMPNullMemAlloc;
if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
@@ -3337,6 +3337,8 @@ getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr
*Allocator) {
for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
auto AllocatorKind = static_cast(I);
const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
+if (!DefAllocator)
+ continue; // null-guard: predefined not populated
llvm::FoldingSetNodeID DAEId;
DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
/*Canonical=*/true);
diff --git a/clang/test/OpenMP/allocate-allocator-duplicate.c
b/clang/test/OpenMP/allocate-allocator-duplicate.c
new file mode 100644
index 0..91a294160992c
--- /dev/null
+++ b/clang/test/OpenMP/allocate-allocator-duplicate.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fopenmp -verify %s
+
+typedef enum omp_allocator_handle_t {
+ omp_default_mem_alloc = 1,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void foo(void) {
+ omp_allocator_handle_t my_handle;
+ int A[2];
+ // expected-error@+2 {{'omp_allocator_handle_t' type not found; include
}}
+ // expected-note@+1 {{previous allocator is specified here}}
+ #pragma omp allocate(A) allocator(my_handle)
+ // expected-warning@+1 {{allocate directive specifies 'my_handle' allocator
while previously used default}}
+ #pragma omp allocate(A) allocator(my_handle)
+}
diff --git a/clang/test/OpenMP/allocate-allocator-handle-diag.c
b/clang/test/OpenMP/allocate-allocator-handle-diag.c
new file mode 100644
index 0..07bf68bd9972d
--- /dev/null
+++ b/clang/test/OpenMP/allocate-allocator-handle-diag.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fopenmp -verify %s
+// No ; forge a typedef.
+typedef enum omp_allocator_handle_t {
+ omp_default_mem_alloc = 1,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void foo(void) {
+ omp_allocator_handle_t my_handle;
+ int A[2];
+ // expected-error@+1 {{'omp_allocator_handle_t' type not found; include
}}
+ #pragma omp allocate(A) allocator(my_handle)
+}
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
