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) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits