"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 {
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());
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)