diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/StmtOpenMP.cpp | 22 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Basic/OpenMPKinds.cpp | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 1 | ||||
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 78 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 11 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 8 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 1 |
13 files changed, 174 insertions, 4 deletions
diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp index b3dfd251692..4ac2ca2abd0 100644 --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -737,6 +737,28 @@ OMPTargetEnterDataDirective::CreateEmpty(const ASTContext &C, unsigned N, return new (Mem) OMPTargetEnterDataDirective(N); } +OMPTargetExitDataDirective * +OMPTargetExitDataDirective::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses) { + void *Mem = C.Allocate(llvm::alignTo(sizeof(OMPTargetExitDataDirective), + llvm::alignOf<OMPClause *>()) + + sizeof(OMPClause *) * Clauses.size()); + OMPTargetExitDataDirective *Dir = + new (Mem) OMPTargetExitDataDirective(StartLoc, EndLoc, Clauses.size()); + Dir->setClauses(Clauses); + return Dir; +} + +OMPTargetExitDataDirective * +OMPTargetExitDataDirective::CreateEmpty(const ASTContext &C, unsigned N, + EmptyShell) { + void *Mem = C.Allocate(llvm::alignTo(sizeof(OMPTargetExitDataDirective), + llvm::alignOf<OMPClause *>()) + + sizeof(OMPClause *) * N); + return new (Mem) OMPTargetExitDataDirective(N); +} + OMPTeamsDirective *OMPTeamsDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 2e8da360c94..927fdeb8de0 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1067,6 +1067,12 @@ void StmtPrinter::VisitOMPTargetEnterDataDirective( PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPTargetExitDataDirective( + OMPTargetExitDataDirective *Node) { + Indent() << "#pragma omp target exit data "; + PrintOMPExecutableDirective(Node); +} + void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) { Indent() << "#pragma omp teams "; PrintOMPExecutableDirective(Node); diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 9ab9c8e1217..2ea0243f12a 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -589,6 +589,11 @@ void StmtProfiler::VisitOMPTargetEnterDataDirective( VisitOMPExecutableDirective(S); } +void StmtProfiler::VisitOMPTargetExitDataDirective( + const OMPTargetExitDataDirective *S) { + VisitOMPExecutableDirective(S); +} + void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) { VisitOMPExecutableDirective(S); } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 167a700d27f..67983871933 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -423,6 +423,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, break; } break; + case OMPD_target_exit_data: + switch (CKind) { +#define OPENMP_TARGET_EXIT_DATA_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; case OMPD_teams: switch (CKind) { #define OPENMP_TEAMS_CLAUSE(Name) \ diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index df6766a768e..bd4fa8b7a31 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -259,6 +259,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::OMPTargetEnterDataDirectiveClass: EmitOMPTargetEnterDataDirective(cast<OMPTargetEnterDataDirective>(*S)); break; + case Stmt::OMPTargetExitDataDirectiveClass: + EmitOMPTargetExitDataDirective(cast<OMPTargetExitDataDirective>(*S)); + break; case Stmt::OMPTaskLoopDirectiveClass: EmitOMPTaskLoopDirective(cast<OMPTaskLoopDirective>(*S)); break; diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index f6b8e5907d4..793e1a97314 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -2666,6 +2666,11 @@ void CodeGenFunction::EmitOMPTargetEnterDataDirective( // TODO: codegen for target enter data. } +void CodeGenFunction::EmitOMPTargetExitDataDirective( + const OMPTargetExitDataDirective &S) { + // TODO: codegen for target exit data. +} + void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) { // emit the code inside the construct for now auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index d1cf0c9206e..129cc9918d7 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2337,6 +2337,7 @@ public: void EmitOMPTargetDirective(const OMPTargetDirective &S); void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S); void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S); + void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S); void EmitOMPTeamsDirective(const OMPTeamsDirective &S); void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 4baf5d26616..94d90c0e210 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -38,6 +38,8 @@ static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) { OMPD_unknown /*target enter/exit*/}, {OMPD_unknown /*target enter*/, OMPD_unknown /*data*/, OMPD_target_enter_data}, + {OMPD_unknown /*target exit*/, OMPD_unknown /*data*/, + OMPD_target_exit_data}, {OMPD_for, OMPD_simd, OMPD_for_simd}, {OMPD_parallel, OMPD_for, OMPD_parallel_for}, {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd}, @@ -55,7 +57,9 @@ static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) { TokenMatched = ((i == 0) && !P.getPreprocessor().getSpelling(Tok).compare("cancellation")) || - ((i == 3) && !P.getPreprocessor().getSpelling(Tok).compare("enter")); + ((i == 3) && + !P.getPreprocessor().getSpelling(Tok).compare("enter")) || + ((i == 4) && !P.getPreprocessor().getSpelling(Tok).compare("exit")); } else { TokenMatched = DKind == F[i][0] && DKind != OMPD_unknown; } @@ -72,10 +76,11 @@ static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) { TokenMatched = ((i == 0) && !P.getPreprocessor().getSpelling(Tok).compare("point")) || - ((i == 1 || i == 3) && + ((i == 1 || i == 3 || i == 4) && !P.getPreprocessor().getSpelling(Tok).compare("data")) || ((i == 2) && - !P.getPreprocessor().getSpelling(Tok).compare("enter")); + (!P.getPreprocessor().getSpelling(Tok).compare("enter") || + !P.getPreprocessor().getSpelling(Tok).compare("exit"))); } else { TokenMatched = SDKind == F[i][1] && SDKind != OMPD_unknown; } @@ -147,6 +152,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() { case OMPD_cancel: case OMPD_target_data: case OMPD_target_enter_data: + case OMPD_target_exit_data: case OMPD_taskloop: case OMPD_taskloop_simd: case OMPD_distribute: @@ -171,7 +177,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() { /// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' | /// 'for simd' | 'parallel for simd' | 'target' | 'target data' | /// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' {clause} | -/// 'distribute' | 'target enter data' | annot_pragma_openmp_end +/// 'distribute' | 'target enter data' | 'target exit data' +/// annot_pragma_openmp_end /// StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( AllowedContsructsKind Allowed) { @@ -226,6 +233,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( case OMPD_cancellation_point: case OMPD_cancel: case OMPD_target_enter_data: + case OMPD_target_exit_data: if (Allowed == ACK_StatementsOpenMPNonStandalone) { Diag(Tok, diag::err_omp_immediate_directive) << getOpenMPDirectiveName(DKind) << 0; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index a3e33bc6580..1b515536389 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1611,6 +1611,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { case OMPD_cancel: case OMPD_flush: case OMPD_target_enter_data: + case OMPD_target_exit_data: llvm_unreachable("OpenMP Directive is not allowed"); case OMPD_unknown: llvm_unreachable("Unknown OpenMP directive"); @@ -1727,6 +1728,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel | target | * | // | parallel | target enter | * | // | | data | | + // | parallel | target exit | * | + // | | data | | // | parallel | teams | + | // | parallel | cancellation | | // | | point | ! | @@ -1758,6 +1761,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | for | target | * | // | for | target enter | * | // | | data | | + // | for | target exit | * | + // | | data | | // | for | teams | + | // | for | cancellation | | // | | point | ! | @@ -1789,6 +1794,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | master | target | * | // | master | target enter | * | // | | data | | + // | master | target exit | * | + // | | data | | // | master | teams | + | // | master | cancellation | | // | | point | | @@ -1819,6 +1826,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | critical | target | * | // | critical | target enter | * | // | | data | | + // | critical | target exit | * | + // | | data | | // | critical | teams | + | // | critical | cancellation | | // | | point | | @@ -1850,6 +1859,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | simd | target | | // | simd | target enter | | // | | data | | + // | simd | target exit | | + // | | data | | // | simd | teams | | // | simd | cancellation | | // | | point | | @@ -1881,6 +1892,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | for simd | target | | // | for simd | target enter | | // | | data | | + // | for simd | target exit | | + // | | data | | // | for simd | teams | | // | for simd | cancellation | | // | | point | | @@ -1912,6 +1925,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel for simd| target | | // | parallel for simd| target enter | | // | | data | | + // | parallel for simd| target exit | | + // | | data | | // | parallel for simd| teams | | // | parallel for simd| cancellation | | // | | point | | @@ -1943,6 +1958,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | sections | target | * | // | sections | target enter | * | // | | data | | + // | sections | target exit | * | + // | | data | | // | sections | teams | + | // | sections | cancellation | | // | | point | ! | @@ -1974,6 +1991,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | section | target | * | // | section | target enter | * | // | | data | | + // | section | target exit | * | + // | | data | | // | section | teams | + | // | section | cancellation | | // | | point | ! | @@ -2005,6 +2024,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | single | target | * | // | single | target enter | * | // | | data | | + // | single | target exit | * | + // | | data | | // | single | teams | + | // | single | cancellation | | // | | point | | @@ -2036,6 +2057,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel for | target | * | // | parallel for | target enter | * | // | | data | | + // | parallel for | target exit | * | + // | | data | | // | parallel for | teams | + | // | parallel for | cancellation | | // | | point | ! | @@ -2067,6 +2090,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel sections| target | * | // | parallel sections| target enter | * | // | | data | | + // | parallel sections| target exit | * | + // | | data | | // | parallel sections| teams | + | // | parallel sections| cancellation | | // | | point | ! | @@ -2098,6 +2123,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | task | target | * | // | task | target enter | * | // | | data | | + // | task | target exit | * | + // | | data | | // | task | teams | + | // | task | cancellation | | // | | point | ! | @@ -2129,6 +2156,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | ordered | target | * | // | ordered | target enter | * | // | | data | | + // | ordered | target exit | * | + // | | data | | // | ordered | teams | + | // | ordered | cancellation | | // | | point | | @@ -2160,6 +2189,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | atomic | target | | // | atomic | target enter | | // | | data | | + // | atomic | target exit | | + // | | data | | // | atomic | teams | | // | atomic | cancellation | | // | | point | | @@ -2191,6 +2222,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | target | target | * | // | target | target enter | * | // | | data | | + // | target | target exit | * | + // | | data | | // | target | teams | * | // | target | cancellation | | // | | point | | @@ -2222,6 +2255,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | teams | target | + | // | teams | target enter | + | // | | data | | + // | teams | target exit | + | + // | | data | | // | teams | teams | + | // | teams | cancellation | | // | | point | | @@ -2253,6 +2288,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | taskloop | target | * | // | taskloop | target enter | * | // | | data | | + // | taskloop | target exit | * | + // | | data | | // | taskloop | teams | + | // | taskloop | cancellation | | // | | point | | @@ -2283,6 +2320,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | taskloop simd | target | | // | taskloop simd | target enter | | // | | data | | + // | taskloop simd | target exit | | + // | | data | | // | taskloop simd | teams | | // | taskloop simd | cancellation | | // | | point | | @@ -2314,6 +2353,8 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | distribute | target | | // | distribute | target enter | | // | | data | | + // | distribute | target exit | | + // | | data | | // | distribute | teams | | // | distribute | cancellation | + | // | | point | | @@ -2743,6 +2784,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( EndLoc); AllowedNameModifiers.push_back(OMPD_target_enter_data); break; + case OMPD_target_exit_data: + Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, + EndLoc); + AllowedNameModifiers.push_back(OMPD_target_exit_data); + break; case OMPD_taskloop: Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); @@ -5522,6 +5568,21 @@ Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, Clauses); } +StmtResult +Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc) { + // OpenMP [2.10.3, Restrictions, p. 102] + // At least one map clause must appear on the directive. + if (!HasMapClause(Clauses)) { + Diag(StartLoc, diag::err_omp_no_map_for_directive) + << getOpenMPDirectiveName(OMPD_target_exit_data); + return StmtError(); + } + + return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses); +} + StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { @@ -8539,6 +8600,23 @@ OMPClause *Sema::ActOnOpenMPMapClause( // further spurious messages } + // target exit_data + // OpenMP [2.10.3, Restrictions, p. 102] + // A map-type must be specified in all map clauses and must be either + // from, release, or delete. + DKind = DSAStack->getCurrentDirective(); + if (DKind == OMPD_target_exit_data && + !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || + MapType == OMPC_MAP_delete)) { + Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) + << + // TODO: Need to determine if map type is implicitly determined + 0 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) + << getOpenMPDirectiveName(DKind); + // Proceed to add the variable in a map clause anyway, to prevent + // further spurious messages + } + Vars.push_back(RE); MI.RefExpr = RE; DSAStack->addMapInfoForVar(VD, MI); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 4b614d888c1..3b435731952 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7402,6 +7402,17 @@ StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective( } template <typename Derived> +StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective( + OMPTargetExitDataDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().StartOpenMPDSABlock(OMPD_target_exit_data, DirName, + nullptr, D->getLocStart()); + StmtResult Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().EndOpenMPDSABlock(Res.get()); + return Res; +} + +template <typename Derived> StmtResult TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) { DeclarationNameInfo DirName; diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 4b312ce7579..ae978d5bcb7 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2462,6 +2462,13 @@ void ASTStmtReader::VisitOMPTargetEnterDataDirective( VisitOMPExecutableDirective(D); } +void ASTStmtReader::VisitOMPTargetExitDataDirective( + OMPTargetExitDataDirective *D) { + VisitStmt(D); + ++Idx; + VisitOMPExecutableDirective(D); +} + void ASTStmtReader::VisitOMPTeamsDirective(OMPTeamsDirective *D) { VisitStmt(D); // The NumClauses field was read in ReadStmtFromStream. @@ -3110,6 +3117,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, Record[ASTStmtReader::NumStmtFields], Empty); break; + case STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE: + S = OMPTargetExitDataDirective::CreateEmpty( + Context, Record[ASTStmtReader::NumStmtFields], Empty); + break; + case STMT_OMP_TEAMS_DIRECTIVE: S = OMPTeamsDirective::CreateEmpty( Context, Record[ASTStmtReader::NumStmtFields], Empty); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index ed6044d45f3..8d1de313d0f 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2222,6 +2222,14 @@ void ASTStmtWriter::VisitOMPTargetEnterDataDirective( Code = serialization::STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE; } +void ASTStmtWriter::VisitOMPTargetExitDataDirective( + OMPTargetExitDataDirective *D) { + VisitStmt(D); + Record.push_back(D->getNumClauses()); + VisitOMPExecutableDirective(D); + Code = serialization::STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE; +} + void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) { VisitStmt(D); VisitOMPExecutableDirective(D); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index e4e61ab2d64..309caa50ea3 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -831,6 +831,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPTargetDirectiveClass: case Stmt::OMPTargetDataDirectiveClass: case Stmt::OMPTargetEnterDataDirectiveClass: + case Stmt::OMPTargetExitDataDirectiveClass: case Stmt::OMPTeamsDirectiveClass: case Stmt::OMPCancellationPointDirectiveClass: case Stmt::OMPCancelDirectiveClass: |