Index: lib/Sema/SemaOpenMP.cpp =================================================================== --- lib/Sema/SemaOpenMP.cpp +++ lib/Sema/SemaOpenMP.cpp @@ -1992,9 +1992,18 @@ return ActOnCapturedRegionEnd(S.get()); } +static bool HasSimdClause(const ArrayRef Clauses) { + for (auto *C : Clauses) { + if (C->getClauseKind() == OMPC_simd) + return true; + } + return false; +} + static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, + const ArrayRef Clauses, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc) { // Allowed nesting of constructs @@ -2940,8 +2949,9 @@ ShouldBeInTargetRegion, ShouldBeInTeamsRegion } Recommend = NoRecommend; - if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered && - CurrentRegion != OMPD_simd) { + if (isOpenMPSimdDirective(ParentRegion) && + (CurrentRegion != OMPD_ordered || + (CurrentRegion == OMPD_ordered && !HasSimdClause(Clauses)))) { // OpenMP [2.16, Nesting of Regions] // OpenMP constructs may not be nested inside a simd region. // OpenMP [2.8.1,simd Construct, Restrictions] @@ -3207,8 +3217,8 @@ OpenMPDirectiveKind CancelRegion, ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { StmtResult Res = StmtError(); - if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, - StartLoc)) + if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, Clauses, + CancelRegion, StartLoc)) return StmtError(); llvm::SmallVector ClausesWithImplicit; Index: test/OpenMP/nesting_of_regions.cpp =================================================================== --- test/OpenMP/nesting_of_regions.cpp +++ test/OpenMP/nesting_of_regions.cpp @@ -153,7 +153,7 @@ } #pragma omp simd for (int i = 0; i < 10; ++i) { -#pragma omp simd +#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} for (int i = 0; i < 10; ++i) ; } @@ -516,7 +516,7 @@ } #pragma omp for simd for (int i = 0; i < 10; ++i) { -#pragma omp simd +#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} for (int i = 0; i < 10; ++i) ; } @@ -1902,7 +1902,7 @@ } #pragma omp parallel for simd for (int i = 0; i < 10; ++i) { -#pragma omp simd +#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} for (int i = 0; i < 10; ++i) ; } @@ -4314,7 +4314,7 @@ } #pragma omp simd for (int i = 0; i < 10; ++i) { -#pragma omp simd +#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} for (int i = 0; i < 10; ++i) ; } @@ -4662,7 +4662,7 @@ } #pragma omp for simd for (int i = 0; i < 10; ++i) { -#pragma omp simd +#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} for (int i = 0; i < 10; ++i) ; } @@ -6022,7 +6022,7 @@ } #pragma omp parallel for simd for (int i = 0; i < 10; ++i) { -#pragma omp simd +#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} for (int i = 0; i < 10; ++i) ; }