From c1e4e8b66b8cc9ef54bc6484cb724e664798ae57 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Fri, 22 Mar 2019 14:41:39 +0000 Subject: [PATCH] [OPENMP]Emit error message for allocate directive without allocator clause in target region. According to the OpenMP 5.0, 2.11.3 allocate Directive, Restrictions, allocate directives that appear in a target region must specify an allocator clause unless a requires directive with the dynamic_allocators clause is present in the same compilation unit. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356752 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 3 + lib/Sema/SemaOpenMP.cpp | 6 +- test/OpenMP/nvptx_allocate_codegen.cpp | 2 +- test/OpenMP/nvptx_allocate_messages.cpp | 80 ++++++++++++++++++++++ 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 test/OpenMP/nvptx_allocate_messages.cpp diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 8b5ce42771..a8776d9b43 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -9152,6 +9152,9 @@ def warn_omp_used_different_allocator : Warning< InGroup; def note_omp_previous_allocator : Note< "previous allocator is specified here">; +def err_expected_allocator_clause : Error<"expected an 'allocator' clause " + "inside of the target region; provide an 'allocator' clause or use 'requires'" + " directive with the 'dynamic_allocators' clause">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index e54652650e..9232ab9d6e 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -2243,8 +2243,12 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( ArrayRef Clauses, DeclContext *Owner) { assert(Clauses.size() <= 1 && "Expected at most one clause."); Expr *Allocator = nullptr; - if (!Clauses.empty()) + if (Clauses.empty()) { + if (LangOpts.OpenMPIsDevice) + targetDiag(Loc, diag::err_expected_allocator_clause); + } else { Allocator = cast(Clauses.back())->getAllocator(); + } OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = getAllocatorKind(*this, DSAStack, Allocator); SmallVector Vars; diff --git a/test/OpenMP/nvptx_allocate_codegen.cpp b/test/OpenMP/nvptx_allocate_codegen.cpp index df6a727c7a..ec1faff426 100644 --- a/test/OpenMP/nvptx_allocate_codegen.cpp +++ b/test/OpenMP/nvptx_allocate_codegen.cpp @@ -64,7 +64,7 @@ int main () { #pragma omp allocate(a) allocator(omp_thread_mem_alloc) a=2; double b = 3; -#pragma omp allocate(b) +#pragma omp allocate(b) allocator(omp_default_mem_alloc) return (foo()); } diff --git a/test/OpenMP/nvptx_allocate_messages.cpp b/test/OpenMP/nvptx_allocate_messages.cpp new file mode 100644 index 0000000000..99aef4338d --- /dev/null +++ b/test/OpenMP/nvptx_allocate_messages.cpp @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-apple-darwin10.6.0 -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc -o %t-host.bc %s +// RUN: %clang_cc1 -verify -DDEVICE -fopenmp -triple nvptx64-nvidia-cuda -fopenmp-targets=nvptx64-nvidia-cuda -fsyntax-only %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc +#ifndef DEVICE +// expected-no-diagnostics +#endif // DEVICE + +#ifndef HEADER +#define HEADER + +int bar() { + int res = 0; +#ifdef DEVICE +// expected-error@+2 {{expected an 'allocator' clause inside of the target region; provide an 'allocator' clause or use 'requires' directive with the 'dynamic_allocators' clause}} +#endif // DEVICE +#pragma omp allocate(res) + return 0; +} + +#pragma omp declare target +typedef void **omp_allocator_handle_t; +extern const omp_allocator_handle_t omp_default_mem_alloc; +extern const omp_allocator_handle_t omp_large_cap_mem_alloc; +extern const omp_allocator_handle_t omp_const_mem_alloc; +extern const omp_allocator_handle_t omp_high_bw_mem_alloc; +extern const omp_allocator_handle_t omp_low_lat_mem_alloc; +extern const omp_allocator_handle_t omp_cgroup_mem_alloc; +extern const omp_allocator_handle_t omp_pteam_mem_alloc; +extern const omp_allocator_handle_t omp_thread_mem_alloc; + +struct St{ + int a; +}; + +struct St1{ + int a; + static int b; +#pragma omp allocate(b) allocator(omp_default_mem_alloc) +} d; + +int a, b, c; +#pragma omp allocate(a) allocator(omp_large_cap_mem_alloc) +#pragma omp allocate(b) allocator(omp_const_mem_alloc) +#pragma omp allocate(d, c) allocator(omp_high_bw_mem_alloc) + +template +struct ST { + static T m; + #pragma omp allocate(m) allocator(omp_low_lat_mem_alloc) +}; + +template T foo() { + T v; + #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc) + v = ST::m; + return v; +} + +namespace ns{ + int a; +} +#pragma omp allocate(ns::a) allocator(omp_pteam_mem_alloc) + +int main () { + static int a; +#pragma omp allocate(a) allocator(omp_thread_mem_alloc) + a=2; + double b = 3; +#ifdef DEVICE +// expected-error@+2 {{expected an 'allocator' clause inside of the target region; provide an 'allocator' clause or use 'requires' directive with the 'dynamic_allocators' clause}} +#endif // DEVICE +#pragma omp allocate(b) +#ifdef DEVICE +// expected-note@+2 {{called by 'main'}} +#endif // DEVICE + return (foo() + bar()); +} + +extern template int ST::m; +#pragma omp end declare target +#endif -- 2.50.1