diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1aeaf590cbb4bf..2f4eb428dfad1e 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10353,6 +10353,10 @@ def err_omp_allocator_used_in_clauses : Error< "data-sharing or data-mapping attribute clauses">; def err_omp_allocator_not_in_uses_allocators : Error< "allocator must be specified in the 'uses_allocators' clause">; +def note_omp_protected_structured_block + : Note<"jump bypasses OpenMP structured block">; +def note_omp_exits_structured_block + : Note<"jump exits scope of OpenMP structured block">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index ea160025ae3dcb..1390876dc0df42 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -647,7 +647,7 @@ void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S, } OS << NL; if (!ForceNoStmt && S->hasAssociatedStmt()) - PrintStmt(S->getInnermostCapturedStmt()->getCapturedStmt()); + PrintStmt(S->getRawStmt()); } void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) { diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index cde0bf448ecb29..edc86c41c3b99b 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -4913,14 +4913,13 @@ CFGBlock *CFGBuilder::VisitOMPExecutableDirective(OMPExecutableDirective *D, B = R; } // Visit associated structured block if any. - if (!D->isStandaloneDirective()) - if (CapturedStmt *CS = D->getInnermostCapturedStmt()) { - Stmt *S = CS->getCapturedStmt(); - if (!isa(S)) - addLocalScopeAndDtors(S); - if (CFGBlock *R = addStmt(S)) - B = R; - } + if (!D->isStandaloneDirective()) { + Stmt *S = D->getRawStmt(); + if (!isa(S)) + addLocalScopeAndDtors(S); + if (CFGBlock *R = addStmt(S)) + B = R; + } return B; } diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 4d88b39175ac4d..7a49fe02dada81 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -3554,12 +3554,9 @@ void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) { } void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) { - auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { - CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt()); - }; - OMPLexicalScope Scope(*this, S, OMPD_unknown); - CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen, - S.hasCancel()); + LexicalScope Scope(*this, S.getSourceRange()); + EmitStopPoint(&S); + EmitStmt(S.getAssociatedStmt()); } void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { @@ -3610,7 +3607,7 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { static void emitMaster(CodeGenFunction &CGF, const OMPExecutableDirective &S) { auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { Action.Enter(CGF); - CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt()); + CGF.EmitStmt(S.getRawStmt()); }; CGF.CGM.getOpenMPRuntime().emitMasterRegion(CGF, CodeGen, S.getBeginLoc()); } @@ -3620,8 +3617,7 @@ void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; - const CapturedStmt *CS = S.getInnermostCapturedStmt(); - const Stmt *MasterRegionBodyStmt = CS->getCapturedStmt(); + const Stmt *MasterRegionBodyStmt = S.getAssociatedStmt(); auto FiniCB = [this](InsertPointTy IP) { OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP); @@ -3635,13 +3631,14 @@ void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { CodeGenIP, FiniBB); }; - CGCapturedStmtInfo CGSI(*CS, CR_OpenMP); - CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI); + LexicalScope Scope(*this, S.getSourceRange()); + EmitStopPoint(&S); Builder.restoreIP(OMPBuilder.CreateMaster(Builder, BodyGenCB, FiniCB)); return; } - OMPLexicalScope Scope(*this, S, OMPD_unknown); + LexicalScope Scope(*this, S.getSourceRange()); + EmitStopPoint(&S); emitMaster(*this, S); } @@ -3650,8 +3647,7 @@ void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; - const CapturedStmt *CS = S.getInnermostCapturedStmt(); - const Stmt *CriticalRegionBodyStmt = CS->getCapturedStmt(); + const Stmt *CriticalRegionBodyStmt = S.getAssociatedStmt(); const Expr *Hint = nullptr; if (const auto *HintClause = S.getSingleClause()) Hint = HintClause->getHint(); @@ -3676,8 +3672,8 @@ void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { CodeGenIP, FiniBB); }; - CGCapturedStmtInfo CGSI(*CS, CR_OpenMP); - CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI); + LexicalScope Scope(*this, S.getSourceRange()); + EmitStopPoint(&S); Builder.restoreIP(OMPBuilder.CreateCritical( Builder, BodyGenCB, FiniCB, S.getDirectiveName().getAsString(), HintInst)); @@ -3687,12 +3683,13 @@ void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { Action.Enter(CGF); - CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt()); + CGF.EmitStmt(S.getAssociatedStmt()); }; const Expr *Hint = nullptr; if (const auto *HintClause = S.getSingleClause()) Hint = HintClause->getHint(); - OMPLexicalScope Scope(*this, S, OMPD_unknown); + LexicalScope Scope(*this, S.getSourceRange()); + EmitStopPoint(&S); CGM.getOpenMPRuntime().emitCriticalRegion(*this, S.getDirectiveName().getAsString(), CodeGen, S.getBeginLoc(), Hint); @@ -5368,17 +5365,11 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { } } - const Stmt *CS = S.getInnermostCapturedStmt()->IgnoreContainers(); - - auto &&CodeGen = [&S, Kind, AO, CS](CodeGenFunction &CGF, - PrePostActionTy &) { - CGF.EmitStopPoint(CS); - emitOMPAtomicExpr(CGF, Kind, AO, S.isPostfixUpdate(), S.getX(), S.getV(), - S.getExpr(), S.getUpdateExpr(), S.isXLHSInRHSPart(), - S.getBeginLoc()); - }; - OMPLexicalScope Scope(*this, S, OMPD_unknown); - CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen); + LexicalScope Scope(*this, S.getSourceRange()); + EmitStopPoint(S.getAssociatedStmt()); + emitOMPAtomicExpr(*this, Kind, AO, S.isPostfixUpdate(), S.getX(), S.getV(), + S.getExpr(), S.getUpdateExpr(), S.isXLHSInRHSPart(), + S.getBeginLoc()); } static void emitCommonOMPTargetDirective(CodeGenFunction &CGF, @@ -6631,7 +6622,12 @@ void CodeGenFunction::EmitSimpleOMPExecutableDirective( CGF.EmitStmt(D.getInnermostCapturedStmt()->getCapturedStmt()); } }; - { + if (D.getDirectiveKind() == OMPD_atomic || + D.getDirectiveKind() == OMPD_critical || + D.getDirectiveKind() == OMPD_section || + D.getDirectiveKind() == OMPD_master) { + EmitStmt(D.getAssociatedStmt()); + } else { auto LPCRegion = CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, D); OMPSimdLexicalScope Scope(*this, D); diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp index b34243edea35e1..d33b14a79dc1a1 100644 --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -17,6 +17,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" +#include "clang/AST/StmtOpenMP.h" #include "llvm/ADT/BitVector.h" using namespace clang; @@ -580,6 +581,17 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, break; default: + if (auto *ED = dyn_cast(S)) { + if (!ED->isStandaloneDirective()) { + unsigned NewParentScope = Scopes.size(); + Scopes.emplace_back(ParentScope, + diag::note_omp_protected_structured_block, + diag::note_omp_exits_structured_block, + ED->getStructuredBlock()->getBeginLoc()); + BuildScopeInformation(ED->getStructuredBlock(), NewParentScope); + return; + } + } break; } @@ -904,6 +916,11 @@ void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc, S.Diag(From->getBeginLoc(), diag::warn_jump_out_of_seh_finally); break; } + if (Scopes[I].InDiag == diag::note_omp_protected_structured_block) { + S.Diag(From->getBeginLoc(), diag::err_goto_into_protected_scope); + S.Diag(To->getBeginLoc(), diag::note_omp_exits_structured_block); + break; + } } } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 21f52e09b39b47..aa5613e8ce4687 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3296,7 +3296,11 @@ class DSAAttrChecker final : public StmtVisitor { void VisitSubCaptures(OMPExecutableDirective *S) { // Check implicitly captured variables. - if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) + if (!S->hasAssociatedStmt() || !S->getAssociatedStmt() || + S->getDirectiveKind() == OMPD_atomic || + S->getDirectiveKind() == OMPD_critical || + S->getDirectiveKind() == OMPD_section || + S->getDirectiveKind() == OMPD_master) return; visitSubCaptures(S->getInnermostCapturedStmt()); // Try to capture inner this->member references to generate correct mappings @@ -3798,19 +3802,20 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { /*OpenMPCaptureLevel=*/1); break; } + case OMPD_atomic: + case OMPD_critical: + case OMPD_section: + case OMPD_master: + break; case OMPD_simd: case OMPD_for: case OMPD_for_simd: case OMPD_sections: - case OMPD_section: case OMPD_single: - case OMPD_master: - case OMPD_critical: case OMPD_taskgroup: case OMPD_distribute: case OMPD_distribute_simd: case OMPD_ordered: - case OMPD_atomic: case OMPD_target_data: { Sema::CapturedParamNameType Params[] = { std::make_pair(StringRef(), QualType()) // __context with shared vars @@ -4276,6 +4281,12 @@ static bool checkOrderedOrderSpecified(Sema &S, StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, ArrayRef Clauses) { + if (DSAStack->getCurrentDirective() == OMPD_atomic || + DSAStack->getCurrentDirective() == OMPD_critical || + DSAStack->getCurrentDirective() == OMPD_section || + DSAStack->getCurrentDirective() == OMPD_master) + return S; + bool ErrorFound = false; CaptureRegionUnwinderRAII CaptureRegionUnwinder( *this, ErrorFound, DSAStack->getCurrentDirective()); @@ -4989,7 +5000,8 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( VarsWithInheritedDSAType VarsWithInheritedDSA; bool ErrorFound = false; ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); - if (AStmt && !CurContext->isDependentContext()) { + if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && + Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) { assert(isa(AStmt) && "Captured statement expected"); // Check default data sharing attributes for referenced variables. @@ -8946,8 +8958,6 @@ StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, if (!AStmt) return StmtError(); - assert(isa(AStmt) && "Captured statement expected"); - setFunctionHasBranchProtectedScope(); DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); @@ -8992,8 +9002,6 @@ StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, if (!AStmt) return StmtError(); - assert(isa(AStmt) && "Captured statement expected"); - setFunctionHasBranchProtectedScope(); return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); @@ -9005,8 +9013,6 @@ StmtResult Sema::ActOnOpenMPCriticalDirective( if (!AStmt) return StmtError(); - assert(isa(AStmt) && "Captured statement expected"); - bool ErrorFound = false; llvm::APSInt Hint; SourceLocation HintLoc; @@ -9724,7 +9730,6 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, if (!AStmt) return StmtError(); - auto *CS = cast(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the // top and a single exit at the bottom. @@ -9788,7 +9793,7 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, << getOpenMPClauseName(MemOrderKind); } - Stmt *Body = CS->getCapturedStmt(); + Stmt *Body = AStmt; if (auto *EWC = dyn_cast(Body)) Body = EWC->getSubExpr(); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index d23b441cad1bad..6e7787ed004abb 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -8332,7 +8332,14 @@ StmtResult TreeTransform::TransformOMPExecutableDirective( StmtResult Body; { Sema::CompoundScopeRAII CompoundScope(getSema()); - Stmt *CS = D->getInnermostCapturedStmt()->getCapturedStmt(); + Stmt *CS; + if (D->getDirectiveKind() == OMPD_atomic || + D->getDirectiveKind() == OMPD_critical || + D->getDirectiveKind() == OMPD_section || + D->getDirectiveKind() == OMPD_master) + CS = D->getAssociatedStmt(); + else + CS = D->getInnermostCapturedStmt()->getCapturedStmt(); Body = getDerived().TransformStmt(CS); } AssociatedStmt = diff --git a/clang/test/AST/ast-dump-openmp-atomic.c b/clang/test/AST/ast-dump-openmp-atomic.c index 53d33064238558..2bd9f558b749a4 100644 --- a/clang/test/AST/ast-dump-openmp-atomic.c +++ b/clang/test/AST/ast-dump-openmp-atomic.c @@ -10,9 +10,5 @@ void test(int i) { // CHECK-NEXT: |-ParmVarDecl {{.*}} col:15 used i 'int' // CHECK-NEXT: `-CompoundStmt {{.*}} // CHECK-NEXT: `-OMPAtomicDirective {{.*}} -// CHECK-NEXT: `-CapturedStmt {{.*}} -// CHECK-NEXT: |-CapturedDecl {{.*}} <> -// CHECK-NEXT: | |-UnaryOperator {{.*}} 'int' prefix '++' -// CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'i' 'int' -// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} col:1 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-atomic.c:4:1) *const restrict' -// CHECK-NEXT: `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'i' 'int' +// CHECK-NEXT: `-UnaryOperator {{.*}} 'int' prefix '++' +// CHECK-NEXT: `-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'i' 'int' diff --git a/clang/test/AST/ast-dump-openmp-critical.c b/clang/test/AST/ast-dump-openmp-critical.c index f882556a790482..d4d3efe3e8a421 100644 --- a/clang/test/AST/ast-dump-openmp-critical.c +++ b/clang/test/AST/ast-dump-openmp-critical.c @@ -9,7 +9,4 @@ void test() { // CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-critical.c:3:1, line:6:1> line:3:6 test 'void ()' // CHECK-NEXT: `-CompoundStmt {{.*}} // CHECK-NEXT: `-OMPCriticalDirective {{.*}} -// CHECK-NEXT: `-CapturedStmt {{.*}} -// CHECK-NEXT: `-CapturedDecl {{.*}} <> -// CHECK-NEXT: |-NullStmt {{.*}} -// CHECK-NEXT: `-ImplicitParamDecl {{.*}} col:1 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-critical.c:4:1) *const restrict' +// CHECK-NEXT: `-NullStmt {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-master.c b/clang/test/AST/ast-dump-openmp-master.c index f2345ee2d5771a..5dd19fc797d522 100644 --- a/clang/test/AST/ast-dump-openmp-master.c +++ b/clang/test/AST/ast-dump-openmp-master.c @@ -9,7 +9,4 @@ void test() { // CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-master.c:3:1, line:6:1> line:3:6 test 'void ()' // CHECK-NEXT: `-CompoundStmt {{.*}} // CHECK-NEXT: `-OMPMasterDirective {{.*}} -// CHECK-NEXT: `-CapturedStmt {{.*}} -// CHECK-NEXT: `-CapturedDecl {{.*}} <> -// CHECK-NEXT: |-NullStmt {{.*}} -// CHECK-NEXT: `-ImplicitParamDecl {{.*}} col:1 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-master.c:4:1) *const restrict' +// CHECK-NEXT: `-NullStmt {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-section.c b/clang/test/AST/ast-dump-openmp-section.c index 4c8e1056990faf..f52d6bb6bb8117 100644 --- a/clang/test/AST/ast-dump-openmp-section.c +++ b/clang/test/AST/ast-dump-openmp-section.c @@ -16,13 +16,5 @@ void test() { // CHECK-NEXT: `-CapturedDecl {{.*}} <> // CHECK-NEXT: |-CompoundStmt {{.*}} // CHECK-NEXT: | `-OMPSectionDirective {{.*}} -// CHECK-NEXT: | `-CapturedStmt {{.*}} -// CHECK-NEXT: | `-CapturedDecl {{.*}} <> -// CHECK-NEXT: | |-NullStmt {{.*}} -// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} col:1 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-section.c:6:1) *const restrict' -// CHECK-NEXT: |-ImplicitParamDecl {{.*}} col:1 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-section.c:4:1) *const restrict' -// CHECK-NEXT: |-RecordDecl {{.*}} col:1 implicit struct definition -// CHECK-NEXT: | `-CapturedRecordAttr {{.*}} <> Implicit -// CHECK-NEXT: `-CapturedDecl {{.*}} <> -// CHECK-NEXT: |-NullStmt {{.*}} -// CHECK-NEXT: `-ImplicitParamDecl {{.*}} col:1 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-section.c:6:1) *const restrict' +// CHECK-NEXT: | `-NullStmt {{.*}} +// CHECK-NEXT: `-ImplicitParamDecl {{.*}} col:1 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-section.c:4:1) *const restrict' diff --git a/clang/test/OpenMP/atomic_messages.c b/clang/test/OpenMP/atomic_messages.c index 7a2150f9416b89..bf3a3bbd30907b 100644 --- a/clang/test/OpenMP/atomic_messages.c +++ b/clang/test/OpenMP/atomic_messages.c @@ -18,9 +18,9 @@ int foo() { // expected-note@+1 {{expected an expression statement}} { foo(); - goto L1; // expected-error {{use of undeclared label 'L1'}} + goto L1; } - goto L2; // expected-error {{use of undeclared label 'L2'}} + goto L2; #pragma omp atomic // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} diff --git a/clang/test/OpenMP/atomic_messages.cpp b/clang/test/OpenMP/atomic_messages.cpp index c44405178c8418..fc29a2ceae1747 100644 --- a/clang/test/OpenMP/atomic_messages.cpp +++ b/clang/test/OpenMP/atomic_messages.cpp @@ -12,9 +12,9 @@ int foo() { // expected-note@+1 {{expected an expression statement}} { foo(); - goto L1; // expected-error {{use of undeclared label 'L1'}} + goto L1; } - goto L2; // expected-error {{use of undeclared label 'L2'}} + goto L2; #pragma omp atomic // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} diff --git a/clang/test/OpenMP/critical_codegen.cpp b/clang/test/OpenMP/critical_codegen.cpp index 4b2566bbf364ba..46fad63b3bd88d 100644 --- a/clang/test/OpenMP/critical_codegen.cpp +++ b/clang/test/OpenMP/critical_codegen.cpp @@ -77,8 +77,6 @@ void critical_ref(S &s) { // ALL: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]], // ALL: [[S_A_REF:%.+]] = getelementptr inbounds %struct.S, %struct.S* [[S_REF]], i32 0, i32 0 ++s.a; - // NORMAL: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]], - // NORMAL: store %struct.S* [[S_REF]], %struct.S** [[S_ADDR:%.+]], // ALL: call void @__kmpc_critical( #pragma omp critical // ALL: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]], diff --git a/clang/test/OpenMP/critical_messages.cpp b/clang/test/OpenMP/critical_messages.cpp index 54349e3396379a..097cce2fac64c1 100644 --- a/clang/test/OpenMP/critical_messages.cpp +++ b/clang/test/OpenMP/critical_messages.cpp @@ -140,16 +140,16 @@ int main(int argc, char **argv) { // expected-note {{declared here}} } int foo() { - L1: + L1: // expected-note {{jump exits scope of OpenMP structured block}} foo(); #pragma omp critical { foo(); - goto L1; // expected-error {{use of undeclared label 'L1'}} + goto L1; // expected-error {{cannot jump from this goto statement to its label}} } - goto L2; // expected-error {{use of undeclared label 'L2'}} + goto L2; // expected-error {{cannot jump from this goto statement to its label}} #pragma omp critical - { + { // expected-note {{jump bypasses OpenMP structured block}} L2: foo(); } diff --git a/clang/test/OpenMP/master_messages.cpp b/clang/test/OpenMP/master_messages.cpp index ce403f0cb05095..d4f35597be4af6 100644 --- a/clang/test/OpenMP/master_messages.cpp +++ b/clang/test/OpenMP/master_messages.cpp @@ -54,16 +54,16 @@ int main() { } int foo() { - L1: + L1: // expected-note {{jump exits scope of OpenMP structured block}} foo(); #pragma omp master { foo(); - goto L1; // expected-error {{use of undeclared label 'L1'}} + goto L1; // expected-error {{cannot jump from this goto statement to its label}} } - goto L2; // expected-error {{use of undeclared label 'L2'}} + goto L2; // expected-error {{cannot jump from this goto statement to its label}} #pragma omp master - { + { // expected-note {{jump bypasses OpenMP structured block}} L2: foo(); } diff --git a/clang/test/OpenMP/parallel_sections_misc_messages.c b/clang/test/OpenMP/parallel_sections_misc_messages.c index 0264cd6dd649ef..08c704b528fa21 100644 --- a/clang/test/OpenMP/parallel_sections_misc_messages.c +++ b/clang/test/OpenMP/parallel_sections_misc_messages.c @@ -50,7 +50,7 @@ void test_branch_protected_scope() { } #pragma omp section if (i == 5) - goto L1; // expected-error {{use of undeclared label 'L1'}} + goto L1; else if (i == 6) return; // expected-error {{cannot return from OpenMP region}} else if (i == 7) diff --git a/clang/test/OpenMP/sections_misc_messages.c b/clang/test/OpenMP/sections_misc_messages.c index fd775400b428b2..cce957c5f4c717 100644 --- a/clang/test/OpenMP/sections_misc_messages.c +++ b/clang/test/OpenMP/sections_misc_messages.c @@ -34,6 +34,20 @@ void test_no_clause() { foo(); foo(); // expected-error {{statement in 'omp sections' directive must be enclosed into a section region}} } +#pragma omp parallel +#pragma omp sections + { + { + if (i == 6) + return; // expected-error {{cannot return from OpenMP region}} + } +#pragma omp section + { + if (i == 6) + return; // expected-error {{cannot return from OpenMP region}} + } + } + } void test_branch_protected_scope() { @@ -48,19 +62,29 @@ void test_branch_protected_scope() { { if (i == 5) goto L1; // expected-error {{use of undeclared label 'L1'}} - else if (i == 6) - return; // expected-error {{cannot return from OpenMP region}} else if (i == 7) goto L2; else if (i == 8) { L2: x[i]++; } +#pragma omp section + if (i == 5) + goto L1; + else if (i == 7) + goto L3; + else if (i == 8) { + L3: + x[i]++; + } + } + +#pragma omp parallel +#pragma omp sections + { #pragma omp section if (i == 5) goto L1; // expected-error {{use of undeclared label 'L1'}} - else if (i == 6) - return; // expected-error {{cannot return from OpenMP region}} else if (i == 7) goto L3; else if (i == 8) {