https://github.com/zahiraam updated https://github.com/llvm/llvm-project/pull/185918
>From 310f7226b1dbc101823253d99103b4a300f73635 Mon Sep 17 00:00:00 2001 From: Ammarguellat <[email protected]> Date: Wed, 11 Mar 2026 09:38:48 -0700 Subject: [PATCH 1/2] [OpenMP] Map const-qualified target map variables as 'to'. --- clang/lib/Sema/SemaOpenMP.cpp | 38 +++++- clang/test/OpenMP/map_const_aggregate.cpp | 150 ++++++++++++++++++++++ 2 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 clang/test/OpenMP/map_const_aggregate.cpp diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index e8a7c1d5e9288..5ff6b9978cdd8 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3862,7 +3862,8 @@ static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, static OpenMPMapClauseKind getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, - bool IsAggregateOrDeclareTarget) { + bool IsAggregateOrDeclareTarget, + bool HasConstQualifier) { OpenMPMapClauseKind Kind = OMPC_MAP_unknown; switch (M) { case OMPC_DEFAULTMAP_MODIFIER_alloc: @@ -3897,7 +3898,10 @@ getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, // 1. the implicit behavior for aggregate is tofrom // 2. it's a declare target link if (IsAggregateOrDeclareTarget) { - Kind = OMPC_MAP_tofrom; + if (HasConstQualifier) + Kind = OMPC_MAP_to; + else + Kind = OMPC_MAP_tofrom; break; } llvm_unreachable("Unexpected defaultmap implicit behavior"); @@ -3906,6 +3910,30 @@ getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, return Kind; } +static bool hasNoMutableFields(const CXXRecordDecl *RD) { + for (const auto *FD : RD->fields()) { + if (FD->isMutable()) + return false; + QualType FT = FD->getType(); + while (FT->isArrayType()) + FT = FT->getAsArrayTypeUnsafe()->getElementType(); + if (const auto *NestedRD = FT->getAsCXXRecordDecl()) + if (!hasNoMutableFields(NestedRD)) + return false; + } + return true; +} + +static bool hasConstQualifiedMappingType(QualType T) { + while (T->isArrayType()) + T = T->getAsArrayTypeUnsafe()->getElementType(); + if (!T.isConstQualified()) + return false; + if (const auto *RD = T->getAsCXXRecordDecl()) + return hasNoMutableFields(RD); + return true; +} + namespace { struct VariableImplicitInfo { static const unsigned MapKindNum = OMPC_MAP_unknown; @@ -4128,7 +4156,8 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { ImpInfo.Privates.insert(E); } else { OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( - M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); + M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res, + hasConstQualifiedMappingType(E->getType())); ImpInfo.Mappings[ClauseKind][Kind].insert(E); } } @@ -4225,7 +4254,8 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { OpenMPDefaultmapClauseKind ClauseKind = getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD); OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( - Modifier, /*IsAggregateOrDeclareTarget=*/true); + Modifier, /*IsAggregateOrDeclareTarget=*/true, + /*HasConstQualifier=*/false); ImpInfo.Mappings[ClauseKind][Kind].insert(E); return; } diff --git a/clang/test/OpenMP/map_const_aggregate.cpp b/clang/test/OpenMP/map_const_aggregate.cpp new file mode 100644 index 0000000000000..857a525533ca2 --- /dev/null +++ b/clang/test/OpenMP/map_const_aggregate.cpp @@ -0,0 +1,150 @@ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu \ +// RUN: -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// RUN %clang_cc1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu \ +// RUN -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// expected-no-diagnostics + +struct foo { + foo(int j) : i(j) {}; + int i; +}; + +// CHECK: @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 545] +// CHECK: @.offload_maptypes.2 = private unnamed_addr constant [1 x i64] [i64 547] +// CHECK: @.offload_maptypes.4 = private unnamed_addr constant [1 x i64] [i64 547] +// CHECK: @.offload_maptypes.6 = private unnamed_addr constant [1 x i64] [i64 545] +// CHECK: @.offload_maptypes.8 = private unnamed_addr constant [1 x i64] [i64 547] +// CHECK: @.offload_maptypes.10 = private unnamed_addr constant [1 x i64] [i64 545] +// CHECK: @.offload_maptypes.12 = private unnamed_addr constant [1 x i64] [i64 35] +// CHECK: @.offload_maptypes.14 = private unnamed_addr constant [2 x i64] [i64 545, i64 547] + +// Const struct, no mutable members -> mapped 'to' + +// LABEL: test_const_no_mutable +// CHECK: store ptr @.offload_maptypes, ptr {{.*}}, align 8 +void test_const_no_mutable() { + const foo a(2); +#pragma omp target + { + int x = a.i; + } +} + +// Non-const -> mapped 'tofrom' + +// LABEL: define dso_local void @_Z13test_nonconstv +// CHECK: store ptr @.offload_maptypes.2, ptr {{.*}}, align 8 +void test_nonconst() { + foo a(2); +#pragma omp target + { + int x = a.i; + } +} + +struct foo_mutable { + foo_mutable(int j) : i(j), m(0) {}; + int i; + mutable int m; +}; + +// Const struct with a mutable member -> mapped 'tofrom' + +// LABEL: define dso_local void @_Z23test_const_with_mutablev +// CHECK: store ptr @.offload_maptypes.4, ptr {{.*}}, align 8 +void test_const_with_mutable() { + const foo_mutable a(2); +#pragma omp target + { + a.m = 1; + } +} + +struct foo_nested { + foo_nested(int j) : inner(j), z(j) {}; + foo inner; + const int z; +}; + +// Const struct nested inside another const struct -> mapped 'to' + +// LABEL: define dso_local void @_Z17test_const_nestedv() #0 { +// CHECK: store ptr @.offload_maptypes.6, ptr {{.*}}, align 8 +void test_const_nested() { + const foo_nested a(2); +#pragma omp target + { + int x = a.inner.i; + } +} + +struct foo_nested_mutable { + foo_nested_mutable(int j) : inner(j), z(j) {}; + foo_mutable inner; // has mutable member buried inside + const int z; +}; + +// Const struct nested inside another const struct, where the nested +// struct has a mutable member -> mapped 'tofrom' + +// LABEL: define dso_local void @_Z30test_const_nested_with_mutablev +// CHECK: store ptr @.offload_maptypes.8, ptr {{.*}}, align 8 +void test_const_nested_with_mutable() { + const foo_nested_mutable a(2); +#pragma omp target + { + a.inner.m = 1; + } +} + +// Const array of foo -> mapped 'to' + +// LABEL: define dso_local void @_Z16test_const_arrayv +// CHECK: store ptr @.offload_maptypes.10, ptr {{.*}}, align 8 +void test_const_array() { + const foo arr[4] = {1, 2, 3, 4}; +#pragma omp target + { + int x = arr[0].i; + } +} + +// Explicit map(tofrom:) on a const struct -> mapped 'tofrom' + +// LABEL: define dso_local void @_Z27test_explicit_map_overridesv +// CHECK: store ptr @.offload_maptypes.12, ptr {{.*}}, align 8 +void test_explicit_map_overrides() { + const foo a(2); +#pragma omp target map(tofrom:a) + { + int x = a.i; + } +} + +// Mixed: const foo (to) and non-const foo (tofrom) in the same region. + +// LABEL: define dso_local void @_Z10test_mixedv +// CHECK: store ptr @.offload_maptypes.14, ptr {{.*}}, align 8 +void test_mixed() { + const foo ca(2); + foo ma(3); +#pragma omp target + { + int x = ca.i; + ma.i = 99; + } +} + +// Defaultmap(tofrom:aggregate) explicit -> mapped 'to'. + +// LABEL: define dso_local void @_Z31test_defaultmap_tofrom_explicitv +// CHECK: store ptr @.offload_maptypes.16, ptr {{.*}}, align 8 +void test_defaultmap_tofrom_explicit() { + const foo a(2); +#pragma omp target defaultmap(tofrom:aggregate) + { + int x = a.i; + } +} >From 9ea784f31952828283c4aadc9d819bcaa2ba3ab8 Mon Sep 17 00:00:00 2001 From: Ammarguellat <[email protected]> Date: Wed, 11 Mar 2026 09:47:01 -0700 Subject: [PATCH 2/2] Fix format --- clang/lib/Sema/SemaOpenMP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 5ff6b9978cdd8..4a1003a406b35 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3899,7 +3899,7 @@ getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, // 2. it's a declare target link if (IsAggregateOrDeclareTarget) { if (HasConstQualifier) - Kind = OMPC_MAP_to; + Kind = OMPC_MAP_to; else Kind = OMPC_MAP_tofrom; break; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
