Author: gbercea Date: Thu Apr 18 12:53:43 2019 New Revision: 358709 URL: http://llvm.org/viewvc/llvm-project?rev=358709&view=rev Log: [OpenMP] Add checks for requires and target directives.
Summary: The requires directive containing target related clauses must appear before any target region in the compilation unit. Reviewers: ABataev, AlexEichenberger, caomhin Reviewed By: ABataev Subscribers: guansong, jfb, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D60875 Added: cfe/trunk/test/OpenMP/requires_target_messages.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaOpenMP.cpp cfe/trunk/test/OpenMP/requires_messages.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=358709&r1=358708&r2=358709&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Apr 18 12:53:43 2019 @@ -9132,6 +9132,10 @@ def err_omp_requires_clause_redeclaratio "Only one %0 clause can appear on a requires directive in a single translation unit">; def note_omp_requires_previous_clause : Note < "%0 clause previously used here">; +def err_omp_target_before_requires : Error < + "target region encountered before requires directive with '%0' clause">; +def note_omp_requires_encountered_target : Note < + "target previously encountered here">; def err_omp_invalid_scope : Error < "'#pragma omp %0' directive must appear only in file scope">; def note_omp_invalid_length_on_this_ptr_mapping : Note < Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=358709&r1=358708&r2=358709&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Apr 18 12:53:43 2019 @@ -193,6 +193,8 @@ private: /// Expression for the predefined allocators. Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { nullptr}; + /// Vector of previously encountered target directives + SmallVector<SourceLocation, 2> TargetLocations; public: explicit DSAStackTy(Sema &S) : SemaRef(S) {} @@ -454,6 +456,16 @@ public: return IsDuplicate; } + /// Add location of previously encountered target to internal vector + void addTargetDirLocation(SourceLocation LocStart) { + TargetLocations.push_back(LocStart); + } + + // Return previously encountered target region locations. + ArrayRef<SourceLocation> getEncounteredTargetLocs() const { + return TargetLocations; + } + /// Set default data sharing attribute to none. void setDefaultDSANone(SourceLocation Loc) { assert(!isStackEmpty()); @@ -2418,6 +2430,27 @@ Sema::ActOnOpenMPRequiresDirective(Sourc OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, ArrayRef<OMPClause *> ClauseList) { + /// For target specific clauses, the requires directive cannot be + /// specified after the handling of any of the target regions in the + /// current compilation unit. + ArrayRef<SourceLocation> TargetLocations = + DSAStack->getEncounteredTargetLocs(); + if (!TargetLocations.empty()) { + for (const OMPClause *CNew : ClauseList) { + // Check if any of the requires clauses affect target regions. + if (isa<OMPUnifiedSharedMemoryClause>(CNew) || + isa<OMPUnifiedAddressClause>(CNew) || + isa<OMPReverseOffloadClause>(CNew) || + isa<OMPDynamicAllocatorsClause>(CNew)) { + Diag(Loc, diag::err_omp_target_before_requires) + << getOpenMPClauseName(CNew->getClauseKind()); + for (SourceLocation TargetLoc : TargetLocations) { + Diag(TargetLoc, diag::note_omp_requires_encountered_target); + } + } + } + } + if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, ClauseList); @@ -4167,6 +4200,16 @@ StmtResult Sema::ActOnOpenMPExecutableDi ->setIsOMPStructuredBlock(true); } + if (!CurContext->isDependentContext() && + isOpenMPTargetExecutionDirective(Kind) && + !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || + DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || + DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || + DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { + // Register target to DSA Stack. + DSAStack->addTargetDirLocation(StartLoc); + } + return Res; } Modified: cfe/trunk/test/OpenMP/requires_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/requires_messages.cpp?rev=358709&r1=358708&r2=358709&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/requires_messages.cpp (original) +++ cfe/trunk/test/OpenMP/requires_messages.cpp Thu Apr 18 12:53:43 2019 @@ -7,7 +7,7 @@ int a; #pragma omp requires unified_shared_memory, unified_shared_memory // expected-error {{Only one unified_shared_memory clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_shared_memory' clause}} -#pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} +#pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} #pragma omp requires unified_address, unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_address' clause}} @@ -29,13 +29,13 @@ int a; #pragma omp requires atomic_default_mem_order( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} -#pragma omp requires atomic_default_mem_order(seq_cst // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} +#pragma omp requires atomic_default_mem_order(seq_cst // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} -#pragma omp requires atomic_default_mem_order(invalid_modifier) // expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} +#pragma omp requires atomic_default_mem_order(invalid_modifier) // expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} #pragma omp requires atomic_default_mem_order(shared) // expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} -#pragma omp requires atomic_default_mem_order(acq_rel), atomic_default_mem_order(relaxed) // expected-error {{directive '#pragma omp requires' cannot contain more than one 'atomic_default_mem_order' claus}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} +#pragma omp requires atomic_default_mem_order(acq_rel), atomic_default_mem_order(relaxed) // expected-error {{directive '#pragma omp requires' cannot contain more than one 'atomic_default_mem_order' claus}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} #pragma omp requires // expected-error {{expected at least one clause on '#pragma omp requires' directive}} Added: cfe/trunk/test/OpenMP/requires_target_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/requires_target_messages.cpp?rev=358709&view=auto ============================================================================== --- cfe/trunk/test/OpenMP/requires_target_messages.cpp (added) +++ cfe/trunk/test/OpenMP/requires_target_messages.cpp Thu Apr 18 12:53:43 2019 @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo2() { + int a; + #pragma omp target // expected-note 4 {{Target previously encountered here}} + { + a = a + 1; + } +} + +#pragma omp requires atomic_default_mem_order(seq_cst) +#pragma omp requires unified_address //expected-error {{Target region encountered before requires directive with 'unified_address' clause}} +#pragma omp requires unified_shared_memory //expected-error {{Target region encountered before requires directive with 'unified_shared_memory' clause}} +#pragma omp requires reverse_offload //expected-error {{Target region encountered before requires directive with 'reverse_offload' clause}} +#pragma omp requires dynamic_allocators //expected-error {{Target region encountered before requires directive with 'dynamic_allocators' clause}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits