Author: Alexey Bataev Date: 2020-03-20T15:45:31-04:00 New Revision: 9b95929a26e133bc3cae9f29f91e8e351d233840
URL: https://github.com/llvm/llvm-project/commit/9b95929a26e133bc3cae9f29f91e8e351d233840 DIFF: https://github.com/llvm/llvm-project/commit/9b95929a26e133bc3cae9f29f91e8e351d233840.diff LOG: [OPENMP50]Do not allow several scan directives in the same parent region. According to OpenMP 5.0, exactly one scan directive must appear in the loop body of an enclosing worksharing-loop, worksharing-loop SIMD, or simd construct on which a reduction clause with the inscan modifier is present. Added: Modified: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaOpenMP.cpp clang/test/OpenMP/scan_messages.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 39d29060372f..90845ecf5468 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9833,6 +9833,10 @@ def err_omp_prohibited_region_critical_same_name : Error< "cannot nest 'critical' regions having the same name %0">; def note_omp_previous_critical_region : Note< "previous 'critical' region starts here">; +def err_omp_several_scan_directives_in_region : Error< + "exactly one 'scan' directive must appear in the loop body of an enclosing directive">; +def note_omp_previous_scan_directive : Note< + "previous 'scan' directive used here">; def err_omp_sections_not_compound_stmt : Error< "the statement for '#pragma omp sections' must be a compound statement">; def err_omp_parallel_sections_not_compound_stmt : Error< diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 861b75a774d8..309ab4afa69d 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -154,6 +154,7 @@ class DSAStackTy { bool CancelRegion = false; bool LoopStart = false; bool BodyComplete = false; + SourceLocation PrevScanLocation; SourceLocation InnerTeamsRegionLoc; /// Reference to the taskgroup task_reduction reference expression. Expr *TaskgroupReductionRef = nullptr; @@ -781,6 +782,22 @@ class DSAStackTy { return Top ? Top->CancelRegion : false; } + /// Mark that parent region already has scan directive. + void setParentHasScanDirective(SourceLocation Loc) { + if (SharingMapTy *Parent = getSecondOnStackOrNull()) + Parent->PrevScanLocation = Loc; + } + /// Return true if current region has inner cancel construct. + bool doesParentHasScanDirective() const { + const SharingMapTy *Top = getSecondOnStackOrNull(); + return Top ? Top->PrevScanLocation.isValid() : false; + } + /// Return true if current region has inner cancel construct. + SourceLocation getParentScanDirectiveLoc() const { + const SharingMapTy *Top = getSecondOnStackOrNull(); + return Top ? Top->PrevScanLocation : SourceLocation(); + } + /// Set collapse value for the region. void setAssociatedLoops(unsigned Val) { getTopOfStack().AssociatedLoops = Val; @@ -8795,11 +8812,21 @@ StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc) { + // Check that exactly one clause is specified. if (Clauses.size() != 1) { Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), diag::err_omp_scan_single_clause_expected); return StmtError(); } + // Check that only one instance of scan directives is used in the same outer + // region. + if (DSAStack->doesParentHasScanDirective()) { + Diag(StartLoc, diag::err_omp_several_scan_directives_in_region); + Diag(DSAStack->getParentScanDirectiveLoc(), + diag::note_omp_previous_scan_directive); + return StmtError(); + } + DSAStack->setParentHasScanDirective(StartLoc); return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); } diff --git a/clang/test/OpenMP/scan_messages.cpp b/clang/test/OpenMP/scan_messages.cpp index ea4e273e9d0b..3be998d0f96e 100644 --- a/clang/test/OpenMP/scan_messages.cpp +++ b/clang/test/OpenMP/scan_messages.cpp @@ -54,12 +54,12 @@ T tmain(T argc) { #pragma omp simd for (int i = 0; i < 10; ++i) switch (argc) { -#pragma omp scan inclusive(argc) +#pragma omp scan inclusive(argc) // expected-note 2 {{previous 'scan' directive used here}} case 1: -#pragma omp scan inclusive(argc) +#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}} break; default: { -#pragma omp scan inclusive(argc) +#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}} } break; } #pragma omp simd @@ -133,12 +133,12 @@ int main(int argc, char **argv) { #pragma omp simd for (int i = 0; i < 10; ++i) switch (argc) { -#pragma omp scan inclusive(argc) +#pragma omp scan inclusive(argc) // expected-note 2 {{previous 'scan' directive used here}} case 1: -#pragma omp scan inclusive(argc) +#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}} break; default: { -#pragma omp scan inclusive(argc) +#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}} } break; } #pragma omp simd _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits