From: Alexey Bataev Date: Tue, 19 Mar 2019 18:39:11 +0000 (+0000) Subject: [OPENMP]Check that global vars require predefined allocator. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=23e5d23710c537c358580c137a3f1ea10c425b9c;p=clang [OPENMP]Check that global vars require predefined allocator. According to 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. Added check for this restriction. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356496 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 39847e07ec..1644ea9791 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/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 ">; +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/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index f084a0345b..794ca2bee7 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -2216,6 +2216,43 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( if (isa(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(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/test/OpenMP/allocate_allocator_messages.cpp b/test/OpenMP/allocate_allocator_messages.cpp index 0f616dfb7e..b5af2b5f71 100644 --- a/test/OpenMP/allocate_allocator_messages.cpp +++ b/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)