lebedev.ri created this revision. lebedev.ri added reviewers: ABataev, OpenMP. lebedev.ri added projects: clang, OpenMP. Herald added subscribers: openmp-commits, guansong.
I'm working on a clang-tidy check, much like existing bugprone-exception-escape <http://clang.llvm.org/extra/clang-tidy/checks/bugprone-exception-escape.html>, to detect when an exception might escape out of an OpenMP construct it isn't supposed to escape from. For that i will be using the `nothrow` bit of `CapturedDecl`s. While that bit is already correctly set for some constructs, e.g. `#pragma omp parallel`: https://godbolt.org/z/2La7pv it isn't set for the `#pragma omp sections`, or `#pragma omp section`: https://godbolt.org/z/qZ-EbP If i'm reading `OpenMP Application Programming Interface Version 5.0 November 2018` <https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5.0.pdf> correctly, they should be, as per `2.8.1 sections Construct`, starting with page 86: - The sections construct is a non-iterative worksharing construct that contains a set of **structured blocks** that are to be distributed among and executed by the threads in a team. Each **structured block** is executed once by one of the threads in the team in the context of its implicit task. - The syntax of the sections construct is as follows: #pragma omp sections [clause[ [,] clause] ... ] new-line { [#pragma omp section new-line] **structured-block** ... - Description Each **structured block** in the sections construct is preceded by a section directive except possibly **the first block**, for which a preceding section directive is optional. - Restrictions • The code enclosed in a sections construct must be a **structured block**. - A throw executed inside a sections region must cause execution to resume within the same section of the sections region, and the same thread that threw the exception must catch it. Repository: rC Clang https://reviews.llvm.org/D57585 Files: lib/Sema/SemaOpenMP.cpp test/AST/ast-dump-openmp-sections.cpp Index: test/AST/ast-dump-openmp-sections.cpp =================================================================== --- /dev/null +++ test/AST/ast-dump-openmp-sections.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp-simd -ast-dump %s | FileCheck %s +// expected-no-diagnostics + +void sections() { +#pragma omp sections + { +#pragma omp section + { + } +#pragma omp section + { + } + } +} + +// CHECK: `-FunctionDecl +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: `-OMPSectionsDirective +// CHECK-NEXT: `-CapturedStmt +// CHECK-NEXT: `-CapturedDecl {{.*}} nothrow +// CHECK-NEXT: |-CompoundStmt +// CHECK-NEXT: | |-OMPSectionDirective +// CHECK-NEXT: | | `-CapturedStmt +// CHECK-NEXT: | | `-CapturedDecl {{.*}} nothrow +// CHECK-NEXT: | | |-CompoundStmt +// CHECK-NEXT: | | `-ImplicitParamDecl +// CHECK-NEXT: | `-OMPSectionDirective +// CHECK-NEXT: | `-CapturedStmt +// CHECK-NEXT: | `-CapturedDecl {{.*}} nothrow +// CHECK-NEXT: | |-CompoundStmt +// CHECK-NEXT: | `-ImplicitParamDecl +// CHECK-NEXT: |-ImplicitParamDecl +// CHECK-NEXT: |-CXXRecordDecl +// CHECK-NEXT: | |-DefinitionData +// CHECK-NEXT: | | |-DefaultConstructor +// CHECK-NEXT: | | |-CopyConstructor +// CHECK-NEXT: | | |-MoveConstructor +// CHECK-NEXT: | | |-CopyAssignment +// CHECK-NEXT: | | |-MoveAssignment +// CHECK-NEXT: | | `-Destructor +// CHECK-NEXT: | `-CapturedRecordAttr +// CHECK-NEXT: |-CapturedDecl {{.*}} nothrow +// CHECK-NEXT: | |-CompoundStmt +// CHECK-NEXT: | `-ImplicitParamDecl +// CHECK-NEXT: |-CXXRecordDecl +// CHECK-NEXT: | |-DefinitionData +// CHECK-NEXT: | | |-DefaultConstructor +// CHECK-NEXT: | | |-CopyConstructor +// CHECK-NEXT: | | |-MoveConstructor +// CHECK-NEXT: | | |-CopyAssignment +// CHECK-NEXT: | | |-MoveAssignment +// CHECK-NEXT: | | `-Destructor +// CHECK-NEXT: | `-CapturedRecordAttr +// CHECK-NEXT: `-CapturedDecl {{.*}} nothrow +// CHECK-NEXT: |-CompoundStmt +// CHECK-NEXT: `-ImplicitParamDecl Index: lib/Sema/SemaOpenMP.cpp =================================================================== --- lib/Sema/SemaOpenMP.cpp +++ lib/Sema/SemaOpenMP.cpp @@ -5969,6 +5969,13 @@ return StmtError(); } + // 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. + // The point of exit cannot be a branch out of the structured block. + // longjmp() and throw() must not violate the entry/exit criteria. + cast<CapturedStmt>(AStmt)->getCapturedDecl()->setNothrow(); + setFunctionHasBranchProtectedScope(); return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, @@ -5983,6 +5990,13 @@ assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); + // 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. + // The point of exit cannot be a branch out of the structured block. + // longjmp() and throw() must not violate the entry/exit criteria. + cast<CapturedStmt>(AStmt)->getCapturedDecl()->setNothrow(); + setFunctionHasBranchProtectedScope(); DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
Index: test/AST/ast-dump-openmp-sections.cpp =================================================================== --- /dev/null +++ test/AST/ast-dump-openmp-sections.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp-simd -ast-dump %s | FileCheck %s +// expected-no-diagnostics + +void sections() { +#pragma omp sections + { +#pragma omp section + { + } +#pragma omp section + { + } + } +} + +// CHECK: `-FunctionDecl +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: `-OMPSectionsDirective +// CHECK-NEXT: `-CapturedStmt +// CHECK-NEXT: `-CapturedDecl {{.*}} nothrow +// CHECK-NEXT: |-CompoundStmt +// CHECK-NEXT: | |-OMPSectionDirective +// CHECK-NEXT: | | `-CapturedStmt +// CHECK-NEXT: | | `-CapturedDecl {{.*}} nothrow +// CHECK-NEXT: | | |-CompoundStmt +// CHECK-NEXT: | | `-ImplicitParamDecl +// CHECK-NEXT: | `-OMPSectionDirective +// CHECK-NEXT: | `-CapturedStmt +// CHECK-NEXT: | `-CapturedDecl {{.*}} nothrow +// CHECK-NEXT: | |-CompoundStmt +// CHECK-NEXT: | `-ImplicitParamDecl +// CHECK-NEXT: |-ImplicitParamDecl +// CHECK-NEXT: |-CXXRecordDecl +// CHECK-NEXT: | |-DefinitionData +// CHECK-NEXT: | | |-DefaultConstructor +// CHECK-NEXT: | | |-CopyConstructor +// CHECK-NEXT: | | |-MoveConstructor +// CHECK-NEXT: | | |-CopyAssignment +// CHECK-NEXT: | | |-MoveAssignment +// CHECK-NEXT: | | `-Destructor +// CHECK-NEXT: | `-CapturedRecordAttr +// CHECK-NEXT: |-CapturedDecl {{.*}} nothrow +// CHECK-NEXT: | |-CompoundStmt +// CHECK-NEXT: | `-ImplicitParamDecl +// CHECK-NEXT: |-CXXRecordDecl +// CHECK-NEXT: | |-DefinitionData +// CHECK-NEXT: | | |-DefaultConstructor +// CHECK-NEXT: | | |-CopyConstructor +// CHECK-NEXT: | | |-MoveConstructor +// CHECK-NEXT: | | |-CopyAssignment +// CHECK-NEXT: | | |-MoveAssignment +// CHECK-NEXT: | | `-Destructor +// CHECK-NEXT: | `-CapturedRecordAttr +// CHECK-NEXT: `-CapturedDecl {{.*}} nothrow +// CHECK-NEXT: |-CompoundStmt +// CHECK-NEXT: `-ImplicitParamDecl Index: lib/Sema/SemaOpenMP.cpp =================================================================== --- lib/Sema/SemaOpenMP.cpp +++ lib/Sema/SemaOpenMP.cpp @@ -5969,6 +5969,13 @@ return StmtError(); } + // 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. + // The point of exit cannot be a branch out of the structured block. + // longjmp() and throw() must not violate the entry/exit criteria. + cast<CapturedStmt>(AStmt)->getCapturedDecl()->setNothrow(); + setFunctionHasBranchProtectedScope(); return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, @@ -5983,6 +5990,13 @@ assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); + // 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. + // The point of exit cannot be a branch out of the structured block. + // longjmp() and throw() must not violate the entry/exit criteria. + cast<CapturedStmt>(AStmt)->getCapturedDecl()->setNothrow(); + setFunctionHasBranchProtectedScope(); DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits