diff options
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 37 | ||||
| -rw-r--r-- | clang/test/OpenMP/allocate_allocator_messages.cpp | 4 |
3 files changed, 45 insertions, 1 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 39847e07ec0..1644ea97916 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9141,6 +9141,11 @@ def err_omp_invalid_map_this_expr : Error < "invalid 'this' expression on 'map' clause">; def err_implied_omp_allocator_handle_t_not_found : Error< "omp_allocator_handle_t type not found; include <omp.h>">; +def err_omp_expected_predefined_allocator : Error< + "expected one of the predefined allocators for the variables with the static " + "storage: 'omp_default_mem_alloc', 'omp_large_cap_mem_alloc', " + "'omp_const_mem_alloc', 'omp_high_bw_mem_alloc', 'omp_low_lat_mem_alloc', " + "'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc' or 'omp_thread_mem_alloc'">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index f084a0345be..794ca2bee70 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2216,6 +2216,43 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( if (isa<ParmVarDecl>(VD)) continue; + // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ + // If a list item has a static storage type, the allocator expression in the + // allocator clause must be a constant expression that evaluates to one of + // the predefined memory allocator values. + if (Allocator && VD->hasGlobalStorage()) { + bool IsPredefinedAllocator = false; + if (const auto *DRE = + dyn_cast<DeclRefExpr>(Allocator->IgnoreParenImpCasts())) { + if (DRE->getType().isConstant(getASTContext())) { + DeclarationName DN = DRE->getDecl()->getDeclName(); + if (DN.isIdentifier()) { + StringRef PredefinedAllocators[] = { + "omp_default_mem_alloc", "omp_large_cap_mem_alloc", + "omp_const_mem_alloc", "omp_high_bw_mem_alloc", + "omp_low_lat_mem_alloc", "omp_cgroup_mem_alloc", + "omp_pteam_mem_alloc", "omp_thread_mem_alloc", + }; + IsPredefinedAllocator = + llvm::any_of(PredefinedAllocators, [&DN](StringRef S) { + return DN.getAsIdentifierInfo()->isStr(S); + }); + } + } + } + if (!IsPredefinedAllocator) { + Diag(Allocator->getExprLoc(), + diag::err_omp_expected_predefined_allocator) + << Allocator->getSourceRange(); + bool IsDecl = VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + Diag(VD->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) + << VD; + continue; + } + } + Vars.push_back(RefExpr); Attr *A = OMPAllocateDeclAttr::CreateImplicit(Context, Allocator, DE->getSourceRange()); diff --git a/clang/test/OpenMP/allocate_allocator_messages.cpp b/clang/test/OpenMP/allocate_allocator_messages.cpp index 0f616dfb7e0..b5af2b5f71c 100644 --- a/clang/test/OpenMP/allocate_allocator_messages.cpp +++ b/clang/test/OpenMP/allocate_allocator_messages.cpp @@ -20,8 +20,10 @@ struct St1{ int a; static int b; #pragma omp allocate(b) allocator(sss) // expected-error {{initializing 'omp_allocator_handle_t' (aka 'void *') with an expression of incompatible type 'int'}} -} d; +} d; // expected-note 2 {{'d' defined here}} +// expected-error@+1 {{expected one of the predefined allocators for the variables with the static storage: 'omp_default_mem_alloc', 'omp_large_cap_mem_alloc', 'omp_const_mem_alloc', 'omp_high_bw_mem_alloc', 'omp_low_lat_mem_alloc', 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc' or 'omp_thread_mem_alloc'}} #pragma omp allocate(d) allocator(nullptr) extern void *allocator; +// expected-error@+1 {{expected one of the predefined allocators for the variables with the static storage: 'omp_default_mem_alloc', 'omp_large_cap_mem_alloc', 'omp_const_mem_alloc', 'omp_high_bw_mem_alloc', 'omp_low_lat_mem_alloc', 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc' or 'omp_thread_mem_alloc'}} #pragma omp allocate(d) allocator(allocator) |

