From c87e623caa08f9378c2bcab96c2b2faaf553d07b Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Fri, 1 Feb 2019 15:41:54 +0000 Subject: [PATCH] [AST][OpenMP] OpenMP Sections / Section constructs contain Structured blocks MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Summary: I'm working on a clang-tidy check, much like existing [[ http://clang.llvm.org/extra/clang-tidy/checks/bugprone-exception-escape.html | bugprone-exception-escape ]], 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 [[ https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5.0.pdf | `OpenMP Application Programming Interface Version 5.0 November 2018` ]] 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. Reviewers: ABataev, #openmp Reviewed By: ABataev Subscribers: guansong, openmp-commits, cfe-commits Tags: #clang, #openmp Differential Revision: https://reviews.llvm.org/D57585 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@352882 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaOpenMP.cpp | 14 +++++++ test/AST/ast-dump-openmp-sections.cpp | 57 +++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 test/AST/ast-dump-openmp-sections.cpp diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index d28f15fe07..59a40ec41c 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -5969,6 +5969,13 @@ StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef Clauses, 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(AStmt)->getCapturedDecl()->setNothrow(); + setFunctionHasBranchProtectedScope(); return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, @@ -5983,6 +5990,13 @@ StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, assert(isa(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(AStmt)->getCapturedDecl()->setNothrow(); + setFunctionHasBranchProtectedScope(); DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); diff --git a/test/AST/ast-dump-openmp-sections.cpp b/test/AST/ast-dump-openmp-sections.cpp new file mode 100644 index 0000000000..79bb751a6e --- /dev/null +++ b/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 -- 2.40.0