[clang] ff295d2 - [OpenMP][clang] declare mapper: fix handling of nested types (#143504)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Jun 14 07:17:12 PDT 2025
Author: Robert Imschweiler
Date: 2025-06-14T16:17:08+02:00
New Revision: ff295d2f3429a5a2a93b2c86099af40544f467d4
URL: https://github.com/llvm/llvm-project/commit/ff295d2f3429a5a2a93b2c86099af40544f467d4
DIFF: https://github.com/llvm/llvm-project/commit/ff295d2f3429a5a2a93b2c86099af40544f467d4.diff
LOG: [OpenMP][clang] declare mapper: fix handling of nested types (#143504)
Fix a crash that happened during parsing of a "declare mapper" construct
for a struct that contains an element for which we also declared a
custom default mapper.
Added:
Modified:
clang/include/clang/Sema/SemaOpenMP.h
clang/lib/Parse/ParseOpenMP.cpp
clang/test/OpenMP/declare_mapper_ast_print.c
clang/test/OpenMP/declare_mapper_ast_print.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h
index be6bec2068784..7b169f56b6807 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -283,7 +283,7 @@ class SemaOpenMP : public SemaBase {
/// mapper' construct.
QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
TypeResult ParsedType);
- /// Called on start of '#pragma omp declare mapper'.
+ /// Called for '#pragma omp declare mapper'.
DeclGroupPtrTy ActOnOpenMPDeclareMapperDirective(
Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index def1a52ba7d4a..78d3503d8eb68 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -576,6 +576,7 @@ Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
return DeclGroupPtrTy();
}
+ Scope *OuterScope = getCurScope();
// Enter scope.
DeclarationNameInfo DirName;
SourceLocation Loc = Tok.getLocation();
@@ -614,12 +615,17 @@ Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
IsCorrect = false;
}
+ // This needs to be called within the scope because
+ // processImplicitMapsWithDefaultMappers may add clauses when analyzing nested
+ // types. The scope used for calling ActOnOpenMPDeclareMapperDirective,
+ // however, needs to be the outer one, otherwise declared mappers don't become
+ // visible.
+ DeclGroupPtrTy DG = Actions.OpenMP().ActOnOpenMPDeclareMapperDirective(
+ OuterScope, Actions.getCurLexicalContext(), MapperId, MapperType,
+ Range.getBegin(), VName, AS, MapperVarRef.get(), Clauses);
// Exit scope.
Actions.OpenMP().EndOpenMPDSABlock(nullptr);
OMPDirectiveScope.Exit();
- DeclGroupPtrTy DG = Actions.OpenMP().ActOnOpenMPDeclareMapperDirective(
- getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
- Range.getBegin(), VName, AS, MapperVarRef.get(), Clauses);
if (!IsCorrect)
return DeclGroupPtrTy();
diff --git a/clang/test/OpenMP/declare_mapper_ast_print.c b/clang/test/OpenMP/declare_mapper_ast_print.c
index 3c554a106fe49..bb83f23a0c18a 100644
--- a/clang/test/OpenMP/declare_mapper_ast_print.c
+++ b/clang/test/OpenMP/declare_mapper_ast_print.c
@@ -49,6 +49,23 @@ struct dat {
#pragma omp declare mapper(struct dat d) map(to: d.d)
// CHECK: #pragma omp declare mapper (default : struct dat d) map(to: d.d){{$}}
+// Verify that nested default mappers do not lead to a crash during parsing / sema.
+// CHECK: struct inner {
+struct inner {
+ int size;
+ int *data;
+};
+#pragma omp declare mapper(struct inner i) map(i, i.data[0 : i.size])
+// CHECK: #pragma omp declare mapper (default : struct inner i) map(tofrom: default::i,i.data[0:i.size]){{$}}
+
+// CHECK: struct outer {
+struct outer {
+ int a;
+ struct inner i;
+};
+#pragma omp declare mapper(struct outer o) map(o)
+// CHECK: #pragma omp declare mapper (default : struct outer o) map(tofrom: default::o) map(tofrom: o.i){{$}}
+
// CHECK: int main(void) {
int main(void) {
#pragma omp declare mapper(id: struct vec v) map(v.len)
@@ -77,6 +94,14 @@ int main(void) {
#pragma omp declare mapper(id1: struct vec vvec) map(iterator(it=0:vvec.len:2), tofrom:vvec.data[it])
// OMP52: #pragma omp declare mapper (id1 : struct vec vvec) map(iterator(int it = 0:vvec.len:2),tofrom: vvec.data[it]);
#endif
+
+ {
+ struct outer outer;
+#pragma omp target map(outer)
+// CHECK: #pragma omp target map(tofrom: outer)
+ { }
+ }
+
return 0;
}
// CHECK: }
diff --git a/clang/test/OpenMP/declare_mapper_ast_print.cpp b/clang/test/OpenMP/declare_mapper_ast_print.cpp
index 422fa9981672e..9ca3412e3e3d9 100644
--- a/clang/test/OpenMP/declare_mapper_ast_print.cpp
+++ b/clang/test/OpenMP/declare_mapper_ast_print.cpp
@@ -34,6 +34,28 @@ class vecchild : public vec {
// CHECK: }
// CHECK: ;
+// Verify that nested default mappers do not lead to a crash during parsing / sema.
+// CHECK: namespace N2 {
+namespace N2
+{
+// CHECK: struct inner {
+struct inner {
+ int size;
+ int *data;
+};
+#pragma omp declare mapper(struct inner i) map(i, i.data[0 : i.size])
+// CHECK: #pragma omp declare mapper (default : struct inner i) map(tofrom: N2::default::i,i.data[0:i.size]){{$}}
+
+// CHECK: struct outer {
+struct outer {
+ int a;
+ struct inner i;
+};
+#pragma omp declare mapper(struct outer o) map(o)
+// CHECK: #pragma omp declare mapper (default : struct outer o) map(tofrom: N2::default::o) map(tofrom: o.i){{$}}
+} // namespace N2
+// CHECK: }
+
template <class T>
class dat {
public:
@@ -122,6 +144,7 @@ T foo(T a) {
int main() {
N1::vec vv, vvv;
N1::vecchild vc;
+ N2::outer outer;
dat<double> dd;
#pragma omp target map(mapper(N1::id) tofrom: vv) map(mapper(dat<double>::id) alloc: vvv)
// CHECK: #pragma omp target map(mapper(N1::id),tofrom: vv) map(mapper(dat<double>::id),alloc: vvv)
@@ -132,6 +155,9 @@ int main() {
#pragma omp target map(mapper(default) tofrom: dd)
// CHECK: #pragma omp target map(mapper(default),tofrom: dd)
{ dd.d++; }
+#pragma omp target map(outer)
+// CHECK: #pragma omp target map(tofrom: outer)
+ { }
#pragma omp target update to(mapper(N1::id) : vc)
// CHECK: #pragma omp target update to(mapper(N1::id): vc)
More information about the cfe-commits
mailing list