[clang] Run PreStmt/PostStmt checker for GCCAsmStmt (PR #95409)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 10 04:45:25 PDT 2024


https://github.com/T-Gruber updated https://github.com/llvm/llvm-project/pull/95409

>From 8fb59a5ab510cbe9d2f6322cb1c6252c8e0b7343 Mon Sep 17 00:00:00 2001
From: T-Gruber <tobi.gruber at gmx.de>
Date: Thu, 13 Jun 2024 15:41:28 +0200
Subject: [PATCH 1/6] Run PreStmt/PostStmt checker for GCCAsmStmt

---
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp  | 1593 ++++++++---------
 clang/unittests/StaticAnalyzer/CMakeLists.txt |    1 +
 .../StaticAnalyzer/ExprEngineVisitTest.cpp    |   92 +
 3 files changed, 869 insertions(+), 817 deletions(-)
 create mode 100644 clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 197d673107285..d99fa7a132f50 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -89,16 +89,15 @@ using namespace ento;
 
 #define DEBUG_TYPE "ExprEngine"
 
-STATISTIC(NumRemoveDeadBindings,
-            "The # of times RemoveDeadBindings is called");
+STATISTIC(NumRemoveDeadBindings, "The # of times RemoveDeadBindings is called");
 STATISTIC(NumMaxBlockCountReached,
-            "The # of aborted paths due to reaching the maximum block count in "
-            "a top level function");
+          "The # of aborted paths due to reaching the maximum block count in "
+          "a top level function");
 STATISTIC(NumMaxBlockCountReachedInInlined,
-            "The # of aborted paths due to reaching the maximum block count in "
-            "an inlined function");
+          "The # of aborted paths due to reaching the maximum block count in "
+          "an inlined function");
 STATISTIC(NumTimesRetriedWithoutInlining,
-            "The # of times we re-evaluated a call without inlining");
+          "The # of times we re-evaluated a call without inlining");
 
 //===----------------------------------------------------------------------===//
 // Internal program state traits.
@@ -126,7 +125,7 @@ class ConstructedObjectKey {
 
 public:
   explicit ConstructedObjectKey(const ConstructionContextItem &Item,
-                       const LocationContext *LC)
+                                const LocationContext *LC)
       : Impl(Item, LC) {}
 
   const ConstructionContextItem &getItem() const { return Impl.first; }
@@ -216,7 +215,7 @@ REGISTER_TRAIT_WITH_PROGRAMSTATE(PendingArrayDestruction,
 // Engine construction and deletion.
 //===----------------------------------------------------------------------===//
 
-static const char* TagProviderName = "ExprEngine";
+static const char *TagProviderName = "ExprEngine";
 
 ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU,
                        AnalysisManager &mgr, SetOfConstDecls *VisitedCalleesIn,
@@ -267,9 +266,9 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
         break;
 
       SVal V = state->getSVal(loc::MemRegionVal(R));
-      SVal Constraint_untested = evalBinOp(state, BO_GT, V,
-                                           svalBuilder.makeZeroVal(T),
-                                           svalBuilder.getConditionType());
+      SVal Constraint_untested =
+          evalBinOp(state, BO_GT, V, svalBuilder.makeZeroVal(T),
+                    svalBuilder.getConditionType());
 
       std::optional<DefinedOrUnknownSVal> Constraint =
           Constraint_untested.getAs<DefinedOrUnknownSVal>();
@@ -281,8 +280,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
         state = newState;
     }
     break;
-  }
-  while (false);
+  } while (false);
 
   if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
     // Precondition: 'self' is always non-null upon entry to an Objective-C
@@ -657,28 +655,23 @@ bool ExprEngine::areAllObjectsFullyConstructed(ProgramStateRef State,
   return true;
 }
 
-
 //===----------------------------------------------------------------------===//
 // Top-level transfer function logic (Dispatcher).
 //===----------------------------------------------------------------------===//
 
 /// evalAssume - Called by ConstraintManager. Used to call checker-specific
 ///  logic for handling assumptions on symbolic values.
-ProgramStateRef ExprEngine::processAssume(ProgramStateRef state,
-                                              SVal cond, bool assumption) {
+ProgramStateRef ExprEngine::processAssume(ProgramStateRef state, SVal cond,
+                                          bool assumption) {
   return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption);
 }
 
-ProgramStateRef
-ExprEngine::processRegionChanges(ProgramStateRef state,
-                                 const InvalidatedSymbols *invalidated,
-                                 ArrayRef<const MemRegion *> Explicits,
-                                 ArrayRef<const MemRegion *> Regions,
-                                 const LocationContext *LCtx,
-                                 const CallEvent *Call) {
-  return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
-                                                         Explicits, Regions,
-                                                         LCtx, Call);
+ProgramStateRef ExprEngine::processRegionChanges(
+    ProgramStateRef state, const InvalidatedSymbols *invalidated,
+    ArrayRef<const MemRegion *> Explicits, ArrayRef<const MemRegion *> Regions,
+    const LocationContext *LCtx, const CallEvent *Call) {
+  return getCheckerManager().runCheckersForRegionChanges(
+      state, invalidated, Explicits, Regions, LCtx, Call);
 }
 
 static void
@@ -970,38 +963,36 @@ void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred,
   currBldrCtx = Ctx;
 
   switch (E.getKind()) {
-    case CFGElement::Statement:
-    case CFGElement::Constructor:
-    case CFGElement::CXXRecordTypedCall:
-      ProcessStmt(E.castAs<CFGStmt>().getStmt(), Pred);
-      return;
-    case CFGElement::Initializer:
-      ProcessInitializer(E.castAs<CFGInitializer>(), Pred);
-      return;
-    case CFGElement::NewAllocator:
-      ProcessNewAllocator(E.castAs<CFGNewAllocator>().getAllocatorExpr(),
-                          Pred);
-      return;
-    case CFGElement::AutomaticObjectDtor:
-    case CFGElement::DeleteDtor:
-    case CFGElement::BaseDtor:
-    case CFGElement::MemberDtor:
-    case CFGElement::TemporaryDtor:
-      ProcessImplicitDtor(E.castAs<CFGImplicitDtor>(), Pred);
-      return;
-    case CFGElement::LoopExit:
-      ProcessLoopExit(E.castAs<CFGLoopExit>().getLoopStmt(), Pred);
-      return;
-    case CFGElement::LifetimeEnds:
-    case CFGElement::CleanupFunction:
-    case CFGElement::ScopeBegin:
-    case CFGElement::ScopeEnd:
-      return;
+  case CFGElement::Statement:
+  case CFGElement::Constructor:
+  case CFGElement::CXXRecordTypedCall:
+    ProcessStmt(E.castAs<CFGStmt>().getStmt(), Pred);
+    return;
+  case CFGElement::Initializer:
+    ProcessInitializer(E.castAs<CFGInitializer>(), Pred);
+    return;
+  case CFGElement::NewAllocator:
+    ProcessNewAllocator(E.castAs<CFGNewAllocator>().getAllocatorExpr(), Pred);
+    return;
+  case CFGElement::AutomaticObjectDtor:
+  case CFGElement::DeleteDtor:
+  case CFGElement::BaseDtor:
+  case CFGElement::MemberDtor:
+  case CFGElement::TemporaryDtor:
+    ProcessImplicitDtor(E.castAs<CFGImplicitDtor>(), Pred);
+    return;
+  case CFGElement::LoopExit:
+    ProcessLoopExit(E.castAs<CFGLoopExit>().getLoopStmt(), Pred);
+    return;
+  case CFGElement::LifetimeEnds:
+  case CFGElement::CleanupFunction:
+  case CFGElement::ScopeBegin:
+  case CFGElement::ScopeEnd:
+    return;
   }
 }
 
-static bool shouldRemoveDeadBindings(AnalysisManager &AMgr,
-                                     const Stmt *S,
+static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const Stmt *S,
                                      const ExplodedNode *Pred,
                                      const LocationContext *LC) {
   // Are we never purging state values?
@@ -1029,11 +1020,10 @@ static bool shouldRemoveDeadBindings(AnalysisManager &AMgr,
 void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out,
                             const Stmt *ReferenceStmt,
                             const LocationContext *LC,
-                            const Stmt *DiagnosticStmt,
-                            ProgramPoint::Kind K) {
+                            const Stmt *DiagnosticStmt, ProgramPoint::Kind K) {
   assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind ||
-          ReferenceStmt == nullptr || isa<ReturnStmt>(ReferenceStmt))
-          && "PostStmt is not generally supported by the SymbolReaper yet");
+          ReferenceStmt == nullptr || isa<ReturnStmt>(ReferenceStmt)) &&
+         "PostStmt is not generally supported by the SymbolReaper yet");
   assert(LC && "Must pass the current (or expiring) LocationContext");
 
   if (!DiagnosticStmt) {
@@ -1118,8 +1108,7 @@ void ExprEngine::ProcessStmt(const Stmt *currStmt, ExplodedNode *Pred) {
   ExplodedNodeSet CleanedStates;
   if (shouldRemoveDeadBindings(AMgr, currStmt, Pred,
                                Pred->getLocationContext())) {
-    removeDead(Pred, CleanedStates, currStmt,
-                                    Pred->getLocationContext());
+    removeDead(Pred, CleanedStates, currStmt, Pred->getLocationContext());
   } else
     CleanedStates.Add(Pred);
 
@@ -1136,7 +1125,7 @@ void ExprEngine::ProcessStmt(const Stmt *currStmt, ExplodedNode *Pred) {
   Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
 }
 
-void ExprEngine::ProcessLoopExit(const Stmt* S, ExplodedNode *Pred) {
+void ExprEngine::ProcessLoopExit(const Stmt *S, ExplodedNode *Pred) {
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
                                 S->getBeginLoc(),
                                 "Error evaluating end of the loop");
@@ -1145,7 +1134,7 @@ void ExprEngine::ProcessLoopExit(const Stmt* S, ExplodedNode *Pred) {
   NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   ProgramStateRef NewState = Pred->getState();
 
-  if(AMgr.options.ShouldUnrollLoops)
+  if (AMgr.options.ShouldUnrollLoops)
     NewState = processLoopEnd(S, NewState);
 
   LoopExit PP(S, Pred->getLocationContext());
@@ -1211,9 +1200,9 @@ void ExprEngine::ProcessInitializer(const CFGInitializer CFGInit,
         // If we fail to get the value for some reason, use a symbolic value.
         if (InitVal.isUnknownOrUndef()) {
           SValBuilder &SVB = getSValBuilder();
-          InitVal = SVB.conjureSymbolVal(BMI->getInit(), stackFrame,
-                                         Field->getType(),
-                                         currBldrCtx->blockCount());
+          InitVal =
+              SVB.conjureSymbolVal(BMI->getInit(), stackFrame, Field->getType(),
+                                   currBldrCtx->blockCount());
         }
       } else {
         InitVal = State->getSVal(BMI->getInit(), stackFrame);
@@ -1314,8 +1303,7 @@ void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
   Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
 }
 
-void ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE,
-                                     ExplodedNode *Pred) {
+void ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred) {
   ExplodedNodeSet Dst;
   AnalysisManager &AMgr = getAnalysisManager();
   AnalyzerOptions &Opts = AMgr.options;
@@ -1406,8 +1394,7 @@ void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
                      /*IsBase=*/false, Pred, Dst, CallOpts);
 }
 
-void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor,
-                                   ExplodedNode *Pred,
+void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, ExplodedNode *Pred,
                                    ExplodedNodeSet &Dst) {
   ProgramStateRef State = Pred->getState();
   const LocationContext *LCtx = Pred->getLocationContext();
@@ -1482,28 +1469,27 @@ void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor,
   VisitCXXDestructor(DTy, ArgR, DE, /*IsBase=*/false, Pred, Dst, CallOpts);
 }
 
-void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
-                                 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
+void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred,
+                                 ExplodedNodeSet &Dst) {
   const LocationContext *LCtx = Pred->getLocationContext();
 
   const auto *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
-  Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor,
-                                            LCtx->getStackFrame());
+  Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor, LCtx->getStackFrame());
   SVal ThisVal = Pred->getState()->getSVal(ThisPtr);
 
   // Create the base object region.
   const CXXBaseSpecifier *Base = D.getBaseSpecifier();
   QualType BaseTy = Base->getType();
-  SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy,
-                                                     Base->isVirtual());
+  SVal BaseVal =
+      getStoreManager().evalDerivedToBase(ThisVal, BaseTy, Base->isVirtual());
 
   EvalCallOptions CallOpts;
   VisitCXXDestructor(BaseTy, BaseVal.getAsRegion(), CurDtor->getBody(),
                      /*IsBase=*/true, Pred, Dst, CallOpts);
 }
 
-void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
-                                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {
+void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred,
+                                   ExplodedNodeSet &Dst) {
   const auto *DtorDecl = D.getDestructorDecl(getContext());
   const FieldDecl *Member = D.getFieldDecl();
   QualType T = Member->getType();
@@ -1683,8 +1669,7 @@ void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
 }
 
 ProgramStateRef ExprEngine::escapeValues(ProgramStateRef State,
-                                         ArrayRef<SVal> Vs,
-                                         PointerEscapeKind K,
+                                         ArrayRef<SVal> Vs, PointerEscapeKind K,
                                          const CallEvent *Call) const {
   class CollectReachableSymbolsCallback final : public SymbolVisitor {
     InvalidatedSymbols &Symbols;
@@ -1719,709 +1704,707 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
   assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
 
   switch (S->getStmtClass()) {
-    // C++, OpenMP and ARC stuff we don't support yet.
-    case Stmt::CXXDependentScopeMemberExprClass:
-    case Stmt::CXXTryStmtClass:
-    case Stmt::CXXTypeidExprClass:
-    case Stmt::CXXUuidofExprClass:
-    case Stmt::CXXFoldExprClass:
-    case Stmt::MSPropertyRefExprClass:
-    case Stmt::MSPropertySubscriptExprClass:
-    case Stmt::CXXUnresolvedConstructExprClass:
-    case Stmt::DependentScopeDeclRefExprClass:
-    case Stmt::ArrayTypeTraitExprClass:
-    case Stmt::ExpressionTraitExprClass:
-    case Stmt::UnresolvedLookupExprClass:
-    case Stmt::UnresolvedMemberExprClass:
-    case Stmt::TypoExprClass:
-    case Stmt::RecoveryExprClass:
-    case Stmt::CXXNoexceptExprClass:
-    case Stmt::PackExpansionExprClass:
-    case Stmt::PackIndexingExprClass:
-    case Stmt::SubstNonTypeTemplateParmPackExprClass:
-    case Stmt::FunctionParmPackExprClass:
-    case Stmt::CoroutineBodyStmtClass:
-    case Stmt::CoawaitExprClass:
-    case Stmt::DependentCoawaitExprClass:
-    case Stmt::CoreturnStmtClass:
-    case Stmt::CoyieldExprClass:
-    case Stmt::SEHTryStmtClass:
-    case Stmt::SEHExceptStmtClass:
-    case Stmt::SEHLeaveStmtClass:
-    case Stmt::SEHFinallyStmtClass:
-    case Stmt::OMPCanonicalLoopClass:
-    case Stmt::OMPParallelDirectiveClass:
-    case Stmt::OMPSimdDirectiveClass:
-    case Stmt::OMPForDirectiveClass:
-    case Stmt::OMPForSimdDirectiveClass:
-    case Stmt::OMPSectionsDirectiveClass:
-    case Stmt::OMPSectionDirectiveClass:
-    case Stmt::OMPScopeDirectiveClass:
-    case Stmt::OMPSingleDirectiveClass:
-    case Stmt::OMPMasterDirectiveClass:
-    case Stmt::OMPCriticalDirectiveClass:
-    case Stmt::OMPParallelForDirectiveClass:
-    case Stmt::OMPParallelForSimdDirectiveClass:
-    case Stmt::OMPParallelSectionsDirectiveClass:
-    case Stmt::OMPParallelMasterDirectiveClass:
-    case Stmt::OMPParallelMaskedDirectiveClass:
-    case Stmt::OMPTaskDirectiveClass:
-    case Stmt::OMPTaskyieldDirectiveClass:
-    case Stmt::OMPBarrierDirectiveClass:
-    case Stmt::OMPTaskwaitDirectiveClass:
-    case Stmt::OMPErrorDirectiveClass:
-    case Stmt::OMPTaskgroupDirectiveClass:
-    case Stmt::OMPFlushDirectiveClass:
-    case Stmt::OMPDepobjDirectiveClass:
-    case Stmt::OMPScanDirectiveClass:
-    case Stmt::OMPOrderedDirectiveClass:
-    case Stmt::OMPAtomicDirectiveClass:
-    case Stmt::OMPTargetDirectiveClass:
-    case Stmt::OMPTargetDataDirectiveClass:
-    case Stmt::OMPTargetEnterDataDirectiveClass:
-    case Stmt::OMPTargetExitDataDirectiveClass:
-    case Stmt::OMPTargetParallelDirectiveClass:
-    case Stmt::OMPTargetParallelForDirectiveClass:
-    case Stmt::OMPTargetUpdateDirectiveClass:
-    case Stmt::OMPTeamsDirectiveClass:
-    case Stmt::OMPCancellationPointDirectiveClass:
-    case Stmt::OMPCancelDirectiveClass:
-    case Stmt::OMPTaskLoopDirectiveClass:
-    case Stmt::OMPTaskLoopSimdDirectiveClass:
-    case Stmt::OMPMasterTaskLoopDirectiveClass:
-    case Stmt::OMPMaskedTaskLoopDirectiveClass:
-    case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
-    case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
-    case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
-    case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
-    case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
-    case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
-    case Stmt::OMPDistributeDirectiveClass:
-    case Stmt::OMPDistributeParallelForDirectiveClass:
-    case Stmt::OMPDistributeParallelForSimdDirectiveClass:
-    case Stmt::OMPDistributeSimdDirectiveClass:
-    case Stmt::OMPTargetParallelForSimdDirectiveClass:
-    case Stmt::OMPTargetSimdDirectiveClass:
-    case Stmt::OMPTeamsDistributeDirectiveClass:
-    case Stmt::OMPTeamsDistributeSimdDirectiveClass:
-    case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
-    case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
-    case Stmt::OMPTargetTeamsDirectiveClass:
-    case Stmt::OMPTargetTeamsDistributeDirectiveClass:
-    case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
-    case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
-    case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
-    case Stmt::OMPTileDirectiveClass:
-    case Stmt::OMPInteropDirectiveClass:
-    case Stmt::OMPDispatchDirectiveClass:
-    case Stmt::OMPMaskedDirectiveClass:
-    case Stmt::OMPGenericLoopDirectiveClass:
-    case Stmt::OMPTeamsGenericLoopDirectiveClass:
-    case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
-    case Stmt::OMPParallelGenericLoopDirectiveClass:
-    case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
-    case Stmt::CapturedStmtClass:
-    case Stmt::OpenACCComputeConstructClass:
-    case Stmt::OpenACCLoopConstructClass:
-    case Stmt::OMPUnrollDirectiveClass:
-    case Stmt::OMPMetaDirectiveClass: {
-      const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
-      Engine.addAbortedBlock(node, currBldrCtx->getBlock());
-      break;
-    }
+  // C++, OpenMP and ARC stuff we don't support yet.
+  case Stmt::CXXDependentScopeMemberExprClass:
+  case Stmt::CXXTryStmtClass:
+  case Stmt::CXXTypeidExprClass:
+  case Stmt::CXXUuidofExprClass:
+  case Stmt::CXXFoldExprClass:
+  case Stmt::MSPropertyRefExprClass:
+  case Stmt::MSPropertySubscriptExprClass:
+  case Stmt::CXXUnresolvedConstructExprClass:
+  case Stmt::DependentScopeDeclRefExprClass:
+  case Stmt::ArrayTypeTraitExprClass:
+  case Stmt::ExpressionTraitExprClass:
+  case Stmt::UnresolvedLookupExprClass:
+  case Stmt::UnresolvedMemberExprClass:
+  case Stmt::TypoExprClass:
+  case Stmt::RecoveryExprClass:
+  case Stmt::CXXNoexceptExprClass:
+  case Stmt::PackExpansionExprClass:
+  case Stmt::PackIndexingExprClass:
+  case Stmt::SubstNonTypeTemplateParmPackExprClass:
+  case Stmt::FunctionParmPackExprClass:
+  case Stmt::CoroutineBodyStmtClass:
+  case Stmt::CoawaitExprClass:
+  case Stmt::DependentCoawaitExprClass:
+  case Stmt::CoreturnStmtClass:
+  case Stmt::CoyieldExprClass:
+  case Stmt::SEHTryStmtClass:
+  case Stmt::SEHExceptStmtClass:
+  case Stmt::SEHLeaveStmtClass:
+  case Stmt::SEHFinallyStmtClass:
+  case Stmt::OMPCanonicalLoopClass:
+  case Stmt::OMPParallelDirectiveClass:
+  case Stmt::OMPSimdDirectiveClass:
+  case Stmt::OMPForDirectiveClass:
+  case Stmt::OMPForSimdDirectiveClass:
+  case Stmt::OMPSectionsDirectiveClass:
+  case Stmt::OMPSectionDirectiveClass:
+  case Stmt::OMPScopeDirectiveClass:
+  case Stmt::OMPSingleDirectiveClass:
+  case Stmt::OMPMasterDirectiveClass:
+  case Stmt::OMPCriticalDirectiveClass:
+  case Stmt::OMPParallelForDirectiveClass:
+  case Stmt::OMPParallelForSimdDirectiveClass:
+  case Stmt::OMPParallelSectionsDirectiveClass:
+  case Stmt::OMPParallelMasterDirectiveClass:
+  case Stmt::OMPParallelMaskedDirectiveClass:
+  case Stmt::OMPTaskDirectiveClass:
+  case Stmt::OMPTaskyieldDirectiveClass:
+  case Stmt::OMPBarrierDirectiveClass:
+  case Stmt::OMPTaskwaitDirectiveClass:
+  case Stmt::OMPErrorDirectiveClass:
+  case Stmt::OMPTaskgroupDirectiveClass:
+  case Stmt::OMPFlushDirectiveClass:
+  case Stmt::OMPDepobjDirectiveClass:
+  case Stmt::OMPScanDirectiveClass:
+  case Stmt::OMPOrderedDirectiveClass:
+  case Stmt::OMPAtomicDirectiveClass:
+  case Stmt::OMPTargetDirectiveClass:
+  case Stmt::OMPTargetDataDirectiveClass:
+  case Stmt::OMPTargetEnterDataDirectiveClass:
+  case Stmt::OMPTargetExitDataDirectiveClass:
+  case Stmt::OMPTargetParallelDirectiveClass:
+  case Stmt::OMPTargetParallelForDirectiveClass:
+  case Stmt::OMPTargetUpdateDirectiveClass:
+  case Stmt::OMPTeamsDirectiveClass:
+  case Stmt::OMPCancellationPointDirectiveClass:
+  case Stmt::OMPCancelDirectiveClass:
+  case Stmt::OMPTaskLoopDirectiveClass:
+  case Stmt::OMPTaskLoopSimdDirectiveClass:
+  case Stmt::OMPMasterTaskLoopDirectiveClass:
+  case Stmt::OMPMaskedTaskLoopDirectiveClass:
+  case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
+  case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
+  case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
+  case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
+  case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
+  case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
+  case Stmt::OMPDistributeDirectiveClass:
+  case Stmt::OMPDistributeParallelForDirectiveClass:
+  case Stmt::OMPDistributeParallelForSimdDirectiveClass:
+  case Stmt::OMPDistributeSimdDirectiveClass:
+  case Stmt::OMPTargetParallelForSimdDirectiveClass:
+  case Stmt::OMPTargetSimdDirectiveClass:
+  case Stmt::OMPTeamsDistributeDirectiveClass:
+  case Stmt::OMPTeamsDistributeSimdDirectiveClass:
+  case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
+  case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
+  case Stmt::OMPTargetTeamsDirectiveClass:
+  case Stmt::OMPTargetTeamsDistributeDirectiveClass:
+  case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
+  case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
+  case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
+  case Stmt::OMPTileDirectiveClass:
+  case Stmt::OMPInteropDirectiveClass:
+  case Stmt::OMPDispatchDirectiveClass:
+  case Stmt::OMPMaskedDirectiveClass:
+  case Stmt::OMPGenericLoopDirectiveClass:
+  case Stmt::OMPTeamsGenericLoopDirectiveClass:
+  case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
+  case Stmt::OMPParallelGenericLoopDirectiveClass:
+  case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
+  case Stmt::CapturedStmtClass:
+  case Stmt::OpenACCComputeConstructClass:
+  case Stmt::OpenACCLoopConstructClass:
+  case Stmt::OMPUnrollDirectiveClass:
+  case Stmt::OMPMetaDirectiveClass: {
+    const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
+    Engine.addAbortedBlock(node, currBldrCtx->getBlock());
+    break;
+  }
 
-    case Stmt::ParenExprClass:
-      llvm_unreachable("ParenExprs already handled.");
-    case Stmt::GenericSelectionExprClass:
-      llvm_unreachable("GenericSelectionExprs already handled.");
-    // Cases that should never be evaluated simply because they shouldn't
-    // appear in the CFG.
-    case Stmt::BreakStmtClass:
-    case Stmt::CaseStmtClass:
-    case Stmt::CompoundStmtClass:
-    case Stmt::ContinueStmtClass:
-    case Stmt::CXXForRangeStmtClass:
-    case Stmt::DefaultStmtClass:
-    case Stmt::DoStmtClass:
-    case Stmt::ForStmtClass:
-    case Stmt::GotoStmtClass:
-    case Stmt::IfStmtClass:
-    case Stmt::IndirectGotoStmtClass:
-    case Stmt::LabelStmtClass:
-    case Stmt::NoStmtClass:
-    case Stmt::NullStmtClass:
-    case Stmt::SwitchStmtClass:
-    case Stmt::WhileStmtClass:
-    case Expr::MSDependentExistsStmtClass:
-      llvm_unreachable("Stmt should not be in analyzer evaluation loop");
-    case Stmt::ImplicitValueInitExprClass:
-      // These nodes are shared in the CFG and would case caching out.
-      // Moreover, no additional evaluation required for them, the
-      // analyzer can reconstruct these values from the AST.
-      llvm_unreachable("Should be pruned from CFG");
-
-    case Stmt::ObjCSubscriptRefExprClass:
-    case Stmt::ObjCPropertyRefExprClass:
-      llvm_unreachable("These are handled by PseudoObjectExpr");
-
-    case Stmt::GNUNullExprClass: {
-      // GNU __null is a pointer-width integer, not an actual pointer.
-      ProgramStateRef state = Pred->getState();
-      state = state->BindExpr(
-          S, Pred->getLocationContext(),
-          svalBuilder.makeIntValWithWidth(getContext().VoidPtrTy, 0));
-      Bldr.generateNode(S, Pred, state);
-      break;
-    }
+  case Stmt::ParenExprClass:
+    llvm_unreachable("ParenExprs already handled.");
+  case Stmt::GenericSelectionExprClass:
+    llvm_unreachable("GenericSelectionExprs already handled.");
+  // Cases that should never be evaluated simply because they shouldn't
+  // appear in the CFG.
+  case Stmt::BreakStmtClass:
+  case Stmt::CaseStmtClass:
+  case Stmt::CompoundStmtClass:
+  case Stmt::ContinueStmtClass:
+  case Stmt::CXXForRangeStmtClass:
+  case Stmt::DefaultStmtClass:
+  case Stmt::DoStmtClass:
+  case Stmt::ForStmtClass:
+  case Stmt::GotoStmtClass:
+  case Stmt::IfStmtClass:
+  case Stmt::IndirectGotoStmtClass:
+  case Stmt::LabelStmtClass:
+  case Stmt::NoStmtClass:
+  case Stmt::NullStmtClass:
+  case Stmt::SwitchStmtClass:
+  case Stmt::WhileStmtClass:
+  case Expr::MSDependentExistsStmtClass:
+    llvm_unreachable("Stmt should not be in analyzer evaluation loop");
+  case Stmt::ImplicitValueInitExprClass:
+    // These nodes are shared in the CFG and would case caching out.
+    // Moreover, no additional evaluation required for them, the
+    // analyzer can reconstruct these values from the AST.
+    llvm_unreachable("Should be pruned from CFG");
+
+  case Stmt::ObjCSubscriptRefExprClass:
+  case Stmt::ObjCPropertyRefExprClass:
+    llvm_unreachable("These are handled by PseudoObjectExpr");
+
+  case Stmt::GNUNullExprClass: {
+    // GNU __null is a pointer-width integer, not an actual pointer.
+    ProgramStateRef state = Pred->getState();
+    state = state->BindExpr(
+        S, Pred->getLocationContext(),
+        svalBuilder.makeIntValWithWidth(getContext().VoidPtrTy, 0));
+    Bldr.generateNode(S, Pred, state);
+    break;
+  }
 
-    case Stmt::ObjCAtSynchronizedStmtClass:
-      Bldr.takeNodes(Pred);
-      VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Stmt::ObjCAtSynchronizedStmtClass:
+    Bldr.takeNodes(Pred);
+    VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Expr::ConstantExprClass:
-    case Stmt::ExprWithCleanupsClass:
-      // Handled due to fully linearised CFG.
-      break;
+  case Expr::ConstantExprClass:
+  case Stmt::ExprWithCleanupsClass:
+    // Handled due to fully linearised CFG.
+    break;
 
-    case Stmt::CXXBindTemporaryExprClass: {
-      Bldr.takeNodes(Pred);
-      ExplodedNodeSet PreVisit;
-      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
-      ExplodedNodeSet Next;
-      VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), PreVisit, Next);
-      getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this);
-      Bldr.addNodes(Dst);
-      break;
-    }
+  case Stmt::CXXBindTemporaryExprClass: {
+    Bldr.takeNodes(Pred);
+    ExplodedNodeSet PreVisit;
+    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+    ExplodedNodeSet Next;
+    VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), PreVisit, Next);
+    getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-    case Stmt::ArrayInitLoopExprClass:
-      Bldr.takeNodes(Pred);
-      VisitArrayInitLoopExpr(cast<ArrayInitLoopExpr>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
-    // Cases not handled yet; but will handle some day.
-    case Stmt::DesignatedInitExprClass:
-    case Stmt::DesignatedInitUpdateExprClass:
-    case Stmt::ArrayInitIndexExprClass:
-    case Stmt::ExtVectorElementExprClass:
-    case Stmt::ImaginaryLiteralClass:
-    case Stmt::ObjCAtCatchStmtClass:
-    case Stmt::ObjCAtFinallyStmtClass:
-    case Stmt::ObjCAtTryStmtClass:
-    case Stmt::ObjCAutoreleasePoolStmtClass:
-    case Stmt::ObjCEncodeExprClass:
-    case Stmt::ObjCIsaExprClass:
-    case Stmt::ObjCProtocolExprClass:
-    case Stmt::ObjCSelectorExprClass:
-    case Stmt::ParenListExprClass:
-    case Stmt::ShuffleVectorExprClass:
-    case Stmt::ConvertVectorExprClass:
-    case Stmt::VAArgExprClass:
-    case Stmt::CUDAKernelCallExprClass:
-    case Stmt::OpaqueValueExprClass:
-    case Stmt::AsTypeExprClass:
-    case Stmt::ConceptSpecializationExprClass:
-    case Stmt::CXXRewrittenBinaryOperatorClass:
-    case Stmt::RequiresExprClass:
-    case Expr::CXXParenListInitExprClass:
-      // Fall through.
-
-    // Cases we intentionally don't evaluate, since they don't need
-    // to be explicitly evaluated.
-    case Stmt::PredefinedExprClass:
-    case Stmt::AddrLabelExprClass:
-    case Stmt::AttributedStmtClass:
-    case Stmt::IntegerLiteralClass:
-    case Stmt::FixedPointLiteralClass:
-    case Stmt::CharacterLiteralClass:
-    case Stmt::CXXScalarValueInitExprClass:
-    case Stmt::CXXBoolLiteralExprClass:
-    case Stmt::ObjCBoolLiteralExprClass:
-    case Stmt::ObjCAvailabilityCheckExprClass:
-    case Stmt::FloatingLiteralClass:
-    case Stmt::NoInitExprClass:
-    case Stmt::SizeOfPackExprClass:
-    case Stmt::StringLiteralClass:
-    case Stmt::SourceLocExprClass:
-    case Stmt::ObjCStringLiteralClass:
-    case Stmt::CXXPseudoDestructorExprClass:
-    case Stmt::SubstNonTypeTemplateParmExprClass:
-    case Stmt::CXXNullPtrLiteralExprClass:
-    case Stmt::ArraySectionExprClass:
-    case Stmt::OMPArrayShapingExprClass:
-    case Stmt::OMPIteratorExprClass:
-    case Stmt::SYCLUniqueStableNameExprClass:
-    case Stmt::TypeTraitExprClass: {
-      Bldr.takeNodes(Pred);
-      ExplodedNodeSet preVisit;
-      getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
-      getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this);
-      Bldr.addNodes(Dst);
-      break;
-    }
+  case Stmt::ArrayInitLoopExprClass:
+    Bldr.takeNodes(Pred);
+    VisitArrayInitLoopExpr(cast<ArrayInitLoopExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
+  // Cases not handled yet; but will handle some day.
+  case Stmt::DesignatedInitExprClass:
+  case Stmt::DesignatedInitUpdateExprClass:
+  case Stmt::ArrayInitIndexExprClass:
+  case Stmt::ExtVectorElementExprClass:
+  case Stmt::ImaginaryLiteralClass:
+  case Stmt::ObjCAtCatchStmtClass:
+  case Stmt::ObjCAtFinallyStmtClass:
+  case Stmt::ObjCAtTryStmtClass:
+  case Stmt::ObjCAutoreleasePoolStmtClass:
+  case Stmt::ObjCEncodeExprClass:
+  case Stmt::ObjCIsaExprClass:
+  case Stmt::ObjCProtocolExprClass:
+  case Stmt::ObjCSelectorExprClass:
+  case Stmt::ParenListExprClass:
+  case Stmt::ShuffleVectorExprClass:
+  case Stmt::ConvertVectorExprClass:
+  case Stmt::VAArgExprClass:
+  case Stmt::CUDAKernelCallExprClass:
+  case Stmt::OpaqueValueExprClass:
+  case Stmt::AsTypeExprClass:
+  case Stmt::ConceptSpecializationExprClass:
+  case Stmt::CXXRewrittenBinaryOperatorClass:
+  case Stmt::RequiresExprClass:
+  case Expr::CXXParenListInitExprClass:
+    // Fall through.
+
+  // Cases we intentionally don't evaluate, since they don't need
+  // to be explicitly evaluated.
+  case Stmt::PredefinedExprClass:
+  case Stmt::AddrLabelExprClass:
+  case Stmt::AttributedStmtClass:
+  case Stmt::IntegerLiteralClass:
+  case Stmt::FixedPointLiteralClass:
+  case Stmt::CharacterLiteralClass:
+  case Stmt::CXXScalarValueInitExprClass:
+  case Stmt::CXXBoolLiteralExprClass:
+  case Stmt::ObjCBoolLiteralExprClass:
+  case Stmt::ObjCAvailabilityCheckExprClass:
+  case Stmt::FloatingLiteralClass:
+  case Stmt::NoInitExprClass:
+  case Stmt::SizeOfPackExprClass:
+  case Stmt::StringLiteralClass:
+  case Stmt::SourceLocExprClass:
+  case Stmt::ObjCStringLiteralClass:
+  case Stmt::CXXPseudoDestructorExprClass:
+  case Stmt::SubstNonTypeTemplateParmExprClass:
+  case Stmt::CXXNullPtrLiteralExprClass:
+  case Stmt::ArraySectionExprClass:
+  case Stmt::OMPArrayShapingExprClass:
+  case Stmt::OMPIteratorExprClass:
+  case Stmt::SYCLUniqueStableNameExprClass:
+  case Stmt::TypeTraitExprClass: {
+    Bldr.takeNodes(Pred);
+    ExplodedNodeSet preVisit;
+    getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
+    getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-    case Stmt::CXXDefaultArgExprClass:
-    case Stmt::CXXDefaultInitExprClass: {
-      Bldr.takeNodes(Pred);
-      ExplodedNodeSet PreVisit;
-      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+  case Stmt::CXXDefaultArgExprClass:
+  case Stmt::CXXDefaultInitExprClass: {
+    Bldr.takeNodes(Pred);
+    ExplodedNodeSet PreVisit;
+    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
 
-      ExplodedNodeSet Tmp;
-      StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx);
+    ExplodedNodeSet Tmp;
+    StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx);
 
-      const Expr *ArgE;
-      if (const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
-        ArgE = DefE->getExpr();
-      else if (const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
-        ArgE = DefE->getExpr();
-      else
-        llvm_unreachable("unknown constant wrapper kind");
+    const Expr *ArgE;
+    if (const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
+      ArgE = DefE->getExpr();
+    else if (const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
+      ArgE = DefE->getExpr();
+    else
+      llvm_unreachable("unknown constant wrapper kind");
 
-      bool IsTemporary = false;
-      if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
-        ArgE = MTE->getSubExpr();
-        IsTemporary = true;
-      }
+    bool IsTemporary = false;
+    if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
+      ArgE = MTE->getSubExpr();
+      IsTemporary = true;
+    }
 
-      std::optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE);
-      if (!ConstantVal)
-        ConstantVal = UnknownVal();
-
-      const LocationContext *LCtx = Pred->getLocationContext();
-      for (const auto I : PreVisit) {
-        ProgramStateRef State = I->getState();
-        State = State->BindExpr(S, LCtx, *ConstantVal);
-        if (IsTemporary)
-          State = createTemporaryRegionIfNeeded(State, LCtx,
-                                                cast<Expr>(S),
-                                                cast<Expr>(S));
-        Bldr2.generateNode(S, I, State);
-      }
+    std::optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE);
+    if (!ConstantVal)
+      ConstantVal = UnknownVal();
 
-      getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
-      Bldr.addNodes(Dst);
-      break;
+    const LocationContext *LCtx = Pred->getLocationContext();
+    for (const auto I : PreVisit) {
+      ProgramStateRef State = I->getState();
+      State = State->BindExpr(S, LCtx, *ConstantVal);
+      if (IsTemporary)
+        State = createTemporaryRegionIfNeeded(State, LCtx, cast<Expr>(S),
+                                              cast<Expr>(S));
+      Bldr2.generateNode(S, I, State);
     }
 
-    // Cases we evaluate as opaque expressions, conjuring a symbol.
-    case Stmt::CXXStdInitializerListExprClass:
-    case Expr::ObjCArrayLiteralClass:
-    case Expr::ObjCDictionaryLiteralClass:
-    case Expr::ObjCBoxedExprClass: {
-      Bldr.takeNodes(Pred);
+    getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-      ExplodedNodeSet preVisit;
-      getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
+  // Cases we evaluate as opaque expressions, conjuring a symbol.
+  case Stmt::CXXStdInitializerListExprClass:
+  case Expr::ObjCArrayLiteralClass:
+  case Expr::ObjCDictionaryLiteralClass:
+  case Expr::ObjCBoxedExprClass: {
+    Bldr.takeNodes(Pred);
 
-      ExplodedNodeSet Tmp;
-      StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx);
-
-      const auto *Ex = cast<Expr>(S);
-      QualType resultType = Ex->getType();
-
-      for (const auto N : preVisit) {
-        const LocationContext *LCtx = N->getLocationContext();
-        SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
-                                                   resultType,
-                                                   currBldrCtx->blockCount());
-        ProgramStateRef State = N->getState()->BindExpr(Ex, LCtx, result);
-
-        // Escape pointers passed into the list, unless it's an ObjC boxed
-        // expression which is not a boxable C structure.
-        if (!(isa<ObjCBoxedExpr>(Ex) &&
-              !cast<ObjCBoxedExpr>(Ex)->getSubExpr()
-                                      ->getType()->isRecordType()))
-          for (auto Child : Ex->children()) {
-            assert(Child);
-            SVal Val = State->getSVal(Child, LCtx);
-            State = escapeValues(State, Val, PSK_EscapeOther);
-          }
+    ExplodedNodeSet preVisit;
+    getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
 
-        Bldr2.generateNode(S, N, State);
-      }
+    ExplodedNodeSet Tmp;
+    StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx);
+
+    const auto *Ex = cast<Expr>(S);
+    QualType resultType = Ex->getType();
+
+    for (const auto N : preVisit) {
+      const LocationContext *LCtx = N->getLocationContext();
+      SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx, resultType,
+                                                 currBldrCtx->blockCount());
+      ProgramStateRef State = N->getState()->BindExpr(Ex, LCtx, result);
+
+      // Escape pointers passed into the list, unless it's an ObjC boxed
+      // expression which is not a boxable C structure.
+      if (!(isa<ObjCBoxedExpr>(Ex) &&
+            !cast<ObjCBoxedExpr>(Ex)->getSubExpr()->getType()->isRecordType()))
+        for (auto Child : Ex->children()) {
+          assert(Child);
+          SVal Val = State->getSVal(Child, LCtx);
+          State = escapeValues(State, Val, PSK_EscapeOther);
+        }
 
-      getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
-      Bldr.addNodes(Dst);
-      break;
+      Bldr2.generateNode(S, N, State);
     }
 
-    case Stmt::ArraySubscriptExprClass:
-      Bldr.takeNodes(Pred);
-      VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+    getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-    case Stmt::MatrixSubscriptExprClass:
-      llvm_unreachable("Support for MatrixSubscriptExpr is not implemented.");
-      break;
+  case Stmt::ArraySubscriptExprClass:
+    Bldr.takeNodes(Pred);
+    VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::GCCAsmStmtClass:
-      Bldr.takeNodes(Pred);
-      VisitGCCAsmStmt(cast<GCCAsmStmt>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Stmt::MatrixSubscriptExprClass:
+    llvm_unreachable("Support for MatrixSubscriptExpr is not implemented.");
+    break;
+
+  case Stmt::GCCAsmStmtClass: {
+    Bldr.takeNodes(Pred);
+    ExplodedNodeSet PreVisit;
+    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+    ExplodedNodeSet PostVisit;
+    for (ExplodedNode *const N : PreVisit)
+      VisitGCCAsmStmt(cast<GCCAsmStmt>(S), N, PostVisit);
+    getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
+    Bldr.addNodes(Dst);
+  } break;
+
+  case Stmt::MSAsmStmtClass:
+    Bldr.takeNodes(Pred);
+    VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
+
+  case Stmt::BlockExprClass:
+    Bldr.takeNodes(Pred);
+    VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::MSAsmStmtClass:
+  case Stmt::LambdaExprClass:
+    if (AMgr.options.ShouldInlineLambdas) {
       Bldr.takeNodes(Pred);
-      VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst);
+      VisitLambdaExpr(cast<LambdaExpr>(S), Pred, Dst);
       Bldr.addNodes(Dst);
-      break;
+    } else {
+      const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
+      Engine.addAbortedBlock(node, currBldrCtx->getBlock());
+    }
+    break;
 
-    case Stmt::BlockExprClass:
+  case Stmt::BinaryOperatorClass: {
+    const auto *B = cast<BinaryOperator>(S);
+    if (B->isLogicalOp()) {
       Bldr.takeNodes(Pred);
-      VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
+      VisitLogicalExpr(B, Pred, Dst);
       Bldr.addNodes(Dst);
       break;
-
-    case Stmt::LambdaExprClass:
-      if (AMgr.options.ShouldInlineLambdas) {
-        Bldr.takeNodes(Pred);
-        VisitLambdaExpr(cast<LambdaExpr>(S), Pred, Dst);
-        Bldr.addNodes(Dst);
-      } else {
-        const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
-        Engine.addAbortedBlock(node, currBldrCtx->getBlock());
-      }
+    } else if (B->getOpcode() == BO_Comma) {
+      ProgramStateRef state = Pred->getState();
+      Bldr.generateNode(
+          B, Pred,
+          state->BindExpr(
+              B, Pred->getLocationContext(),
+              state->getSVal(B->getRHS(), Pred->getLocationContext())));
       break;
+    }
 
-    case Stmt::BinaryOperatorClass: {
-      const auto *B = cast<BinaryOperator>(S);
-      if (B->isLogicalOp()) {
-        Bldr.takeNodes(Pred);
-        VisitLogicalExpr(B, Pred, Dst);
-        Bldr.addNodes(Dst);
-        break;
-      }
-      else if (B->getOpcode() == BO_Comma) {
-        ProgramStateRef state = Pred->getState();
-        Bldr.generateNode(B, Pred,
-                          state->BindExpr(B, Pred->getLocationContext(),
-                                          state->getSVal(B->getRHS(),
-                                                  Pred->getLocationContext())));
-        break;
-      }
+    Bldr.takeNodes(Pred);
 
-      Bldr.takeNodes(Pred);
+    if (AMgr.options.ShouldEagerlyAssume &&
+        (B->isRelationalOp() || B->isEqualityOp())) {
+      ExplodedNodeSet Tmp;
+      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
+      evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S));
+    } else
+      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
 
-      if (AMgr.options.ShouldEagerlyAssume &&
-          (B->isRelationalOp() || B->isEqualityOp())) {
-        ExplodedNodeSet Tmp;
-        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
-        evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S));
-      }
-      else
-        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-      Bldr.addNodes(Dst);
-      break;
-    }
+  case Stmt::CXXOperatorCallExprClass: {
+    const auto *OCE = cast<CXXOperatorCallExpr>(S);
 
-    case Stmt::CXXOperatorCallExprClass: {
-      const auto *OCE = cast<CXXOperatorCallExpr>(S);
-
-      // For instance method operators, make sure the 'this' argument has a
-      // valid region.
-      const Decl *Callee = OCE->getCalleeDecl();
-      if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
-        if (MD->isImplicitObjectMemberFunction()) {
-          ProgramStateRef State = Pred->getState();
-          const LocationContext *LCtx = Pred->getLocationContext();
-          ProgramStateRef NewState =
+    // For instance method operators, make sure the 'this' argument has a
+    // valid region.
+    const Decl *Callee = OCE->getCalleeDecl();
+    if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
+      if (MD->isImplicitObjectMemberFunction()) {
+        ProgramStateRef State = Pred->getState();
+        const LocationContext *LCtx = Pred->getLocationContext();
+        ProgramStateRef NewState =
             createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
-          if (NewState != State) {
-            Pred = Bldr.generateNode(OCE, Pred, NewState, /*tag=*/nullptr,
-                                     ProgramPoint::PreStmtKind);
-            // Did we cache out?
-            if (!Pred)
-              break;
-          }
+        if (NewState != State) {
+          Pred = Bldr.generateNode(OCE, Pred, NewState, /*tag=*/nullptr,
+                                   ProgramPoint::PreStmtKind);
+          // Did we cache out?
+          if (!Pred)
+            break;
         }
       }
-      [[fallthrough]];
     }
+    [[fallthrough]];
+  }
 
-    case Stmt::CallExprClass:
-    case Stmt::CXXMemberCallExprClass:
-    case Stmt::UserDefinedLiteralClass:
-      Bldr.takeNodes(Pred);
-      VisitCallExpr(cast<CallExpr>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
-
-    case Stmt::CXXCatchStmtClass:
-      Bldr.takeNodes(Pred);
-      VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
-
-    case Stmt::CXXTemporaryObjectExprClass:
-    case Stmt::CXXConstructExprClass:
-      Bldr.takeNodes(Pred);
-      VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
-
-    case Stmt::CXXInheritedCtorInitExprClass:
-      Bldr.takeNodes(Pred);
-      VisitCXXInheritedCtorInitExpr(cast<CXXInheritedCtorInitExpr>(S), Pred,
-                                    Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Stmt::CallExprClass:
+  case Stmt::CXXMemberCallExprClass:
+  case Stmt::UserDefinedLiteralClass:
+    Bldr.takeNodes(Pred);
+    VisitCallExpr(cast<CallExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::CXXNewExprClass: {
-      Bldr.takeNodes(Pred);
+  case Stmt::CXXCatchStmtClass:
+    Bldr.takeNodes(Pred);
+    VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-      ExplodedNodeSet PreVisit;
-      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+  case Stmt::CXXTemporaryObjectExprClass:
+  case Stmt::CXXConstructExprClass:
+    Bldr.takeNodes(Pred);
+    VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-      ExplodedNodeSet PostVisit;
-      for (const auto i : PreVisit)
-        VisitCXXNewExpr(cast<CXXNewExpr>(S), i, PostVisit);
+  case Stmt::CXXInheritedCtorInitExprClass:
+    Bldr.takeNodes(Pred);
+    VisitCXXInheritedCtorInitExpr(cast<CXXInheritedCtorInitExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-      getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
-      Bldr.addNodes(Dst);
-      break;
-    }
+  case Stmt::CXXNewExprClass: {
+    Bldr.takeNodes(Pred);
 
-    case Stmt::CXXDeleteExprClass: {
-      Bldr.takeNodes(Pred);
-      ExplodedNodeSet PreVisit;
-      const auto *CDE = cast<CXXDeleteExpr>(S);
-      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
-      ExplodedNodeSet PostVisit;
-      getCheckerManager().runCheckersForPostStmt(PostVisit, PreVisit, S, *this);
+    ExplodedNodeSet PreVisit;
+    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
 
-      for (const auto i : PostVisit)
-        VisitCXXDeleteExpr(CDE, i, Dst);
+    ExplodedNodeSet PostVisit;
+    for (const auto i : PreVisit)
+      VisitCXXNewExpr(cast<CXXNewExpr>(S), i, PostVisit);
 
-      Bldr.addNodes(Dst);
-      break;
-    }
-      // FIXME: ChooseExpr is really a constant.  We need to fix
-      //        the CFG do not model them as explicit control-flow.
+    getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-    case Stmt::ChooseExprClass: { // __builtin_choose_expr
-      Bldr.takeNodes(Pred);
-      const auto *C = cast<ChooseExpr>(S);
-      VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
-    }
+  case Stmt::CXXDeleteExprClass: {
+    Bldr.takeNodes(Pred);
+    ExplodedNodeSet PreVisit;
+    const auto *CDE = cast<CXXDeleteExpr>(S);
+    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+    ExplodedNodeSet PostVisit;
+    getCheckerManager().runCheckersForPostStmt(PostVisit, PreVisit, S, *this);
 
-    case Stmt::CompoundAssignOperatorClass:
-      Bldr.takeNodes(Pred);
-      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+    for (const auto i : PostVisit)
+      VisitCXXDeleteExpr(CDE, i, Dst);
 
-    case Stmt::CompoundLiteralExprClass:
-      Bldr.takeNodes(Pred);
-      VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+    Bldr.addNodes(Dst);
+    break;
+  }
+    // FIXME: ChooseExpr is really a constant.  We need to fix
+    //        the CFG do not model them as explicit control-flow.
 
-    case Stmt::BinaryConditionalOperatorClass:
-    case Stmt::ConditionalOperatorClass: { // '?' operator
-      Bldr.takeNodes(Pred);
-      const auto *C = cast<AbstractConditionalOperator>(S);
-      VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
-    }
+  case Stmt::ChooseExprClass: { // __builtin_choose_expr
+    Bldr.takeNodes(Pred);
+    const auto *C = cast<ChooseExpr>(S);
+    VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-    case Stmt::CXXThisExprClass:
-      Bldr.takeNodes(Pred);
-      VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Stmt::CompoundAssignOperatorClass:
+    Bldr.takeNodes(Pred);
+    VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::DeclRefExprClass: {
-      Bldr.takeNodes(Pred);
-      const auto *DE = cast<DeclRefExpr>(S);
-      VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
-    }
+  case Stmt::CompoundLiteralExprClass:
+    Bldr.takeNodes(Pred);
+    VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::DeclStmtClass:
-      Bldr.takeNodes(Pred);
-      VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Stmt::BinaryConditionalOperatorClass:
+  case Stmt::ConditionalOperatorClass: { // '?' operator
+    Bldr.takeNodes(Pred);
+    const auto *C = cast<AbstractConditionalOperator>(S);
+    VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-    case Stmt::ImplicitCastExprClass:
-    case Stmt::CStyleCastExprClass:
-    case Stmt::CXXStaticCastExprClass:
-    case Stmt::CXXDynamicCastExprClass:
-    case Stmt::CXXReinterpretCastExprClass:
-    case Stmt::CXXConstCastExprClass:
-    case Stmt::CXXFunctionalCastExprClass:
-    case Stmt::BuiltinBitCastExprClass:
-    case Stmt::ObjCBridgedCastExprClass:
-    case Stmt::CXXAddrspaceCastExprClass: {
-      Bldr.takeNodes(Pred);
-      const auto *C = cast<CastExpr>(S);
-      ExplodedNodeSet dstExpr;
-      VisitCast(C, C->getSubExpr(), Pred, dstExpr);
+  case Stmt::CXXThisExprClass:
+    Bldr.takeNodes(Pred);
+    VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-      // Handle the postvisit checks.
-      getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this);
-      Bldr.addNodes(Dst);
-      break;
-    }
+  case Stmt::DeclRefExprClass: {
+    Bldr.takeNodes(Pred);
+    const auto *DE = cast<DeclRefExpr>(S);
+    VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-    case Expr::MaterializeTemporaryExprClass: {
-      Bldr.takeNodes(Pred);
-      const auto *MTE = cast<MaterializeTemporaryExpr>(S);
-      ExplodedNodeSet dstPrevisit;
-      getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, MTE, *this);
-      ExplodedNodeSet dstExpr;
-      for (const auto i : dstPrevisit)
-        CreateCXXTemporaryObject(MTE, i, dstExpr);
-      getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, MTE, *this);
-      Bldr.addNodes(Dst);
-      break;
-    }
+  case Stmt::DeclStmtClass:
+    Bldr.takeNodes(Pred);
+    VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::InitListExprClass:
-      Bldr.takeNodes(Pred);
-      VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Stmt::ImplicitCastExprClass:
+  case Stmt::CStyleCastExprClass:
+  case Stmt::CXXStaticCastExprClass:
+  case Stmt::CXXDynamicCastExprClass:
+  case Stmt::CXXReinterpretCastExprClass:
+  case Stmt::CXXConstCastExprClass:
+  case Stmt::CXXFunctionalCastExprClass:
+  case Stmt::BuiltinBitCastExprClass:
+  case Stmt::ObjCBridgedCastExprClass:
+  case Stmt::CXXAddrspaceCastExprClass: {
+    Bldr.takeNodes(Pred);
+    const auto *C = cast<CastExpr>(S);
+    ExplodedNodeSet dstExpr;
+    VisitCast(C, C->getSubExpr(), Pred, dstExpr);
+
+    // Handle the postvisit checks.
+    getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-    case Stmt::MemberExprClass:
-      Bldr.takeNodes(Pred);
-      VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Expr::MaterializeTemporaryExprClass: {
+    Bldr.takeNodes(Pred);
+    const auto *MTE = cast<MaterializeTemporaryExpr>(S);
+    ExplodedNodeSet dstPrevisit;
+    getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, MTE, *this);
+    ExplodedNodeSet dstExpr;
+    for (const auto i : dstPrevisit)
+      CreateCXXTemporaryObject(MTE, i, dstExpr);
+    getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, MTE, *this);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-    case Stmt::AtomicExprClass:
-      Bldr.takeNodes(Pred);
-      VisitAtomicExpr(cast<AtomicExpr>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Stmt::InitListExprClass:
+    Bldr.takeNodes(Pred);
+    VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::ObjCIvarRefExprClass:
-      Bldr.takeNodes(Pred);
-      VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Stmt::MemberExprClass:
+    Bldr.takeNodes(Pred);
+    VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::ObjCForCollectionStmtClass:
-      Bldr.takeNodes(Pred);
-      VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Stmt::AtomicExprClass:
+    Bldr.takeNodes(Pred);
+    VisitAtomicExpr(cast<AtomicExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::ObjCMessageExprClass:
-      Bldr.takeNodes(Pred);
-      VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Stmt::ObjCIvarRefExprClass:
+    Bldr.takeNodes(Pred);
+    VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::ObjCAtThrowStmtClass:
-    case Stmt::CXXThrowExprClass:
-      // FIXME: This is not complete.  We basically treat @throw as
-      // an abort.
-      Bldr.generateSink(S, Pred, Pred->getState());
-      break;
+  case Stmt::ObjCForCollectionStmtClass:
+    Bldr.takeNodes(Pred);
+    VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::ReturnStmtClass:
-      Bldr.takeNodes(Pred);
-      VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+  case Stmt::ObjCMessageExprClass:
+    Bldr.takeNodes(Pred);
+    VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-    case Stmt::OffsetOfExprClass: {
-      Bldr.takeNodes(Pred);
-      ExplodedNodeSet PreVisit;
-      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+  case Stmt::ObjCAtThrowStmtClass:
+  case Stmt::CXXThrowExprClass:
+    // FIXME: This is not complete.  We basically treat @throw as
+    // an abort.
+    Bldr.generateSink(S, Pred, Pred->getState());
+    break;
 
-      ExplodedNodeSet PostVisit;
-      for (const auto Node : PreVisit)
-        VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Node, PostVisit);
+  case Stmt::ReturnStmtClass:
+    Bldr.takeNodes(Pred);
+    VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-      getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
-      Bldr.addNodes(Dst);
-      break;
-    }
+  case Stmt::OffsetOfExprClass: {
+    Bldr.takeNodes(Pred);
+    ExplodedNodeSet PreVisit;
+    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
 
-    case Stmt::UnaryExprOrTypeTraitExprClass:
-      Bldr.takeNodes(Pred);
-      VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
-                                    Pred, Dst);
-      Bldr.addNodes(Dst);
-      break;
+    ExplodedNodeSet PostVisit;
+    for (const auto Node : PreVisit)
+      VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Node, PostVisit);
 
-    case Stmt::StmtExprClass: {
-      const auto *SE = cast<StmtExpr>(S);
+    getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
+    Bldr.addNodes(Dst);
+    break;
+  }
 
-      if (SE->getSubStmt()->body_empty()) {
-        // Empty statement expression.
-        assert(SE->getType() == getContext().VoidTy
-               && "Empty statement expression must have void type.");
-        break;
-      }
+  case Stmt::UnaryExprOrTypeTraitExprClass:
+    Bldr.takeNodes(Pred);
+    VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S), Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
 
-      if (const auto *LastExpr =
-              dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
-        ProgramStateRef state = Pred->getState();
-        Bldr.generateNode(SE, Pred,
-                          state->BindExpr(SE, Pred->getLocationContext(),
-                                          state->getSVal(LastExpr,
-                                                  Pred->getLocationContext())));
-      }
-      break;
-    }
+  case Stmt::StmtExprClass: {
+    const auto *SE = cast<StmtExpr>(S);
 
-    case Stmt::UnaryOperatorClass: {
-      Bldr.takeNodes(Pred);
-      const auto *U = cast<UnaryOperator>(S);
-      if (AMgr.options.ShouldEagerlyAssume && (U->getOpcode() == UO_LNot)) {
-        ExplodedNodeSet Tmp;
-        VisitUnaryOperator(U, Pred, Tmp);
-        evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U);
-      }
-      else
-        VisitUnaryOperator(U, Pred, Dst);
-      Bldr.addNodes(Dst);
+    if (SE->getSubStmt()->body_empty()) {
+      // Empty statement expression.
+      assert(SE->getType() == getContext().VoidTy &&
+             "Empty statement expression must have void type.");
       break;
     }
 
-    case Stmt::PseudoObjectExprClass: {
-      Bldr.takeNodes(Pred);
+    if (const auto *LastExpr =
+            dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
       ProgramStateRef state = Pred->getState();
-      const auto *PE = cast<PseudoObjectExpr>(S);
-      if (const Expr *Result = PE->getResultExpr()) {
-        SVal V = state->getSVal(Result, Pred->getLocationContext());
-        Bldr.generateNode(S, Pred,
-                          state->BindExpr(S, Pred->getLocationContext(), V));
-      }
-      else
-        Bldr.generateNode(S, Pred,
-                          state->BindExpr(S, Pred->getLocationContext(),
-                                                   UnknownVal()));
-
-      Bldr.addNodes(Dst);
-      break;
+      Bldr.generateNode(
+          SE, Pred,
+          state->BindExpr(
+              SE, Pred->getLocationContext(),
+              state->getSVal(LastExpr, Pred->getLocationContext())));
     }
+    break;
+  }
 
-    case Expr::ObjCIndirectCopyRestoreExprClass: {
-      // ObjCIndirectCopyRestoreExpr implies passing a temporary for
-      // correctness of lifetime management.  Due to limited analysis
-      // of ARC, this is implemented as direct arg passing.
-      Bldr.takeNodes(Pred);
-      ProgramStateRef state = Pred->getState();
-      const auto *OIE = cast<ObjCIndirectCopyRestoreExpr>(S);
-      const Expr *E = OIE->getSubExpr();
-      SVal V = state->getSVal(E, Pred->getLocationContext());
+  case Stmt::UnaryOperatorClass: {
+    Bldr.takeNodes(Pred);
+    const auto *U = cast<UnaryOperator>(S);
+    if (AMgr.options.ShouldEagerlyAssume && (U->getOpcode() == UO_LNot)) {
+      ExplodedNodeSet Tmp;
+      VisitUnaryOperator(U, Pred, Tmp);
+      evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U);
+    } else
+      VisitUnaryOperator(U, Pred, Dst);
+    Bldr.addNodes(Dst);
+    break;
+  }
+
+  case Stmt::PseudoObjectExprClass: {
+    Bldr.takeNodes(Pred);
+    ProgramStateRef state = Pred->getState();
+    const auto *PE = cast<PseudoObjectExpr>(S);
+    if (const Expr *Result = PE->getResultExpr()) {
+      SVal V = state->getSVal(Result, Pred->getLocationContext());
       Bldr.generateNode(S, Pred,
-              state->BindExpr(S, Pred->getLocationContext(), V));
-      Bldr.addNodes(Dst);
-      break;
-    }
+                        state->BindExpr(S, Pred->getLocationContext(), V));
+    } else
+      Bldr.generateNode(
+          S, Pred,
+          state->BindExpr(S, Pred->getLocationContext(), UnknownVal()));
+
+    Bldr.addNodes(Dst);
+    break;
+  }
+
+  case Expr::ObjCIndirectCopyRestoreExprClass: {
+    // ObjCIndirectCopyRestoreExpr implies passing a temporary for
+    // correctness of lifetime management.  Due to limited analysis
+    // of ARC, this is implemented as direct arg passing.
+    Bldr.takeNodes(Pred);
+    ProgramStateRef state = Pred->getState();
+    const auto *OIE = cast<ObjCIndirectCopyRestoreExpr>(S);
+    const Expr *E = OIE->getSubExpr();
+    SVal V = state->getSVal(E, Pred->getLocationContext());
+    Bldr.generateNode(S, Pred,
+                      state->BindExpr(S, Pred->getLocationContext(), V));
+    Bldr.addNodes(Dst);
+    break;
+  }
   }
 }
 
@@ -2470,7 +2453,7 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N,
   // Note, changing the state ensures that we are not going to cache out.
   ProgramStateRef NewNodeState = BeforeProcessingCall->getState();
   NewNodeState =
-    NewNodeState->set<ReplayWithoutInlining>(const_cast<Stmt *>(CE));
+      NewNodeState->set<ReplayWithoutInlining>(const_cast<Stmt *>(CE));
 
   // Make the new node a successor of BeforeProcessingCall.
   bool IsNew = false;
@@ -2484,7 +2467,7 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N,
 
   // Add the new node to the work list.
   Engine.enqueueStmtNode(NewNode, CalleeSF->getCallSiteBlock(),
-                                  CalleeSF->getIndex());
+                         CalleeSF->getIndex());
   NumTimesRetriedWithoutInlining++;
   return true;
 }
@@ -2496,7 +2479,7 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
   PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
   // If we reach a loop which has a known bound (and meets
   // other constraints) then consider completely unrolling it.
-  if(AMgr.options.ShouldUnrollLoops) {
+  if (AMgr.options.ShouldUnrollLoops) {
     unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath;
     const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminatorStmt();
     if (Term) {
@@ -2510,7 +2493,7 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
       }
     }
     // Is we are inside an unrolled loop then no need the check the counters.
-    if(isUnrolledState(Pred->getState()))
+    if (isUnrolledState(Pred->getState()))
       return;
   }
 
@@ -2534,14 +2517,14 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
   if (BlockCount >= AMgr.options.maxBlockVisitOnPath) {
     static SimpleProgramPointTag tag(TagProviderName, "Block count exceeded");
     const ExplodedNode *Sink =
-                   nodeBuilder.generateSink(Pred->getState(), Pred, &tag);
+        nodeBuilder.generateSink(Pred->getState(), Pred, &tag);
 
     // Check if we stopped at the top level function or not.
     // Root node should have the location context of the top most function.
     const LocationContext *CalleeLC = Pred->getLocation().getLocationContext();
     const LocationContext *CalleeSF = CalleeLC->getStackFrame();
     const LocationContext *RootLC =
-                        (*G.roots_begin())->getLocation().getLocationContext();
+        (*G.roots_begin())->getLocation().getLocationContext();
     if (RootLC->getStackFrame() != CalleeSF) {
       Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl());
 
@@ -2570,10 +2553,8 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
 /// integers that promote their values (which are currently not tracked well).
 /// This function returns the SVal bound to Condition->IgnoreCasts if all the
 //  cast(s) did was sign-extend the original value.
-static SVal RecoverCastedSymbol(ProgramStateRef state,
-                                const Stmt *Condition,
-                                const LocationContext *LCtx,
-                                ASTContext &Ctx) {
+static SVal RecoverCastedSymbol(ProgramStateRef state, const Stmt *Condition,
+                                const LocationContext *LCtx, ASTContext &Ctx) {
 
   const auto *Ex = dyn_cast<Expr>(Condition);
   if (!Ex)
@@ -2634,8 +2615,7 @@ static const Stmt *getRightmostLeaf(const Stmt *Condition) {
 // not evaluated, and is thus not in the SVal cache, we need to use that leaf
 // expression to evaluate the truth value of the condition in the current state
 // space.
-static const Stmt *ResolveCondition(const Stmt *Condition,
-                                    const CFGBlock *B) {
+static const Stmt *ResolveCondition(const Stmt *Condition, const CFGBlock *B) {
   if (const auto *Ex = dyn_cast<Expr>(Condition))
     Condition = Ex->IgnoreParens();
 
@@ -2677,10 +2657,9 @@ ProgramStateRef ExprEngine::setWhetherHasMoreIteration(
   return State->set<ObjCForHasMoreIterations>({O, LC}, HasMoreIteraton);
 }
 
-ProgramStateRef
-ExprEngine::removeIterationState(ProgramStateRef State,
-                                 const ObjCForCollectionStmt *O,
-                                 const LocationContext *LC) {
+ProgramStateRef ExprEngine::removeIterationState(ProgramStateRef State,
+                                                 const ObjCForCollectionStmt *O,
+                                                 const LocationContext *LC) {
   assert(State->contains<ObjCForHasMoreIterations>({O, LC}));
   return State->remove<ObjCForHasMoreIterations>({O, LC});
 }
@@ -2743,10 +2722,8 @@ assumeCondition(const Stmt *Condition, ExplodedNode *N) {
 }
 
 void ExprEngine::processBranch(const Stmt *Condition,
-                               NodeBuilderContext& BldCtx,
-                               ExplodedNode *Pred,
-                               ExplodedNodeSet &Dst,
-                               const CFGBlock *DstT,
+                               NodeBuilderContext &BldCtx, ExplodedNode *Pred,
+                               ExplodedNodeSet &Dst, const CFGBlock *DstT,
                                const CFGBlock *DstF) {
   assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) &&
          "CXXBindTemporaryExprs are handled by processBindTemporary.");
@@ -2820,12 +2797,9 @@ void ExprEngine::processBranch(const Stmt *Condition,
 REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedGlobalsSet,
                                  llvm::ImmutableSet<const VarDecl *>)
 
-void ExprEngine::processStaticInitializer(const DeclStmt *DS,
-                                          NodeBuilderContext &BuilderCtx,
-                                          ExplodedNode *Pred,
-                                          ExplodedNodeSet &Dst,
-                                          const CFGBlock *DstT,
-                                          const CFGBlock *DstF) {
+void ExprEngine::processStaticInitializer(
+    const DeclStmt *DS, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred,
+    ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) {
   PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
   currBldrCtx = &BuilderCtx;
 
@@ -2874,7 +2848,7 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
 
   if (isa<UndefinedVal, loc::ConcreteInt>(V)) {
     // Dispatch to the first target and mark it as a sink.
-    //ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
+    // ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
     // FIXME: add checker visit.
     //    UndefBranches.insert(N);
     return;
@@ -2897,7 +2871,7 @@ void ExprEngine::processBeginOfFunction(NodeBuilderContext &BC,
 
 /// ProcessEndPath - Called by CoreEngine.  Used to generate end-of-path
 ///  nodes when the control reaches the end of a function.
-void ExprEngine::processEndOfFunction(NodeBuilderContext& BC,
+void ExprEngine::processEndOfFunction(NodeBuilderContext &BC,
                                       ExplodedNode *Pred,
                                       const ReturnStmt *RS) {
   ProgramStateRef State = Pred->getState();
@@ -2971,17 +2945,17 @@ void ExprEngine::processEndOfFunction(NodeBuilderContext& BC,
 
 /// ProcessSwitch - Called by CoreEngine.  Used to generate successor
 ///  nodes by processing the 'effects' of a switch statement.
-void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
+void ExprEngine::processSwitch(SwitchNodeBuilder &builder) {
   using iterator = SwitchNodeBuilder::iterator;
 
   ProgramStateRef state = builder.getState();
   const Expr *CondE = builder.getCondition();
-  SVal  CondV_untested = state->getSVal(CondE, builder.getLocationContext());
+  SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext());
 
   if (CondV_untested.isUndef()) {
-    //ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
-    // FIXME: add checker
-    //UndefBranches.insert(N);
+    // ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
+    //  FIXME: add checker
+    // UndefBranches.insert(N);
 
     return;
   }
@@ -2992,7 +2966,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
   iterator I = builder.begin(), EI = builder.end();
   bool defaultIsFeasible = I == EI;
 
-  for ( ; I != EI; ++I) {
+  for (; I != EI; ++I) {
     // Successor may be pruned out during CFG construction.
     if (!I.getBlock())
       continue;
@@ -3084,8 +3058,7 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
       // Sema follows a sequence of complex rules to determine whether the
       // variable should be captured.
       if (const FieldDecl *FD = LambdaCaptureFields[VD]) {
-        Loc CXXThis =
-            svalBuilder.getCXXThis(MD, LocCtxt->getStackFrame());
+        Loc CXXThis = svalBuilder.getCXXThis(MD, LocCtxt->getStackFrame());
         SVal CXXThisVal = state->getSVal(CXXThis);
         VInfo = std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType());
       }
@@ -3293,10 +3266,10 @@ void ExprEngine::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *Ex,
 
 /// VisitArraySubscriptExpr - Transfer function for array accesses
 void ExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr *A,
-                                             ExplodedNode *Pred,
-                                             ExplodedNodeSet &Dst){
+                                         ExplodedNode *Pred,
+                                         ExplodedNodeSet &Dst) {
   const Expr *Base = A->getBase()->IgnoreParens();
-  const Expr *Idx  = A->getIdx()->IgnoreParens();
+  const Expr *Idx = A->getIdx()->IgnoreParens();
 
   ExplodedNodeSet CheckerPreStmt;
   getCheckerManager().runCheckersForPreStmt(CheckerPreStmt, Pred, A, *this);
@@ -3309,8 +3282,9 @@ void ExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr *A,
   // The "like" case is for situations where C standard prohibits the type to
   // be an lvalue, e.g. taking the address of a subscript of an expression of
   // type "void *".
-  bool IsGLValueLike = A->isGLValue() ||
-    (A->getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus);
+  bool IsGLValueLike =
+      A->isGLValue() ||
+      (A->getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus);
 
   for (auto *Node : CheckerPreStmt) {
     const LocationContext *LCtx = Node->getLocationContext();
@@ -3325,11 +3299,10 @@ void ExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr *A,
       if (T->isVoidType())
         T = getContext().CharTy;
 
-      SVal V = state->getLValue(T,
-                                state->getSVal(Idx, LCtx),
+      SVal V = state->getLValue(T, state->getSVal(Idx, LCtx),
                                 state->getSVal(Base, LCtx));
       Bldr.generateNode(A, Node, state->BindExpr(A, LCtx, V), nullptr,
-          ProgramPoint::PostLValueKind);
+                        ProgramPoint::PostLValueKind);
     } else if (IsVectorType) {
       // FIXME: non-glvalue vector reads are not modelled.
       Bldr.generateNode(A, Node, state, nullptr);
@@ -3404,8 +3377,8 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
         // pointers as soon as they are used.
         if (!M->isGLValue()) {
           assert(M->getType()->isArrayType());
-          const auto *PE =
-            dyn_cast<ImplicitCastExpr>(I->getParentMap().getParentIgnoreParens(M));
+          const auto *PE = dyn_cast<ImplicitCastExpr>(
+              I->getParentMap().getParentIgnoreParens(M));
           if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
             llvm_unreachable("should always be wrapped in ArrayToPointerDecay");
           }
@@ -3454,18 +3427,17 @@ void ExprEngine::VisitAtomicExpr(const AtomicExpr *AE, ExplodedNode *Pred,
     }
 
     State = State->invalidateRegions(ValuesToInvalidate, AE,
-                                    currBldrCtx->blockCount(),
-                                    LCtx,
-                                    /*CausedByPointerEscape*/true,
-                                    /*Symbols=*/nullptr);
+                                     currBldrCtx->blockCount(), LCtx,
+                                     /*CausedByPointerEscape*/ true,
+                                     /*Symbols=*/nullptr);
 
     SVal ResultVal = UnknownVal();
     State = State->BindExpr(AE, LCtx, ResultVal);
-    Bldr.generateNode(AE, I, State, nullptr,
-                      ProgramPoint::PostStmtKind);
+    Bldr.generateNode(AE, I, State, nullptr, ProgramPoint::PostStmtKind);
   }
 
-  getCheckerManager().runCheckersForPostStmt(Dst, AfterInvalidateSet, AE, *this);
+  getCheckerManager().runCheckersForPostStmt(Dst, AfterInvalidateSet, AE,
+                                             *this);
 }
 
 // A value escapes in four possible cases:
@@ -3524,21 +3496,16 @@ ExprEngine::processPointerEscapedOnBind(ProgramStateRef State, SVal Loc,
                                      nullptr);
 }
 
-ProgramStateRef
-ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State,
-    const InvalidatedSymbols *Invalidated,
-    ArrayRef<const MemRegion *> ExplicitRegions,
-    const CallEvent *Call,
+ProgramStateRef ExprEngine::notifyCheckersOfPointerEscape(
+    ProgramStateRef State, const InvalidatedSymbols *Invalidated,
+    ArrayRef<const MemRegion *> ExplicitRegions, const CallEvent *Call,
     RegionAndSymbolInvalidationTraits &ITraits) {
   if (!Invalidated || Invalidated->empty())
     return State;
 
   if (!Call)
-    return getCheckerManager().runCheckersForPointerEscape(State,
-                                                           *Invalidated,
-                                                           nullptr,
-                                                           PSK_EscapeOther,
-                                                           &ITraits);
+    return getCheckerManager().runCheckersForPointerEscape(
+        State, *Invalidated, nullptr, PSK_EscapeOther, &ITraits);
 
   // If the symbols were invalidated by a call, we want to find out which ones
   // were invalidated directly due to being arguments to the call.
@@ -3556,13 +3523,15 @@ ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State,
   }
 
   if (!SymbolsDirectlyInvalidated.empty())
-    State = getCheckerManager().runCheckersForPointerEscape(State,
-        SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall, &ITraits);
+    State = getCheckerManager().runCheckersForPointerEscape(
+        State, SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall,
+        &ITraits);
 
   // Notify about the symbols that get indirectly invalidated by the call.
   if (!SymbolsIndirectlyInvalidated.empty())
-    State = getCheckerManager().runCheckersForPointerEscape(State,
-        SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall, &ITraits);
+    State = getCheckerManager().runCheckersForPointerEscape(
+        State, SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall,
+        &ITraits);
 
   return State;
 }
@@ -3570,8 +3539,7 @@ ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State,
 /// evalBind - Handle the semantics of binding a value to a specific location.
 ///  This method is used by evalStore and (soon) VisitDeclStmt, and others.
 void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
-                          ExplodedNode *Pred,
-                          SVal location, SVal Val,
+                          ExplodedNode *Pred, SVal location, SVal Val,
                           bool atDeclInit, const ProgramPoint *PP) {
   const LocationContext *LC = Pred->getLocationContext();
   PostStmt PS(StoreE, LC);
@@ -3588,8 +3556,8 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
   // If the location is not a 'Loc', it will already be handled by
   // the checkers.  There is nothing left to do.
   if (!isa<Loc>(location)) {
-    const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/nullptr,
-                                     /*tag*/nullptr);
+    const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/ nullptr,
+                                     /*tag*/ nullptr);
     ProgramStateRef state = Pred->getState();
     state = processPointerEscapedOnBind(state, location, Val, LC);
     Bldr.generateNode(L, state, Pred);
@@ -3604,8 +3572,8 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
     // When binding the value, pass on the hint that this is a initialization.
     // For initializations, we do not need to inform clients of region
     // changes.
-    state = state->bindLoc(location.castAs<Loc>(),
-                           Val, LC, /* notifyChanges = */ !atDeclInit);
+    state = state->bindLoc(location.castAs<Loc>(), Val, LC,
+                           /* notifyChanges = */ !atDeclInit);
 
     const MemRegion *LocReg = nullptr;
     if (std::optional<loc::MemRegionVal> LocRegVal =
@@ -3627,10 +3595,9 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
 ///  @param location The location to store the value
 ///  @param Val The value to be stored
 void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
-                             const Expr *LocationE,
-                             ExplodedNode *Pred,
-                             ProgramStateRef state, SVal location, SVal Val,
-                             const ProgramPointTag *tag) {
+                           const Expr *LocationE, ExplodedNode *Pred,
+                           ProgramStateRef state, SVal location, SVal Val,
+                           const ProgramPointTag *tag) {
   // Proceed with the store.  We use AssignE as the anchor for the PostStore
   // ProgramPoint if it is non-NULL, and LocationE otherwise.
   const Expr *StoreE = AssignE ? AssignE : LocationE;
@@ -3649,14 +3616,10 @@ void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
     evalBind(Dst, StoreE, I, location, Val, false);
 }
 
-void ExprEngine::evalLoad(ExplodedNodeSet &Dst,
-                          const Expr *NodeEx,
-                          const Expr *BoundEx,
-                          ExplodedNode *Pred,
-                          ProgramStateRef state,
-                          SVal location,
-                          const ProgramPointTag *tag,
-                          QualType LoadTy) {
+void ExprEngine::evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx,
+                          const Expr *BoundEx, ExplodedNode *Pred,
+                          ProgramStateRef state, SVal location,
+                          const ProgramPointTag *tag, QualType LoadTy) {
   assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
   assert(NodeEx);
   assert(BoundEx);
@@ -3687,12 +3650,9 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst,
   }
 }
 
-void ExprEngine::evalLocation(ExplodedNodeSet &Dst,
-                              const Stmt *NodeEx,
-                              const Stmt *BoundEx,
-                              ExplodedNode *Pred,
-                              ProgramStateRef state,
-                              SVal location,
+void ExprEngine::evalLocation(ExplodedNodeSet &Dst, const Stmt *NodeEx,
+                              const Stmt *BoundEx, ExplodedNode *Pred,
+                              ProgramStateRef state, SVal location,
                               bool isLoad) {
   StmtNodeBuilder BldrTop(Pred, Dst, *currBldrCtx);
   // Early checks for performance reason.
@@ -3717,18 +3677,17 @@ void ExprEngine::evalLocation(ExplodedNodeSet &Dst,
     Bldr.generateNode(NodeEx, Pred, state, &tag);
   }
   ExplodedNodeSet Tmp;
-  getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad,
-                                             NodeEx, BoundEx, *this);
+  getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad, NodeEx,
+                                             BoundEx, *this);
   BldrTop.addNodes(Tmp);
 }
 
-std::pair<const ProgramPointTag *, const ProgramPointTag*>
+std::pair<const ProgramPointTag *, const ProgramPointTag *>
 ExprEngine::geteagerlyAssumeBinOpBifurcationTags() {
-  static SimpleProgramPointTag
-         eagerlyAssumeBinOpBifurcationTrue(TagProviderName,
-                                           "Eagerly Assume True"),
-         eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
-                                            "Eagerly Assume False");
+  static SimpleProgramPointTag eagerlyAssumeBinOpBifurcationTrue(
+      TagProviderName, "Eagerly Assume True"),
+      eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
+                                         "Eagerly Assume False");
   return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
                         &eagerlyAssumeBinOpBifurcationFalse);
 }
@@ -3751,8 +3710,8 @@ void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
     SVal V = state->getSVal(Ex, Pred->getLocationContext());
     std::optional<nonloc::SymbolVal> SEV = V.getAs<nonloc::SymbolVal>();
     if (SEV && SEV->isExpression()) {
-      const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
-        geteagerlyAssumeBinOpBifurcationTags();
+      const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
+          geteagerlyAssumeBinOpBifurcationTags();
 
       ProgramStateRef StateTrue, StateFalse;
       std::tie(StateTrue, StateFalse) = state->assume(*SEV);
@@ -3809,13 +3768,14 @@ void ExprEngine::VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
 
 namespace llvm {
 
-template<>
-struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
-  DOTGraphTraits (bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
+template <>
+struct DOTGraphTraits<ExplodedGraph *> : public DefaultDOTGraphTraits {
+  DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
 
   static bool nodeHasBugReport(const ExplodedNode *N) {
     BugReporter &BR = static_cast<ExprEngine &>(
-      N->getState()->getStateManager().getOwningEngine()).getBugReporter();
+                          N->getState()->getStateManager().getOwningEngine())
+                          .getBugReporter();
 
     for (const auto &Class : BR.equivalenceClasses()) {
       for (const auto &Report : Class.getReports()) {
@@ -3858,7 +3818,7 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
     return N->isTrivial();
   }
 
-  static std::string getNodeLabel(const ExplodedNode *N, ExplodedGraph *G){
+  static std::string getNodeLabel(const ExplodedNode *N, ExplodedGraph *G) {
     std::string Buf;
     llvm::raw_string_ostream Out(Buf);
 
@@ -3866,8 +3826,7 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
     const unsigned int Space = 1;
     ProgramStateRef State = N->getState();
 
-    Out << "{ \"state_id\": " << State->getID()
-        << ",\\l";
+    Out << "{ \"state_id\": " << State->getID() << ",\\l";
 
     Indent(Out, Space, IsDot) << "\"program_points\": [\\l";
 
@@ -3882,9 +3841,9 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
             Out << '\"' << Tag->getTagDescription() << '\"';
           else
             Out << "null";
-          Out << ", \"node_id\": " << OtherNode->getID() <<
-                 ", \"is_sink\": " << OtherNode->isSink() <<
-                 ", \"has_report\": " << nodeHasBugReport(OtherNode) << " }";
+          Out << ", \"node_id\": " << OtherNode->getID()
+              << ", \"is_sink\": " << OtherNode->isSink()
+              << ", \"has_report\": " << nodeHasBugReport(OtherNode) << " }";
         },
         // Adds a comma and a new-line between each program point.
         [&](const ExplodedNode *) { Out << ",\\l"; },
@@ -3953,4 +3912,4 @@ void *ProgramStateTrait<ReplayWithoutInlining>::GDMIndex() {
   return &index;
 }
 
-void ExprEngine::anchor() { }
+void ExprEngine::anchor() {}
diff --git a/clang/unittests/StaticAnalyzer/CMakeLists.txt b/clang/unittests/StaticAnalyzer/CMakeLists.txt
index ff34d5747cc81..e6cddc18905b9 100644
--- a/clang/unittests/StaticAnalyzer/CMakeLists.txt
+++ b/clang/unittests/StaticAnalyzer/CMakeLists.txt
@@ -10,6 +10,7 @@ add_clang_unittest(StaticAnalysisTests
   CallDescriptionTest.cpp
   CallEventTest.cpp
   ConflictingEvalCallsTest.cpp
+  ExprEngineVisitTest.cpp
   FalsePositiveRefutationBRVisitorTest.cpp
   IsCLibraryFunctionTest.cpp
   MemRegionDescriptiveNameTest.cpp
diff --git a/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp b/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
new file mode 100644
index 0000000000000..b5d25e98dba55
--- /dev/null
+++ b/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
@@ -0,0 +1,92 @@
+//===- ExprEngineVisitTest.cpp -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CheckerRegistration.h"
+#include "clang/AST/Stmt.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+
+void emitErrorReport(CheckerContext &C, const BugType &Bug,
+                     const std::string &Desc) {
+  if (ExplodedNode *Node = C.generateNonFatalErrorNode(C.getState())) {
+    auto Report = std::make_unique<PathSensitiveBugReport>(Bug, Desc, Node);
+    C.emitReport(std::move(Report));
+  }
+}
+
+class ExprEngineVisitPreChecker : public Checker<check::PreStmt<GCCAsmStmt>> {
+public:
+  void checkPreStmt(const GCCAsmStmt *ASM, CheckerContext &C) const {
+    emitErrorReport(C, Bug, "PreStmt<GCCAsmStmt>");
+  }
+
+private:
+  const BugType Bug{this, "GCCAsmStmtBug"};
+};
+
+class ExprEngineVisitPostChecker : public Checker<check::PostStmt<GCCAsmStmt>> {
+public:
+  void checkPostStmt(const GCCAsmStmt *ASM, CheckerContext &C) const {
+    emitErrorReport(C, Bug, "PostStmt<GCCAsmStmt>");
+  }
+
+private:
+  const BugType Bug{this, "GCCAsmStmtBug"};
+};
+
+void addExprEngineVisitPreChecker(AnalysisASTConsumer &AnalysisConsumer,
+                                  AnalyzerOptions &AnOpts) {
+  AnOpts.CheckersAndPackages = {{"ExprEngineVisitPreChecker", true}};
+  AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
+    Registry.addChecker<ExprEngineVisitPreChecker>("ExprEngineVisitPreChecker",
+                                                   "Desc", "DocsURI");
+  });
+}
+
+void addExprEngineVisitPostChecker(AnalysisASTConsumer &AnalysisConsumer,
+                                   AnalyzerOptions &AnOpts) {
+  AnOpts.CheckersAndPackages = {{"ExprEngineVisitPostChecker", true}};
+  AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
+    Registry.addChecker<ExprEngineVisitPostChecker>(
+        "ExprEngineVisitPostChecker", "Desc", "DocsURI");
+  });
+}
+
+TEST(ExprEngineVisitTest, checkPreStmtGCCAsmStmt) {
+  std::string Diags;
+  EXPECT_TRUE(runCheckerOnCode<addExprEngineVisitPreChecker>(R"(
+    int a = 1;
+    void top() {
+      asm("");
+    }
+  )",
+                                                             Diags));
+  EXPECT_EQ(Diags, "ExprEngineVisitPreChecker: PreStmt<GCCAsmStmt>\n");
+}
+
+TEST(ExprEngineVisitTest, checkPostStmtGCCAsmStmt) {
+  std::string Diags;
+  EXPECT_TRUE(runCheckerOnCode<addExprEngineVisitPostChecker>(R"(
+    int a = 1;
+    void top() {
+      asm("");
+    }
+  )",
+                                                              Diags));
+  EXPECT_EQ(Diags, "ExprEngineVisitPostChecker: PostStmt<GCCAsmStmt>\n");
+}
+
+} // namespace

>From 380c80ab7bd1ee76e6620188eaafabddd39c01e7 Mon Sep 17 00:00:00 2001
From: T-Gruber <tobi.gruber at gmx.de>
Date: Thu, 13 Jun 2024 21:01:38 +0200
Subject: [PATCH 2/6] Restored format of previous commit

---
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 1598 +++++++++---------
 1 file changed, 822 insertions(+), 776 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index d99fa7a132f50..4bfa0a599da67 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -89,15 +89,16 @@ using namespace ento;
 
 #define DEBUG_TYPE "ExprEngine"
 
-STATISTIC(NumRemoveDeadBindings, "The # of times RemoveDeadBindings is called");
+STATISTIC(NumRemoveDeadBindings,
+            "The # of times RemoveDeadBindings is called");
 STATISTIC(NumMaxBlockCountReached,
-          "The # of aborted paths due to reaching the maximum block count in "
-          "a top level function");
+            "The # of aborted paths due to reaching the maximum block count in "
+            "a top level function");
 STATISTIC(NumMaxBlockCountReachedInInlined,
-          "The # of aborted paths due to reaching the maximum block count in "
-          "an inlined function");
+            "The # of aborted paths due to reaching the maximum block count in "
+            "an inlined function");
 STATISTIC(NumTimesRetriedWithoutInlining,
-          "The # of times we re-evaluated a call without inlining");
+            "The # of times we re-evaluated a call without inlining");
 
 //===----------------------------------------------------------------------===//
 // Internal program state traits.
@@ -125,7 +126,7 @@ class ConstructedObjectKey {
 
 public:
   explicit ConstructedObjectKey(const ConstructionContextItem &Item,
-                                const LocationContext *LC)
+                       const LocationContext *LC)
       : Impl(Item, LC) {}
 
   const ConstructionContextItem &getItem() const { return Impl.first; }
@@ -215,7 +216,7 @@ REGISTER_TRAIT_WITH_PROGRAMSTATE(PendingArrayDestruction,
 // Engine construction and deletion.
 //===----------------------------------------------------------------------===//
 
-static const char *TagProviderName = "ExprEngine";
+static const char* TagProviderName = "ExprEngine";
 
 ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU,
                        AnalysisManager &mgr, SetOfConstDecls *VisitedCalleesIn,
@@ -266,9 +267,9 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
         break;
 
       SVal V = state->getSVal(loc::MemRegionVal(R));
-      SVal Constraint_untested =
-          evalBinOp(state, BO_GT, V, svalBuilder.makeZeroVal(T),
-                    svalBuilder.getConditionType());
+      SVal Constraint_untested = evalBinOp(state, BO_GT, V,
+                                           svalBuilder.makeZeroVal(T),
+                                           svalBuilder.getConditionType());
 
       std::optional<DefinedOrUnknownSVal> Constraint =
           Constraint_untested.getAs<DefinedOrUnknownSVal>();
@@ -280,7 +281,8 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
         state = newState;
     }
     break;
-  } while (false);
+  }
+  while (false);
 
   if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
     // Precondition: 'self' is always non-null upon entry to an Objective-C
@@ -655,23 +657,28 @@ bool ExprEngine::areAllObjectsFullyConstructed(ProgramStateRef State,
   return true;
 }
 
+
 //===----------------------------------------------------------------------===//
 // Top-level transfer function logic (Dispatcher).
 //===----------------------------------------------------------------------===//
 
 /// evalAssume - Called by ConstraintManager. Used to call checker-specific
 ///  logic for handling assumptions on symbolic values.
-ProgramStateRef ExprEngine::processAssume(ProgramStateRef state, SVal cond,
-                                          bool assumption) {
+ProgramStateRef ExprEngine::processAssume(ProgramStateRef state,
+                                              SVal cond, bool assumption) {
   return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption);
 }
 
-ProgramStateRef ExprEngine::processRegionChanges(
-    ProgramStateRef state, const InvalidatedSymbols *invalidated,
-    ArrayRef<const MemRegion *> Explicits, ArrayRef<const MemRegion *> Regions,
-    const LocationContext *LCtx, const CallEvent *Call) {
-  return getCheckerManager().runCheckersForRegionChanges(
-      state, invalidated, Explicits, Regions, LCtx, Call);
+ProgramStateRef
+ExprEngine::processRegionChanges(ProgramStateRef state,
+                                 const InvalidatedSymbols *invalidated,
+                                 ArrayRef<const MemRegion *> Explicits,
+                                 ArrayRef<const MemRegion *> Regions,
+                                 const LocationContext *LCtx,
+                                 const CallEvent *Call) {
+  return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
+                                                         Explicits, Regions,
+                                                         LCtx, Call);
 }
 
 static void
@@ -963,36 +970,38 @@ void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred,
   currBldrCtx = Ctx;
 
   switch (E.getKind()) {
-  case CFGElement::Statement:
-  case CFGElement::Constructor:
-  case CFGElement::CXXRecordTypedCall:
-    ProcessStmt(E.castAs<CFGStmt>().getStmt(), Pred);
-    return;
-  case CFGElement::Initializer:
-    ProcessInitializer(E.castAs<CFGInitializer>(), Pred);
-    return;
-  case CFGElement::NewAllocator:
-    ProcessNewAllocator(E.castAs<CFGNewAllocator>().getAllocatorExpr(), Pred);
-    return;
-  case CFGElement::AutomaticObjectDtor:
-  case CFGElement::DeleteDtor:
-  case CFGElement::BaseDtor:
-  case CFGElement::MemberDtor:
-  case CFGElement::TemporaryDtor:
-    ProcessImplicitDtor(E.castAs<CFGImplicitDtor>(), Pred);
-    return;
-  case CFGElement::LoopExit:
-    ProcessLoopExit(E.castAs<CFGLoopExit>().getLoopStmt(), Pred);
-    return;
-  case CFGElement::LifetimeEnds:
-  case CFGElement::CleanupFunction:
-  case CFGElement::ScopeBegin:
-  case CFGElement::ScopeEnd:
-    return;
+    case CFGElement::Statement:
+    case CFGElement::Constructor:
+    case CFGElement::CXXRecordTypedCall:
+      ProcessStmt(E.castAs<CFGStmt>().getStmt(), Pred);
+      return;
+    case CFGElement::Initializer:
+      ProcessInitializer(E.castAs<CFGInitializer>(), Pred);
+      return;
+    case CFGElement::NewAllocator:
+      ProcessNewAllocator(E.castAs<CFGNewAllocator>().getAllocatorExpr(),
+                          Pred);
+      return;
+    case CFGElement::AutomaticObjectDtor:
+    case CFGElement::DeleteDtor:
+    case CFGElement::BaseDtor:
+    case CFGElement::MemberDtor:
+    case CFGElement::TemporaryDtor:
+      ProcessImplicitDtor(E.castAs<CFGImplicitDtor>(), Pred);
+      return;
+    case CFGElement::LoopExit:
+      ProcessLoopExit(E.castAs<CFGLoopExit>().getLoopStmt(), Pred);
+      return;
+    case CFGElement::LifetimeEnds:
+    case CFGElement::CleanupFunction:
+    case CFGElement::ScopeBegin:
+    case CFGElement::ScopeEnd:
+      return;
   }
 }
 
-static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const Stmt *S,
+static bool shouldRemoveDeadBindings(AnalysisManager &AMgr,
+                                     const Stmt *S,
                                      const ExplodedNode *Pred,
                                      const LocationContext *LC) {
   // Are we never purging state values?
@@ -1020,10 +1029,11 @@ static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const Stmt *S,
 void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out,
                             const Stmt *ReferenceStmt,
                             const LocationContext *LC,
-                            const Stmt *DiagnosticStmt, ProgramPoint::Kind K) {
+                            const Stmt *DiagnosticStmt,
+                            ProgramPoint::Kind K) {
   assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind ||
-          ReferenceStmt == nullptr || isa<ReturnStmt>(ReferenceStmt)) &&
-         "PostStmt is not generally supported by the SymbolReaper yet");
+          ReferenceStmt == nullptr || isa<ReturnStmt>(ReferenceStmt))
+          && "PostStmt is not generally supported by the SymbolReaper yet");
   assert(LC && "Must pass the current (or expiring) LocationContext");
 
   if (!DiagnosticStmt) {
@@ -1108,7 +1118,8 @@ void ExprEngine::ProcessStmt(const Stmt *currStmt, ExplodedNode *Pred) {
   ExplodedNodeSet CleanedStates;
   if (shouldRemoveDeadBindings(AMgr, currStmt, Pred,
                                Pred->getLocationContext())) {
-    removeDead(Pred, CleanedStates, currStmt, Pred->getLocationContext());
+    removeDead(Pred, CleanedStates, currStmt,
+                                    Pred->getLocationContext());
   } else
     CleanedStates.Add(Pred);
 
@@ -1125,7 +1136,7 @@ void ExprEngine::ProcessStmt(const Stmt *currStmt, ExplodedNode *Pred) {
   Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
 }
 
-void ExprEngine::ProcessLoopExit(const Stmt *S, ExplodedNode *Pred) {
+void ExprEngine::ProcessLoopExit(const Stmt* S, ExplodedNode *Pred) {
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
                                 S->getBeginLoc(),
                                 "Error evaluating end of the loop");
@@ -1134,7 +1145,7 @@ void ExprEngine::ProcessLoopExit(const Stmt *S, ExplodedNode *Pred) {
   NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   ProgramStateRef NewState = Pred->getState();
 
-  if (AMgr.options.ShouldUnrollLoops)
+  if(AMgr.options.ShouldUnrollLoops)
     NewState = processLoopEnd(S, NewState);
 
   LoopExit PP(S, Pred->getLocationContext());
@@ -1200,9 +1211,9 @@ void ExprEngine::ProcessInitializer(const CFGInitializer CFGInit,
         // If we fail to get the value for some reason, use a symbolic value.
         if (InitVal.isUnknownOrUndef()) {
           SValBuilder &SVB = getSValBuilder();
-          InitVal =
-              SVB.conjureSymbolVal(BMI->getInit(), stackFrame, Field->getType(),
-                                   currBldrCtx->blockCount());
+          InitVal = SVB.conjureSymbolVal(BMI->getInit(), stackFrame,
+                                         Field->getType(),
+                                         currBldrCtx->blockCount());
         }
       } else {
         InitVal = State->getSVal(BMI->getInit(), stackFrame);
@@ -1303,7 +1314,8 @@ void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
   Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
 }
 
-void ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred) {
+void ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE,
+                                     ExplodedNode *Pred) {
   ExplodedNodeSet Dst;
   AnalysisManager &AMgr = getAnalysisManager();
   AnalyzerOptions &Opts = AMgr.options;
@@ -1394,7 +1406,8 @@ void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
                      /*IsBase=*/false, Pred, Dst, CallOpts);
 }
 
-void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, ExplodedNode *Pred,
+void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor,
+                                   ExplodedNode *Pred,
                                    ExplodedNodeSet &Dst) {
   ProgramStateRef State = Pred->getState();
   const LocationContext *LCtx = Pred->getLocationContext();
@@ -1469,27 +1482,28 @@ void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, ExplodedNode *Pred,
   VisitCXXDestructor(DTy, ArgR, DE, /*IsBase=*/false, Pred, Dst, CallOpts);
 }
 
-void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred,
-                                 ExplodedNodeSet &Dst) {
+void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
+                                 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
   const LocationContext *LCtx = Pred->getLocationContext();
 
   const auto *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
-  Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor, LCtx->getStackFrame());
+  Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor,
+                                            LCtx->getStackFrame());
   SVal ThisVal = Pred->getState()->getSVal(ThisPtr);
 
   // Create the base object region.
   const CXXBaseSpecifier *Base = D.getBaseSpecifier();
   QualType BaseTy = Base->getType();
-  SVal BaseVal =
-      getStoreManager().evalDerivedToBase(ThisVal, BaseTy, Base->isVirtual());
+  SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy,
+                                                     Base->isVirtual());
 
   EvalCallOptions CallOpts;
   VisitCXXDestructor(BaseTy, BaseVal.getAsRegion(), CurDtor->getBody(),
                      /*IsBase=*/true, Pred, Dst, CallOpts);
 }
 
-void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred,
-                                   ExplodedNodeSet &Dst) {
+void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
+                                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {
   const auto *DtorDecl = D.getDestructorDecl(getContext());
   const FieldDecl *Member = D.getFieldDecl();
   QualType T = Member->getType();
@@ -1669,7 +1683,8 @@ void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
 }
 
 ProgramStateRef ExprEngine::escapeValues(ProgramStateRef State,
-                                         ArrayRef<SVal> Vs, PointerEscapeKind K,
+                                         ArrayRef<SVal> Vs,
+                                         PointerEscapeKind K,
                                          const CallEvent *Call) const {
   class CollectReachableSymbolsCallback final : public SymbolVisitor {
     InvalidatedSymbols &Symbols;
@@ -1704,707 +1719,714 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
   assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
 
   switch (S->getStmtClass()) {
-  // C++, OpenMP and ARC stuff we don't support yet.
-  case Stmt::CXXDependentScopeMemberExprClass:
-  case Stmt::CXXTryStmtClass:
-  case Stmt::CXXTypeidExprClass:
-  case Stmt::CXXUuidofExprClass:
-  case Stmt::CXXFoldExprClass:
-  case Stmt::MSPropertyRefExprClass:
-  case Stmt::MSPropertySubscriptExprClass:
-  case Stmt::CXXUnresolvedConstructExprClass:
-  case Stmt::DependentScopeDeclRefExprClass:
-  case Stmt::ArrayTypeTraitExprClass:
-  case Stmt::ExpressionTraitExprClass:
-  case Stmt::UnresolvedLookupExprClass:
-  case Stmt::UnresolvedMemberExprClass:
-  case Stmt::TypoExprClass:
-  case Stmt::RecoveryExprClass:
-  case Stmt::CXXNoexceptExprClass:
-  case Stmt::PackExpansionExprClass:
-  case Stmt::PackIndexingExprClass:
-  case Stmt::SubstNonTypeTemplateParmPackExprClass:
-  case Stmt::FunctionParmPackExprClass:
-  case Stmt::CoroutineBodyStmtClass:
-  case Stmt::CoawaitExprClass:
-  case Stmt::DependentCoawaitExprClass:
-  case Stmt::CoreturnStmtClass:
-  case Stmt::CoyieldExprClass:
-  case Stmt::SEHTryStmtClass:
-  case Stmt::SEHExceptStmtClass:
-  case Stmt::SEHLeaveStmtClass:
-  case Stmt::SEHFinallyStmtClass:
-  case Stmt::OMPCanonicalLoopClass:
-  case Stmt::OMPParallelDirectiveClass:
-  case Stmt::OMPSimdDirectiveClass:
-  case Stmt::OMPForDirectiveClass:
-  case Stmt::OMPForSimdDirectiveClass:
-  case Stmt::OMPSectionsDirectiveClass:
-  case Stmt::OMPSectionDirectiveClass:
-  case Stmt::OMPScopeDirectiveClass:
-  case Stmt::OMPSingleDirectiveClass:
-  case Stmt::OMPMasterDirectiveClass:
-  case Stmt::OMPCriticalDirectiveClass:
-  case Stmt::OMPParallelForDirectiveClass:
-  case Stmt::OMPParallelForSimdDirectiveClass:
-  case Stmt::OMPParallelSectionsDirectiveClass:
-  case Stmt::OMPParallelMasterDirectiveClass:
-  case Stmt::OMPParallelMaskedDirectiveClass:
-  case Stmt::OMPTaskDirectiveClass:
-  case Stmt::OMPTaskyieldDirectiveClass:
-  case Stmt::OMPBarrierDirectiveClass:
-  case Stmt::OMPTaskwaitDirectiveClass:
-  case Stmt::OMPErrorDirectiveClass:
-  case Stmt::OMPTaskgroupDirectiveClass:
-  case Stmt::OMPFlushDirectiveClass:
-  case Stmt::OMPDepobjDirectiveClass:
-  case Stmt::OMPScanDirectiveClass:
-  case Stmt::OMPOrderedDirectiveClass:
-  case Stmt::OMPAtomicDirectiveClass:
-  case Stmt::OMPTargetDirectiveClass:
-  case Stmt::OMPTargetDataDirectiveClass:
-  case Stmt::OMPTargetEnterDataDirectiveClass:
-  case Stmt::OMPTargetExitDataDirectiveClass:
-  case Stmt::OMPTargetParallelDirectiveClass:
-  case Stmt::OMPTargetParallelForDirectiveClass:
-  case Stmt::OMPTargetUpdateDirectiveClass:
-  case Stmt::OMPTeamsDirectiveClass:
-  case Stmt::OMPCancellationPointDirectiveClass:
-  case Stmt::OMPCancelDirectiveClass:
-  case Stmt::OMPTaskLoopDirectiveClass:
-  case Stmt::OMPTaskLoopSimdDirectiveClass:
-  case Stmt::OMPMasterTaskLoopDirectiveClass:
-  case Stmt::OMPMaskedTaskLoopDirectiveClass:
-  case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
-  case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
-  case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
-  case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
-  case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
-  case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
-  case Stmt::OMPDistributeDirectiveClass:
-  case Stmt::OMPDistributeParallelForDirectiveClass:
-  case Stmt::OMPDistributeParallelForSimdDirectiveClass:
-  case Stmt::OMPDistributeSimdDirectiveClass:
-  case Stmt::OMPTargetParallelForSimdDirectiveClass:
-  case Stmt::OMPTargetSimdDirectiveClass:
-  case Stmt::OMPTeamsDistributeDirectiveClass:
-  case Stmt::OMPTeamsDistributeSimdDirectiveClass:
-  case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
-  case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
-  case Stmt::OMPTargetTeamsDirectiveClass:
-  case Stmt::OMPTargetTeamsDistributeDirectiveClass:
-  case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
-  case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
-  case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
-  case Stmt::OMPTileDirectiveClass:
-  case Stmt::OMPInteropDirectiveClass:
-  case Stmt::OMPDispatchDirectiveClass:
-  case Stmt::OMPMaskedDirectiveClass:
-  case Stmt::OMPGenericLoopDirectiveClass:
-  case Stmt::OMPTeamsGenericLoopDirectiveClass:
-  case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
-  case Stmt::OMPParallelGenericLoopDirectiveClass:
-  case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
-  case Stmt::CapturedStmtClass:
-  case Stmt::OpenACCComputeConstructClass:
-  case Stmt::OpenACCLoopConstructClass:
-  case Stmt::OMPUnrollDirectiveClass:
-  case Stmt::OMPMetaDirectiveClass: {
-    const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
-    Engine.addAbortedBlock(node, currBldrCtx->getBlock());
-    break;
-  }
+    // C++, OpenMP and ARC stuff we don't support yet.
+    case Stmt::CXXDependentScopeMemberExprClass:
+    case Stmt::CXXTryStmtClass:
+    case Stmt::CXXTypeidExprClass:
+    case Stmt::CXXUuidofExprClass:
+    case Stmt::CXXFoldExprClass:
+    case Stmt::MSPropertyRefExprClass:
+    case Stmt::MSPropertySubscriptExprClass:
+    case Stmt::CXXUnresolvedConstructExprClass:
+    case Stmt::DependentScopeDeclRefExprClass:
+    case Stmt::ArrayTypeTraitExprClass:
+    case Stmt::ExpressionTraitExprClass:
+    case Stmt::UnresolvedLookupExprClass:
+    case Stmt::UnresolvedMemberExprClass:
+    case Stmt::TypoExprClass:
+    case Stmt::RecoveryExprClass:
+    case Stmt::CXXNoexceptExprClass:
+    case Stmt::PackExpansionExprClass:
+    case Stmt::PackIndexingExprClass:
+    case Stmt::SubstNonTypeTemplateParmPackExprClass:
+    case Stmt::FunctionParmPackExprClass:
+    case Stmt::CoroutineBodyStmtClass:
+    case Stmt::CoawaitExprClass:
+    case Stmt::DependentCoawaitExprClass:
+    case Stmt::CoreturnStmtClass:
+    case Stmt::CoyieldExprClass:
+    case Stmt::SEHTryStmtClass:
+    case Stmt::SEHExceptStmtClass:
+    case Stmt::SEHLeaveStmtClass:
+    case Stmt::SEHFinallyStmtClass:
+    case Stmt::OMPCanonicalLoopClass:
+    case Stmt::OMPParallelDirectiveClass:
+    case Stmt::OMPSimdDirectiveClass:
+    case Stmt::OMPForDirectiveClass:
+    case Stmt::OMPForSimdDirectiveClass:
+    case Stmt::OMPSectionsDirectiveClass:
+    case Stmt::OMPSectionDirectiveClass:
+    case Stmt::OMPScopeDirectiveClass:
+    case Stmt::OMPSingleDirectiveClass:
+    case Stmt::OMPMasterDirectiveClass:
+    case Stmt::OMPCriticalDirectiveClass:
+    case Stmt::OMPParallelForDirectiveClass:
+    case Stmt::OMPParallelForSimdDirectiveClass:
+    case Stmt::OMPParallelSectionsDirectiveClass:
+    case Stmt::OMPParallelMasterDirectiveClass:
+    case Stmt::OMPParallelMaskedDirectiveClass:
+    case Stmt::OMPTaskDirectiveClass:
+    case Stmt::OMPTaskyieldDirectiveClass:
+    case Stmt::OMPBarrierDirectiveClass:
+    case Stmt::OMPTaskwaitDirectiveClass:
+    case Stmt::OMPErrorDirectiveClass:
+    case Stmt::OMPTaskgroupDirectiveClass:
+    case Stmt::OMPFlushDirectiveClass:
+    case Stmt::OMPDepobjDirectiveClass:
+    case Stmt::OMPScanDirectiveClass:
+    case Stmt::OMPOrderedDirectiveClass:
+    case Stmt::OMPAtomicDirectiveClass:
+    case Stmt::OMPTargetDirectiveClass:
+    case Stmt::OMPTargetDataDirectiveClass:
+    case Stmt::OMPTargetEnterDataDirectiveClass:
+    case Stmt::OMPTargetExitDataDirectiveClass:
+    case Stmt::OMPTargetParallelDirectiveClass:
+    case Stmt::OMPTargetParallelForDirectiveClass:
+    case Stmt::OMPTargetUpdateDirectiveClass:
+    case Stmt::OMPTeamsDirectiveClass:
+    case Stmt::OMPCancellationPointDirectiveClass:
+    case Stmt::OMPCancelDirectiveClass:
+    case Stmt::OMPTaskLoopDirectiveClass:
+    case Stmt::OMPTaskLoopSimdDirectiveClass:
+    case Stmt::OMPMasterTaskLoopDirectiveClass:
+    case Stmt::OMPMaskedTaskLoopDirectiveClass:
+    case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
+    case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
+    case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
+    case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
+    case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
+    case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
+    case Stmt::OMPDistributeDirectiveClass:
+    case Stmt::OMPDistributeParallelForDirectiveClass:
+    case Stmt::OMPDistributeParallelForSimdDirectiveClass:
+    case Stmt::OMPDistributeSimdDirectiveClass:
+    case Stmt::OMPTargetParallelForSimdDirectiveClass:
+    case Stmt::OMPTargetSimdDirectiveClass:
+    case Stmt::OMPTeamsDistributeDirectiveClass:
+    case Stmt::OMPTeamsDistributeSimdDirectiveClass:
+    case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
+    case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
+    case Stmt::OMPTargetTeamsDirectiveClass:
+    case Stmt::OMPTargetTeamsDistributeDirectiveClass:
+    case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
+    case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
+    case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
+    case Stmt::OMPTileDirectiveClass:
+    case Stmt::OMPInteropDirectiveClass:
+    case Stmt::OMPDispatchDirectiveClass:
+    case Stmt::OMPMaskedDirectiveClass:
+    case Stmt::OMPGenericLoopDirectiveClass:
+    case Stmt::OMPTeamsGenericLoopDirectiveClass:
+    case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
+    case Stmt::OMPParallelGenericLoopDirectiveClass:
+    case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
+    case Stmt::CapturedStmtClass:
+    case Stmt::OpenACCComputeConstructClass:
+    case Stmt::OpenACCLoopConstructClass:
+    case Stmt::OMPUnrollDirectiveClass:
+    case Stmt::OMPMetaDirectiveClass: {
+      const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
+      Engine.addAbortedBlock(node, currBldrCtx->getBlock());
+      break;
+    }
 
-  case Stmt::ParenExprClass:
-    llvm_unreachable("ParenExprs already handled.");
-  case Stmt::GenericSelectionExprClass:
-    llvm_unreachable("GenericSelectionExprs already handled.");
-  // Cases that should never be evaluated simply because they shouldn't
-  // appear in the CFG.
-  case Stmt::BreakStmtClass:
-  case Stmt::CaseStmtClass:
-  case Stmt::CompoundStmtClass:
-  case Stmt::ContinueStmtClass:
-  case Stmt::CXXForRangeStmtClass:
-  case Stmt::DefaultStmtClass:
-  case Stmt::DoStmtClass:
-  case Stmt::ForStmtClass:
-  case Stmt::GotoStmtClass:
-  case Stmt::IfStmtClass:
-  case Stmt::IndirectGotoStmtClass:
-  case Stmt::LabelStmtClass:
-  case Stmt::NoStmtClass:
-  case Stmt::NullStmtClass:
-  case Stmt::SwitchStmtClass:
-  case Stmt::WhileStmtClass:
-  case Expr::MSDependentExistsStmtClass:
-    llvm_unreachable("Stmt should not be in analyzer evaluation loop");
-  case Stmt::ImplicitValueInitExprClass:
-    // These nodes are shared in the CFG and would case caching out.
-    // Moreover, no additional evaluation required for them, the
-    // analyzer can reconstruct these values from the AST.
-    llvm_unreachable("Should be pruned from CFG");
-
-  case Stmt::ObjCSubscriptRefExprClass:
-  case Stmt::ObjCPropertyRefExprClass:
-    llvm_unreachable("These are handled by PseudoObjectExpr");
-
-  case Stmt::GNUNullExprClass: {
-    // GNU __null is a pointer-width integer, not an actual pointer.
-    ProgramStateRef state = Pred->getState();
-    state = state->BindExpr(
-        S, Pred->getLocationContext(),
-        svalBuilder.makeIntValWithWidth(getContext().VoidPtrTy, 0));
-    Bldr.generateNode(S, Pred, state);
-    break;
-  }
+    case Stmt::ParenExprClass:
+      llvm_unreachable("ParenExprs already handled.");
+    case Stmt::GenericSelectionExprClass:
+      llvm_unreachable("GenericSelectionExprs already handled.");
+    // Cases that should never be evaluated simply because they shouldn't
+    // appear in the CFG.
+    case Stmt::BreakStmtClass:
+    case Stmt::CaseStmtClass:
+    case Stmt::CompoundStmtClass:
+    case Stmt::ContinueStmtClass:
+    case Stmt::CXXForRangeStmtClass:
+    case Stmt::DefaultStmtClass:
+    case Stmt::DoStmtClass:
+    case Stmt::ForStmtClass:
+    case Stmt::GotoStmtClass:
+    case Stmt::IfStmtClass:
+    case Stmt::IndirectGotoStmtClass:
+    case Stmt::LabelStmtClass:
+    case Stmt::NoStmtClass:
+    case Stmt::NullStmtClass:
+    case Stmt::SwitchStmtClass:
+    case Stmt::WhileStmtClass:
+    case Expr::MSDependentExistsStmtClass:
+      llvm_unreachable("Stmt should not be in analyzer evaluation loop");
+    case Stmt::ImplicitValueInitExprClass:
+      // These nodes are shared in the CFG and would case caching out.
+      // Moreover, no additional evaluation required for them, the
+      // analyzer can reconstruct these values from the AST.
+      llvm_unreachable("Should be pruned from CFG");
+
+    case Stmt::ObjCSubscriptRefExprClass:
+    case Stmt::ObjCPropertyRefExprClass:
+      llvm_unreachable("These are handled by PseudoObjectExpr");
+
+    case Stmt::GNUNullExprClass: {
+      // GNU __null is a pointer-width integer, not an actual pointer.
+      ProgramStateRef state = Pred->getState();
+      state = state->BindExpr(
+          S, Pred->getLocationContext(),
+          svalBuilder.makeIntValWithWidth(getContext().VoidPtrTy, 0));
+      Bldr.generateNode(S, Pred, state);
+      break;
+    }
 
-  case Stmt::ObjCAtSynchronizedStmtClass:
-    Bldr.takeNodes(Pred);
-    VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::ObjCAtSynchronizedStmtClass:
+      Bldr.takeNodes(Pred);
+      VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Expr::ConstantExprClass:
-  case Stmt::ExprWithCleanupsClass:
-    // Handled due to fully linearised CFG.
-    break;
+    case Expr::ConstantExprClass:
+    case Stmt::ExprWithCleanupsClass:
+      // Handled due to fully linearised CFG.
+      break;
 
-  case Stmt::CXXBindTemporaryExprClass: {
-    Bldr.takeNodes(Pred);
-    ExplodedNodeSet PreVisit;
-    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
-    ExplodedNodeSet Next;
-    VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), PreVisit, Next);
-    getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this);
-    Bldr.addNodes(Dst);
-    break;
-  }
+    case Stmt::CXXBindTemporaryExprClass: {
+      Bldr.takeNodes(Pred);
+      ExplodedNodeSet PreVisit;
+      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+      ExplodedNodeSet Next;
+      VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), PreVisit, Next);
+      getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this);
+      Bldr.addNodes(Dst);
+      break;
+    }
 
-  case Stmt::ArrayInitLoopExprClass:
-    Bldr.takeNodes(Pred);
-    VisitArrayInitLoopExpr(cast<ArrayInitLoopExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
-  // Cases not handled yet; but will handle some day.
-  case Stmt::DesignatedInitExprClass:
-  case Stmt::DesignatedInitUpdateExprClass:
-  case Stmt::ArrayInitIndexExprClass:
-  case Stmt::ExtVectorElementExprClass:
-  case Stmt::ImaginaryLiteralClass:
-  case Stmt::ObjCAtCatchStmtClass:
-  case Stmt::ObjCAtFinallyStmtClass:
-  case Stmt::ObjCAtTryStmtClass:
-  case Stmt::ObjCAutoreleasePoolStmtClass:
-  case Stmt::ObjCEncodeExprClass:
-  case Stmt::ObjCIsaExprClass:
-  case Stmt::ObjCProtocolExprClass:
-  case Stmt::ObjCSelectorExprClass:
-  case Stmt::ParenListExprClass:
-  case Stmt::ShuffleVectorExprClass:
-  case Stmt::ConvertVectorExprClass:
-  case Stmt::VAArgExprClass:
-  case Stmt::CUDAKernelCallExprClass:
-  case Stmt::OpaqueValueExprClass:
-  case Stmt::AsTypeExprClass:
-  case Stmt::ConceptSpecializationExprClass:
-  case Stmt::CXXRewrittenBinaryOperatorClass:
-  case Stmt::RequiresExprClass:
-  case Expr::CXXParenListInitExprClass:
-    // Fall through.
-
-  // Cases we intentionally don't evaluate, since they don't need
-  // to be explicitly evaluated.
-  case Stmt::PredefinedExprClass:
-  case Stmt::AddrLabelExprClass:
-  case Stmt::AttributedStmtClass:
-  case Stmt::IntegerLiteralClass:
-  case Stmt::FixedPointLiteralClass:
-  case Stmt::CharacterLiteralClass:
-  case Stmt::CXXScalarValueInitExprClass:
-  case Stmt::CXXBoolLiteralExprClass:
-  case Stmt::ObjCBoolLiteralExprClass:
-  case Stmt::ObjCAvailabilityCheckExprClass:
-  case Stmt::FloatingLiteralClass:
-  case Stmt::NoInitExprClass:
-  case Stmt::SizeOfPackExprClass:
-  case Stmt::StringLiteralClass:
-  case Stmt::SourceLocExprClass:
-  case Stmt::ObjCStringLiteralClass:
-  case Stmt::CXXPseudoDestructorExprClass:
-  case Stmt::SubstNonTypeTemplateParmExprClass:
-  case Stmt::CXXNullPtrLiteralExprClass:
-  case Stmt::ArraySectionExprClass:
-  case Stmt::OMPArrayShapingExprClass:
-  case Stmt::OMPIteratorExprClass:
-  case Stmt::SYCLUniqueStableNameExprClass:
-  case Stmt::TypeTraitExprClass: {
-    Bldr.takeNodes(Pred);
-    ExplodedNodeSet preVisit;
-    getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
-    getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this);
-    Bldr.addNodes(Dst);
-    break;
-  }
+    case Stmt::ArrayInitLoopExprClass:
+      Bldr.takeNodes(Pred);
+      VisitArrayInitLoopExpr(cast<ArrayInitLoopExpr>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
+    // Cases not handled yet; but will handle some day.
+    case Stmt::DesignatedInitExprClass:
+    case Stmt::DesignatedInitUpdateExprClass:
+    case Stmt::ArrayInitIndexExprClass:
+    case Stmt::ExtVectorElementExprClass:
+    case Stmt::ImaginaryLiteralClass:
+    case Stmt::ObjCAtCatchStmtClass:
+    case Stmt::ObjCAtFinallyStmtClass:
+    case Stmt::ObjCAtTryStmtClass:
+    case Stmt::ObjCAutoreleasePoolStmtClass:
+    case Stmt::ObjCEncodeExprClass:
+    case Stmt::ObjCIsaExprClass:
+    case Stmt::ObjCProtocolExprClass:
+    case Stmt::ObjCSelectorExprClass:
+    case Stmt::ParenListExprClass:
+    case Stmt::ShuffleVectorExprClass:
+    case Stmt::ConvertVectorExprClass:
+    case Stmt::VAArgExprClass:
+    case Stmt::CUDAKernelCallExprClass:
+    case Stmt::OpaqueValueExprClass:
+    case Stmt::AsTypeExprClass:
+    case Stmt::ConceptSpecializationExprClass:
+    case Stmt::CXXRewrittenBinaryOperatorClass:
+    case Stmt::RequiresExprClass:
+    case Expr::CXXParenListInitExprClass:
+      // Fall through.
+
+    // Cases we intentionally don't evaluate, since they don't need
+    // to be explicitly evaluated.
+    case Stmt::PredefinedExprClass:
+    case Stmt::AddrLabelExprClass:
+    case Stmt::AttributedStmtClass:
+    case Stmt::IntegerLiteralClass:
+    case Stmt::FixedPointLiteralClass:
+    case Stmt::CharacterLiteralClass:
+    case Stmt::CXXScalarValueInitExprClass:
+    case Stmt::CXXBoolLiteralExprClass:
+    case Stmt::ObjCBoolLiteralExprClass:
+    case Stmt::ObjCAvailabilityCheckExprClass:
+    case Stmt::FloatingLiteralClass:
+    case Stmt::NoInitExprClass:
+    case Stmt::SizeOfPackExprClass:
+    case Stmt::StringLiteralClass:
+    case Stmt::SourceLocExprClass:
+    case Stmt::ObjCStringLiteralClass:
+    case Stmt::CXXPseudoDestructorExprClass:
+    case Stmt::SubstNonTypeTemplateParmExprClass:
+    case Stmt::CXXNullPtrLiteralExprClass:
+    case Stmt::ArraySectionExprClass:
+    case Stmt::OMPArrayShapingExprClass:
+    case Stmt::OMPIteratorExprClass:
+    case Stmt::SYCLUniqueStableNameExprClass:
+    case Stmt::TypeTraitExprClass: {
+      Bldr.takeNodes(Pred);
+      ExplodedNodeSet preVisit;
+      getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
+      getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this);
+      Bldr.addNodes(Dst);
+      break;
+    }
 
-  case Stmt::CXXDefaultArgExprClass:
-  case Stmt::CXXDefaultInitExprClass: {
-    Bldr.takeNodes(Pred);
-    ExplodedNodeSet PreVisit;
-    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+    case Stmt::CXXDefaultArgExprClass:
+    case Stmt::CXXDefaultInitExprClass: {
+      Bldr.takeNodes(Pred);
+      ExplodedNodeSet PreVisit;
+      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
 
-    ExplodedNodeSet Tmp;
-    StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx);
+      ExplodedNodeSet Tmp;
+      StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx);
 
-    const Expr *ArgE;
-    if (const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
-      ArgE = DefE->getExpr();
-    else if (const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
-      ArgE = DefE->getExpr();
-    else
-      llvm_unreachable("unknown constant wrapper kind");
+      const Expr *ArgE;
+      if (const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
+        ArgE = DefE->getExpr();
+      else if (const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
+        ArgE = DefE->getExpr();
+      else
+        llvm_unreachable("unknown constant wrapper kind");
 
-    bool IsTemporary = false;
-    if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
-      ArgE = MTE->getSubExpr();
-      IsTemporary = true;
-    }
+      bool IsTemporary = false;
+      if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
+        ArgE = MTE->getSubExpr();
+        IsTemporary = true;
+      }
 
-    std::optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE);
-    if (!ConstantVal)
-      ConstantVal = UnknownVal();
+      std::optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE);
+      if (!ConstantVal)
+        ConstantVal = UnknownVal();
+
+      const LocationContext *LCtx = Pred->getLocationContext();
+      for (const auto I : PreVisit) {
+        ProgramStateRef State = I->getState();
+        State = State->BindExpr(S, LCtx, *ConstantVal);
+        if (IsTemporary)
+          State = createTemporaryRegionIfNeeded(State, LCtx,
+                                                cast<Expr>(S),
+                                                cast<Expr>(S));
+        Bldr2.generateNode(S, I, State);
+      }
 
-    const LocationContext *LCtx = Pred->getLocationContext();
-    for (const auto I : PreVisit) {
-      ProgramStateRef State = I->getState();
-      State = State->BindExpr(S, LCtx, *ConstantVal);
-      if (IsTemporary)
-        State = createTemporaryRegionIfNeeded(State, LCtx, cast<Expr>(S),
-                                              cast<Expr>(S));
-      Bldr2.generateNode(S, I, State);
+      getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
+      Bldr.addNodes(Dst);
+      break;
     }
 
-    getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
-    Bldr.addNodes(Dst);
-    break;
-  }
+    // Cases we evaluate as opaque expressions, conjuring a symbol.
+    case Stmt::CXXStdInitializerListExprClass:
+    case Expr::ObjCArrayLiteralClass:
+    case Expr::ObjCDictionaryLiteralClass:
+    case Expr::ObjCBoxedExprClass: {
+      Bldr.takeNodes(Pred);
 
-  // Cases we evaluate as opaque expressions, conjuring a symbol.
-  case Stmt::CXXStdInitializerListExprClass:
-  case Expr::ObjCArrayLiteralClass:
-  case Expr::ObjCDictionaryLiteralClass:
-  case Expr::ObjCBoxedExprClass: {
-    Bldr.takeNodes(Pred);
+      ExplodedNodeSet preVisit;
+      getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
 
-    ExplodedNodeSet preVisit;
-    getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
+      ExplodedNodeSet Tmp;
+      StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx);
+
+      const auto *Ex = cast<Expr>(S);
+      QualType resultType = Ex->getType();
+
+      for (const auto N : preVisit) {
+        const LocationContext *LCtx = N->getLocationContext();
+        SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
+                                                   resultType,
+                                                   currBldrCtx->blockCount());
+        ProgramStateRef State = N->getState()->BindExpr(Ex, LCtx, result);
+
+        // Escape pointers passed into the list, unless it's an ObjC boxed
+        // expression which is not a boxable C structure.
+        if (!(isa<ObjCBoxedExpr>(Ex) &&
+              !cast<ObjCBoxedExpr>(Ex)->getSubExpr()
+                                      ->getType()->isRecordType()))
+          for (auto Child : Ex->children()) {
+            assert(Child);
+            SVal Val = State->getSVal(Child, LCtx);
+            State = escapeValues(State, Val, PSK_EscapeOther);
+          }
 
-    ExplodedNodeSet Tmp;
-    StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx);
-
-    const auto *Ex = cast<Expr>(S);
-    QualType resultType = Ex->getType();
-
-    for (const auto N : preVisit) {
-      const LocationContext *LCtx = N->getLocationContext();
-      SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx, resultType,
-                                                 currBldrCtx->blockCount());
-      ProgramStateRef State = N->getState()->BindExpr(Ex, LCtx, result);
-
-      // Escape pointers passed into the list, unless it's an ObjC boxed
-      // expression which is not a boxable C structure.
-      if (!(isa<ObjCBoxedExpr>(Ex) &&
-            !cast<ObjCBoxedExpr>(Ex)->getSubExpr()->getType()->isRecordType()))
-        for (auto Child : Ex->children()) {
-          assert(Child);
-          SVal Val = State->getSVal(Child, LCtx);
-          State = escapeValues(State, Val, PSK_EscapeOther);
-        }
+        Bldr2.generateNode(S, N, State);
+      }
 
-      Bldr2.generateNode(S, N, State);
+      getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
+      Bldr.addNodes(Dst);
+      break;
     }
 
-    getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
-    Bldr.addNodes(Dst);
-    break;
-  }
-
-  case Stmt::ArraySubscriptExprClass:
-    Bldr.takeNodes(Pred);
-    VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
-
-  case Stmt::MatrixSubscriptExprClass:
-    llvm_unreachable("Support for MatrixSubscriptExpr is not implemented.");
-    break;
+    case Stmt::ArraySubscriptExprClass:
+      Bldr.takeNodes(Pred);
+      VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::GCCAsmStmtClass: {
-    Bldr.takeNodes(Pred);
-    ExplodedNodeSet PreVisit;
-    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
-    ExplodedNodeSet PostVisit;
-    for (ExplodedNode *const N : PreVisit)
-      VisitGCCAsmStmt(cast<GCCAsmStmt>(S), N, PostVisit);
-    getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
-    Bldr.addNodes(Dst);
-  } break;
-
-  case Stmt::MSAsmStmtClass:
-    Bldr.takeNodes(Pred);
-    VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::MatrixSubscriptExprClass:
+      llvm_unreachable("Support for MatrixSubscriptExpr is not implemented.");
+      break;
 
-  case Stmt::BlockExprClass:
-    Bldr.takeNodes(Pred);
-    VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::GCCAsmStmtClass: {
+      Bldr.takeNodes(Pred);
+      ExplodedNodeSet PreVisit;
+      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+      ExplodedNodeSet PostVisit;
+      for (ExplodedNode *const N : PreVisit)
+        VisitGCCAsmStmt(cast<GCCAsmStmt>(S), N, PostVisit);
+      getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
+      Bldr.addNodes(Dst);
+    } break;
 
-  case Stmt::LambdaExprClass:
-    if (AMgr.options.ShouldInlineLambdas) {
+    case Stmt::MSAsmStmtClass:
       Bldr.takeNodes(Pred);
-      VisitLambdaExpr(cast<LambdaExpr>(S), Pred, Dst);
+      VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst);
       Bldr.addNodes(Dst);
-    } else {
-      const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
-      Engine.addAbortedBlock(node, currBldrCtx->getBlock());
-    }
-    break;
+      break;
 
-  case Stmt::BinaryOperatorClass: {
-    const auto *B = cast<BinaryOperator>(S);
-    if (B->isLogicalOp()) {
+    case Stmt::BlockExprClass:
       Bldr.takeNodes(Pred);
-      VisitLogicalExpr(B, Pred, Dst);
+      VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
       Bldr.addNodes(Dst);
       break;
-    } else if (B->getOpcode() == BO_Comma) {
-      ProgramStateRef state = Pred->getState();
-      Bldr.generateNode(
-          B, Pred,
-          state->BindExpr(
-              B, Pred->getLocationContext(),
-              state->getSVal(B->getRHS(), Pred->getLocationContext())));
+
+    case Stmt::LambdaExprClass:
+      if (AMgr.options.ShouldInlineLambdas) {
+        Bldr.takeNodes(Pred);
+        VisitLambdaExpr(cast<LambdaExpr>(S), Pred, Dst);
+        Bldr.addNodes(Dst);
+      } else {
+        const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
+        Engine.addAbortedBlock(node, currBldrCtx->getBlock());
+      }
       break;
-    }
 
-    Bldr.takeNodes(Pred);
+    case Stmt::BinaryOperatorClass: {
+      const auto *B = cast<BinaryOperator>(S);
+      if (B->isLogicalOp()) {
+        Bldr.takeNodes(Pred);
+        VisitLogicalExpr(B, Pred, Dst);
+        Bldr.addNodes(Dst);
+        break;
+      }
+      else if (B->getOpcode() == BO_Comma) {
+        ProgramStateRef state = Pred->getState();
+        Bldr.generateNode(B, Pred,
+                          state->BindExpr(B, Pred->getLocationContext(),
+                                          state->getSVal(B->getRHS(),
+                                                  Pred->getLocationContext())));
+        break;
+      }
 
-    if (AMgr.options.ShouldEagerlyAssume &&
-        (B->isRelationalOp() || B->isEqualityOp())) {
-      ExplodedNodeSet Tmp;
-      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
-      evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S));
-    } else
-      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
+      Bldr.takeNodes(Pred);
 
-    Bldr.addNodes(Dst);
-    break;
-  }
+      if (AMgr.options.ShouldEagerlyAssume &&
+          (B->isRelationalOp() || B->isEqualityOp())) {
+        ExplodedNodeSet Tmp;
+        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
+        evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S));
+      }
+      else
+        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
 
-  case Stmt::CXXOperatorCallExprClass: {
-    const auto *OCE = cast<CXXOperatorCallExpr>(S);
+      Bldr.addNodes(Dst);
+      break;
+    }
 
-    // For instance method operators, make sure the 'this' argument has a
-    // valid region.
-    const Decl *Callee = OCE->getCalleeDecl();
-    if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
-      if (MD->isImplicitObjectMemberFunction()) {
-        ProgramStateRef State = Pred->getState();
-        const LocationContext *LCtx = Pred->getLocationContext();
-        ProgramStateRef NewState =
+    case Stmt::CXXOperatorCallExprClass: {
+      const auto *OCE = cast<CXXOperatorCallExpr>(S);
+
+      // For instance method operators, make sure the 'this' argument has a
+      // valid region.
+      const Decl *Callee = OCE->getCalleeDecl();
+      if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
+        if (MD->isImplicitObjectMemberFunction()) {
+          ProgramStateRef State = Pred->getState();
+          const LocationContext *LCtx = Pred->getLocationContext();
+          ProgramStateRef NewState =
             createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
-        if (NewState != State) {
-          Pred = Bldr.generateNode(OCE, Pred, NewState, /*tag=*/nullptr,
-                                   ProgramPoint::PreStmtKind);
-          // Did we cache out?
-          if (!Pred)
-            break;
+          if (NewState != State) {
+            Pred = Bldr.generateNode(OCE, Pred, NewState, /*tag=*/nullptr,
+                                     ProgramPoint::PreStmtKind);
+            // Did we cache out?
+            if (!Pred)
+              break;
+          }
         }
       }
+      [[fallthrough]];
     }
-    [[fallthrough]];
-  }
 
-  case Stmt::CallExprClass:
-  case Stmt::CXXMemberCallExprClass:
-  case Stmt::UserDefinedLiteralClass:
-    Bldr.takeNodes(Pred);
-    VisitCallExpr(cast<CallExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::CallExprClass:
+    case Stmt::CXXMemberCallExprClass:
+    case Stmt::UserDefinedLiteralClass:
+      Bldr.takeNodes(Pred);
+      VisitCallExpr(cast<CallExpr>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::CXXCatchStmtClass:
-    Bldr.takeNodes(Pred);
-    VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::CXXCatchStmtClass:
+      Bldr.takeNodes(Pred);
+      VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::CXXTemporaryObjectExprClass:
-  case Stmt::CXXConstructExprClass:
-    Bldr.takeNodes(Pred);
-    VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::CXXTemporaryObjectExprClass:
+    case Stmt::CXXConstructExprClass:
+      Bldr.takeNodes(Pred);
+      VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::CXXInheritedCtorInitExprClass:
-    Bldr.takeNodes(Pred);
-    VisitCXXInheritedCtorInitExpr(cast<CXXInheritedCtorInitExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::CXXInheritedCtorInitExprClass:
+      Bldr.takeNodes(Pred);
+      VisitCXXInheritedCtorInitExpr(cast<CXXInheritedCtorInitExpr>(S), Pred,
+                                    Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::CXXNewExprClass: {
-    Bldr.takeNodes(Pred);
+    case Stmt::CXXNewExprClass: {
+      Bldr.takeNodes(Pred);
 
-    ExplodedNodeSet PreVisit;
-    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+      ExplodedNodeSet PreVisit;
+      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
 
-    ExplodedNodeSet PostVisit;
-    for (const auto i : PreVisit)
-      VisitCXXNewExpr(cast<CXXNewExpr>(S), i, PostVisit);
+      ExplodedNodeSet PostVisit;
+      for (const auto i : PreVisit)
+        VisitCXXNewExpr(cast<CXXNewExpr>(S), i, PostVisit);
 
-    getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
-    Bldr.addNodes(Dst);
-    break;
-  }
+      getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
+      Bldr.addNodes(Dst);
+      break;
+    }
 
-  case Stmt::CXXDeleteExprClass: {
-    Bldr.takeNodes(Pred);
-    ExplodedNodeSet PreVisit;
-    const auto *CDE = cast<CXXDeleteExpr>(S);
-    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
-    ExplodedNodeSet PostVisit;
-    getCheckerManager().runCheckersForPostStmt(PostVisit, PreVisit, S, *this);
+    case Stmt::CXXDeleteExprClass: {
+      Bldr.takeNodes(Pred);
+      ExplodedNodeSet PreVisit;
+      const auto *CDE = cast<CXXDeleteExpr>(S);
+      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+      ExplodedNodeSet PostVisit;
+      getCheckerManager().runCheckersForPostStmt(PostVisit, PreVisit, S, *this);
 
-    for (const auto i : PostVisit)
-      VisitCXXDeleteExpr(CDE, i, Dst);
+      for (const auto i : PostVisit)
+        VisitCXXDeleteExpr(CDE, i, Dst);
 
-    Bldr.addNodes(Dst);
-    break;
-  }
-    // FIXME: ChooseExpr is really a constant.  We need to fix
-    //        the CFG do not model them as explicit control-flow.
+      Bldr.addNodes(Dst);
+      break;
+    }
+      // FIXME: ChooseExpr is really a constant.  We need to fix
+      //        the CFG do not model them as explicit control-flow.
 
-  case Stmt::ChooseExprClass: { // __builtin_choose_expr
-    Bldr.takeNodes(Pred);
-    const auto *C = cast<ChooseExpr>(S);
-    VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
-  }
+    case Stmt::ChooseExprClass: { // __builtin_choose_expr
+      Bldr.takeNodes(Pred);
+      const auto *C = cast<ChooseExpr>(S);
+      VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
+    }
 
-  case Stmt::CompoundAssignOperatorClass:
-    Bldr.takeNodes(Pred);
-    VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::CompoundAssignOperatorClass:
+      Bldr.takeNodes(Pred);
+      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::CompoundLiteralExprClass:
-    Bldr.takeNodes(Pred);
-    VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::CompoundLiteralExprClass:
+      Bldr.takeNodes(Pred);
+      VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::BinaryConditionalOperatorClass:
-  case Stmt::ConditionalOperatorClass: { // '?' operator
-    Bldr.takeNodes(Pred);
-    const auto *C = cast<AbstractConditionalOperator>(S);
-    VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
-  }
+    case Stmt::BinaryConditionalOperatorClass:
+    case Stmt::ConditionalOperatorClass: { // '?' operator
+      Bldr.takeNodes(Pred);
+      const auto *C = cast<AbstractConditionalOperator>(S);
+      VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
+    }
 
-  case Stmt::CXXThisExprClass:
-    Bldr.takeNodes(Pred);
-    VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::CXXThisExprClass:
+      Bldr.takeNodes(Pred);
+      VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::DeclRefExprClass: {
-    Bldr.takeNodes(Pred);
-    const auto *DE = cast<DeclRefExpr>(S);
-    VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
-  }
+    case Stmt::DeclRefExprClass: {
+      Bldr.takeNodes(Pred);
+      const auto *DE = cast<DeclRefExpr>(S);
+      VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
+    }
 
-  case Stmt::DeclStmtClass:
-    Bldr.takeNodes(Pred);
-    VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::DeclStmtClass:
+      Bldr.takeNodes(Pred);
+      VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::ImplicitCastExprClass:
-  case Stmt::CStyleCastExprClass:
-  case Stmt::CXXStaticCastExprClass:
-  case Stmt::CXXDynamicCastExprClass:
-  case Stmt::CXXReinterpretCastExprClass:
-  case Stmt::CXXConstCastExprClass:
-  case Stmt::CXXFunctionalCastExprClass:
-  case Stmt::BuiltinBitCastExprClass:
-  case Stmt::ObjCBridgedCastExprClass:
-  case Stmt::CXXAddrspaceCastExprClass: {
-    Bldr.takeNodes(Pred);
-    const auto *C = cast<CastExpr>(S);
-    ExplodedNodeSet dstExpr;
-    VisitCast(C, C->getSubExpr(), Pred, dstExpr);
-
-    // Handle the postvisit checks.
-    getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this);
-    Bldr.addNodes(Dst);
-    break;
-  }
+    case Stmt::ImplicitCastExprClass:
+    case Stmt::CStyleCastExprClass:
+    case Stmt::CXXStaticCastExprClass:
+    case Stmt::CXXDynamicCastExprClass:
+    case Stmt::CXXReinterpretCastExprClass:
+    case Stmt::CXXConstCastExprClass:
+    case Stmt::CXXFunctionalCastExprClass:
+    case Stmt::BuiltinBitCastExprClass:
+    case Stmt::ObjCBridgedCastExprClass:
+    case Stmt::CXXAddrspaceCastExprClass: {
+      Bldr.takeNodes(Pred);
+      const auto *C = cast<CastExpr>(S);
+      ExplodedNodeSet dstExpr;
+      VisitCast(C, C->getSubExpr(), Pred, dstExpr);
 
-  case Expr::MaterializeTemporaryExprClass: {
-    Bldr.takeNodes(Pred);
-    const auto *MTE = cast<MaterializeTemporaryExpr>(S);
-    ExplodedNodeSet dstPrevisit;
-    getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, MTE, *this);
-    ExplodedNodeSet dstExpr;
-    for (const auto i : dstPrevisit)
-      CreateCXXTemporaryObject(MTE, i, dstExpr);
-    getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, MTE, *this);
-    Bldr.addNodes(Dst);
-    break;
-  }
+      // Handle the postvisit checks.
+      getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this);
+      Bldr.addNodes(Dst);
+      break;
+    }
 
-  case Stmt::InitListExprClass:
-    Bldr.takeNodes(Pred);
-    VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Expr::MaterializeTemporaryExprClass: {
+      Bldr.takeNodes(Pred);
+      const auto *MTE = cast<MaterializeTemporaryExpr>(S);
+      ExplodedNodeSet dstPrevisit;
+      getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, MTE, *this);
+      ExplodedNodeSet dstExpr;
+      for (const auto i : dstPrevisit)
+        CreateCXXTemporaryObject(MTE, i, dstExpr);
+      getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, MTE, *this);
+      Bldr.addNodes(Dst);
+      break;
+    }
 
-  case Stmt::MemberExprClass:
-    Bldr.takeNodes(Pred);
-    VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::InitListExprClass:
+      Bldr.takeNodes(Pred);
+      VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::AtomicExprClass:
-    Bldr.takeNodes(Pred);
-    VisitAtomicExpr(cast<AtomicExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::MemberExprClass:
+      Bldr.takeNodes(Pred);
+      VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::ObjCIvarRefExprClass:
-    Bldr.takeNodes(Pred);
-    VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::AtomicExprClass:
+      Bldr.takeNodes(Pred);
+      VisitAtomicExpr(cast<AtomicExpr>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::ObjCForCollectionStmtClass:
-    Bldr.takeNodes(Pred);
-    VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::ObjCIvarRefExprClass:
+      Bldr.takeNodes(Pred);
+      VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::ObjCMessageExprClass:
-    Bldr.takeNodes(Pred);
-    VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::ObjCForCollectionStmtClass:
+      Bldr.takeNodes(Pred);
+      VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::ObjCAtThrowStmtClass:
-  case Stmt::CXXThrowExprClass:
-    // FIXME: This is not complete.  We basically treat @throw as
-    // an abort.
-    Bldr.generateSink(S, Pred, Pred->getState());
-    break;
+    case Stmt::ObjCMessageExprClass:
+      Bldr.takeNodes(Pred);
+      VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::ReturnStmtClass:
-    Bldr.takeNodes(Pred);
-    VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+    case Stmt::ObjCAtThrowStmtClass:
+    case Stmt::CXXThrowExprClass:
+      // FIXME: This is not complete.  We basically treat @throw as
+      // an abort.
+      Bldr.generateSink(S, Pred, Pred->getState());
+      break;
 
-  case Stmt::OffsetOfExprClass: {
-    Bldr.takeNodes(Pred);
-    ExplodedNodeSet PreVisit;
-    getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+    case Stmt::ReturnStmtClass:
+      Bldr.takeNodes(Pred);
+      VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-    ExplodedNodeSet PostVisit;
-    for (const auto Node : PreVisit)
-      VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Node, PostVisit);
+    case Stmt::OffsetOfExprClass: {
+      Bldr.takeNodes(Pred);
+      ExplodedNodeSet PreVisit;
+      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
 
-    getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
-    Bldr.addNodes(Dst);
-    break;
-  }
+      ExplodedNodeSet PostVisit;
+      for (const auto Node : PreVisit)
+        VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Node, PostVisit);
 
-  case Stmt::UnaryExprOrTypeTraitExprClass:
-    Bldr.takeNodes(Pred);
-    VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S), Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
+      getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
+      Bldr.addNodes(Dst);
+      break;
+    }
+
+    case Stmt::UnaryExprOrTypeTraitExprClass:
+      Bldr.takeNodes(Pred);
+      VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
+                                    Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
 
-  case Stmt::StmtExprClass: {
-    const auto *SE = cast<StmtExpr>(S);
+    case Stmt::StmtExprClass: {
+      const auto *SE = cast<StmtExpr>(S);
 
-    if (SE->getSubStmt()->body_empty()) {
-      // Empty statement expression.
-      assert(SE->getType() == getContext().VoidTy &&
-             "Empty statement expression must have void type.");
+      if (SE->getSubStmt()->body_empty()) {
+        // Empty statement expression.
+        assert(SE->getType() == getContext().VoidTy
+               && "Empty statement expression must have void type.");
+        break;
+      }
+
+      if (const auto *LastExpr =
+              dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
+        ProgramStateRef state = Pred->getState();
+        Bldr.generateNode(SE, Pred,
+                          state->BindExpr(SE, Pred->getLocationContext(),
+                                          state->getSVal(LastExpr,
+                                                  Pred->getLocationContext())));
+      }
       break;
     }
 
-    if (const auto *LastExpr =
-            dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
-      ProgramStateRef state = Pred->getState();
-      Bldr.generateNode(
-          SE, Pred,
-          state->BindExpr(
-              SE, Pred->getLocationContext(),
-              state->getSVal(LastExpr, Pred->getLocationContext())));
+    case Stmt::UnaryOperatorClass: {
+      Bldr.takeNodes(Pred);
+      const auto *U = cast<UnaryOperator>(S);
+      if (AMgr.options.ShouldEagerlyAssume && (U->getOpcode() == UO_LNot)) {
+        ExplodedNodeSet Tmp;
+        VisitUnaryOperator(U, Pred, Tmp);
+        evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U);
+      }
+      else
+        VisitUnaryOperator(U, Pred, Dst);
+      Bldr.addNodes(Dst);
+      break;
     }
-    break;
-  }
-
-  case Stmt::UnaryOperatorClass: {
-    Bldr.takeNodes(Pred);
-    const auto *U = cast<UnaryOperator>(S);
-    if (AMgr.options.ShouldEagerlyAssume && (U->getOpcode() == UO_LNot)) {
-      ExplodedNodeSet Tmp;
-      VisitUnaryOperator(U, Pred, Tmp);
-      evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U);
-    } else
-      VisitUnaryOperator(U, Pred, Dst);
-    Bldr.addNodes(Dst);
-    break;
-  }
 
-  case Stmt::PseudoObjectExprClass: {
-    Bldr.takeNodes(Pred);
-    ProgramStateRef state = Pred->getState();
-    const auto *PE = cast<PseudoObjectExpr>(S);
-    if (const Expr *Result = PE->getResultExpr()) {
-      SVal V = state->getSVal(Result, Pred->getLocationContext());
-      Bldr.generateNode(S, Pred,
-                        state->BindExpr(S, Pred->getLocationContext(), V));
-    } else
-      Bldr.generateNode(
-          S, Pred,
-          state->BindExpr(S, Pred->getLocationContext(), UnknownVal()));
+    case Stmt::PseudoObjectExprClass: {
+      Bldr.takeNodes(Pred);
+      ProgramStateRef state = Pred->getState();
+      const auto *PE = cast<PseudoObjectExpr>(S);
+      if (const Expr *Result = PE->getResultExpr()) {
+        SVal V = state->getSVal(Result, Pred->getLocationContext());
+        Bldr.generateNode(S, Pred,
+                          state->BindExpr(S, Pred->getLocationContext(), V));
+      }
+      else
+        Bldr.generateNode(S, Pred,
+                          state->BindExpr(S, Pred->getLocationContext(),
+                                                   UnknownVal()));
 
-    Bldr.addNodes(Dst);
-    break;
-  }
+      Bldr.addNodes(Dst);
+      break;
+    }
 
-  case Expr::ObjCIndirectCopyRestoreExprClass: {
-    // ObjCIndirectCopyRestoreExpr implies passing a temporary for
-    // correctness of lifetime management.  Due to limited analysis
-    // of ARC, this is implemented as direct arg passing.
-    Bldr.takeNodes(Pred);
-    ProgramStateRef state = Pred->getState();
-    const auto *OIE = cast<ObjCIndirectCopyRestoreExpr>(S);
-    const Expr *E = OIE->getSubExpr();
-    SVal V = state->getSVal(E, Pred->getLocationContext());
-    Bldr.generateNode(S, Pred,
-                      state->BindExpr(S, Pred->getLocationContext(), V));
-    Bldr.addNodes(Dst);
-    break;
-  }
+    case Expr::ObjCIndirectCopyRestoreExprClass: {
+      // ObjCIndirectCopyRestoreExpr implies passing a temporary for
+      // correctness of lifetime management.  Due to limited analysis
+      // of ARC, this is implemented as direct arg passing.
+      Bldr.takeNodes(Pred);
+      ProgramStateRef state = Pred->getState();
+      const auto *OIE = cast<ObjCIndirectCopyRestoreExpr>(S);
+      const Expr *E = OIE->getSubExpr();
+      SVal V = state->getSVal(E, Pred->getLocationContext());
+      Bldr.generateNode(S, Pred,
+              state->BindExpr(S, Pred->getLocationContext(), V));
+      Bldr.addNodes(Dst);
+      break;
+    }
   }
 }
 
@@ -2453,7 +2475,7 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N,
   // Note, changing the state ensures that we are not going to cache out.
   ProgramStateRef NewNodeState = BeforeProcessingCall->getState();
   NewNodeState =
-      NewNodeState->set<ReplayWithoutInlining>(const_cast<Stmt *>(CE));
+    NewNodeState->set<ReplayWithoutInlining>(const_cast<Stmt *>(CE));
 
   // Make the new node a successor of BeforeProcessingCall.
   bool IsNew = false;
@@ -2467,7 +2489,7 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N,
 
   // Add the new node to the work list.
   Engine.enqueueStmtNode(NewNode, CalleeSF->getCallSiteBlock(),
-                         CalleeSF->getIndex());
+                                  CalleeSF->getIndex());
   NumTimesRetriedWithoutInlining++;
   return true;
 }
@@ -2479,7 +2501,7 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
   PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
   // If we reach a loop which has a known bound (and meets
   // other constraints) then consider completely unrolling it.
-  if (AMgr.options.ShouldUnrollLoops) {
+  if(AMgr.options.ShouldUnrollLoops) {
     unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath;
     const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminatorStmt();
     if (Term) {
@@ -2493,7 +2515,7 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
       }
     }
     // Is we are inside an unrolled loop then no need the check the counters.
-    if (isUnrolledState(Pred->getState()))
+    if(isUnrolledState(Pred->getState()))
       return;
   }
 
@@ -2517,14 +2539,14 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
   if (BlockCount >= AMgr.options.maxBlockVisitOnPath) {
     static SimpleProgramPointTag tag(TagProviderName, "Block count exceeded");
     const ExplodedNode *Sink =
-        nodeBuilder.generateSink(Pred->getState(), Pred, &tag);
+                   nodeBuilder.generateSink(Pred->getState(), Pred, &tag);
 
     // Check if we stopped at the top level function or not.
     // Root node should have the location context of the top most function.
     const LocationContext *CalleeLC = Pred->getLocation().getLocationContext();
     const LocationContext *CalleeSF = CalleeLC->getStackFrame();
     const LocationContext *RootLC =
-        (*G.roots_begin())->getLocation().getLocationContext();
+                        (*G.roots_begin())->getLocation().getLocationContext();
     if (RootLC->getStackFrame() != CalleeSF) {
       Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl());
 
@@ -2553,8 +2575,10 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
 /// integers that promote their values (which are currently not tracked well).
 /// This function returns the SVal bound to Condition->IgnoreCasts if all the
 //  cast(s) did was sign-extend the original value.
-static SVal RecoverCastedSymbol(ProgramStateRef state, const Stmt *Condition,
-                                const LocationContext *LCtx, ASTContext &Ctx) {
+static SVal RecoverCastedSymbol(ProgramStateRef state,
+                                const Stmt *Condition,
+                                const LocationContext *LCtx,
+                                ASTContext &Ctx) {
 
   const auto *Ex = dyn_cast<Expr>(Condition);
   if (!Ex)
@@ -2615,7 +2639,8 @@ static const Stmt *getRightmostLeaf(const Stmt *Condition) {
 // not evaluated, and is thus not in the SVal cache, we need to use that leaf
 // expression to evaluate the truth value of the condition in the current state
 // space.
-static const Stmt *ResolveCondition(const Stmt *Condition, const CFGBlock *B) {
+static const Stmt *ResolveCondition(const Stmt *Condition,
+                                    const CFGBlock *B) {
   if (const auto *Ex = dyn_cast<Expr>(Condition))
     Condition = Ex->IgnoreParens();
 
@@ -2657,9 +2682,10 @@ ProgramStateRef ExprEngine::setWhetherHasMoreIteration(
   return State->set<ObjCForHasMoreIterations>({O, LC}, HasMoreIteraton);
 }
 
-ProgramStateRef ExprEngine::removeIterationState(ProgramStateRef State,
-                                                 const ObjCForCollectionStmt *O,
-                                                 const LocationContext *LC) {
+ProgramStateRef
+ExprEngine::removeIterationState(ProgramStateRef State,
+                                 const ObjCForCollectionStmt *O,
+                                 const LocationContext *LC) {
   assert(State->contains<ObjCForHasMoreIterations>({O, LC}));
   return State->remove<ObjCForHasMoreIterations>({O, LC});
 }
@@ -2722,8 +2748,10 @@ assumeCondition(const Stmt *Condition, ExplodedNode *N) {
 }
 
 void ExprEngine::processBranch(const Stmt *Condition,
-                               NodeBuilderContext &BldCtx, ExplodedNode *Pred,
-                               ExplodedNodeSet &Dst, const CFGBlock *DstT,
+                               NodeBuilderContext& BldCtx,
+                               ExplodedNode *Pred,
+                               ExplodedNodeSet &Dst,
+                               const CFGBlock *DstT,
                                const CFGBlock *DstF) {
   assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) &&
          "CXXBindTemporaryExprs are handled by processBindTemporary.");
@@ -2797,9 +2825,12 @@ void ExprEngine::processBranch(const Stmt *Condition,
 REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedGlobalsSet,
                                  llvm::ImmutableSet<const VarDecl *>)
 
-void ExprEngine::processStaticInitializer(
-    const DeclStmt *DS, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred,
-    ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) {
+void ExprEngine::processStaticInitializer(const DeclStmt *DS,
+                                          NodeBuilderContext &BuilderCtx,
+                                          ExplodedNode *Pred,
+                                          ExplodedNodeSet &Dst,
+                                          const CFGBlock *DstT,
+                                          const CFGBlock *DstF) {
   PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
   currBldrCtx = &BuilderCtx;
 
@@ -2848,7 +2879,7 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
 
   if (isa<UndefinedVal, loc::ConcreteInt>(V)) {
     // Dispatch to the first target and mark it as a sink.
-    // ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
+    //ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
     // FIXME: add checker visit.
     //    UndefBranches.insert(N);
     return;
@@ -2871,7 +2902,7 @@ void ExprEngine::processBeginOfFunction(NodeBuilderContext &BC,
 
 /// ProcessEndPath - Called by CoreEngine.  Used to generate end-of-path
 ///  nodes when the control reaches the end of a function.
-void ExprEngine::processEndOfFunction(NodeBuilderContext &BC,
+void ExprEngine::processEndOfFunction(NodeBuilderContext& BC,
                                       ExplodedNode *Pred,
                                       const ReturnStmt *RS) {
   ProgramStateRef State = Pred->getState();
@@ -2945,17 +2976,17 @@ void ExprEngine::processEndOfFunction(NodeBuilderContext &BC,
 
 /// ProcessSwitch - Called by CoreEngine.  Used to generate successor
 ///  nodes by processing the 'effects' of a switch statement.
-void ExprEngine::processSwitch(SwitchNodeBuilder &builder) {
+void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
   using iterator = SwitchNodeBuilder::iterator;
 
   ProgramStateRef state = builder.getState();
   const Expr *CondE = builder.getCondition();
-  SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext());
+  SVal  CondV_untested = state->getSVal(CondE, builder.getLocationContext());
 
   if (CondV_untested.isUndef()) {
-    // ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
-    //  FIXME: add checker
-    // UndefBranches.insert(N);
+    //ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
+    // FIXME: add checker
+    //UndefBranches.insert(N);
 
     return;
   }
@@ -2966,7 +2997,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder &builder) {
   iterator I = builder.begin(), EI = builder.end();
   bool defaultIsFeasible = I == EI;
 
-  for (; I != EI; ++I) {
+  for ( ; I != EI; ++I) {
     // Successor may be pruned out during CFG construction.
     if (!I.getBlock())
       continue;
@@ -3058,7 +3089,8 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
       // Sema follows a sequence of complex rules to determine whether the
       // variable should be captured.
       if (const FieldDecl *FD = LambdaCaptureFields[VD]) {
-        Loc CXXThis = svalBuilder.getCXXThis(MD, LocCtxt->getStackFrame());
+        Loc CXXThis =
+            svalBuilder.getCXXThis(MD, LocCtxt->getStackFrame());
         SVal CXXThisVal = state->getSVal(CXXThis);
         VInfo = std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType());
       }
@@ -3266,10 +3298,10 @@ void ExprEngine::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *Ex,
 
 /// VisitArraySubscriptExpr - Transfer function for array accesses
 void ExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr *A,
-                                         ExplodedNode *Pred,
-                                         ExplodedNodeSet &Dst) {
+                                             ExplodedNode *Pred,
+                                             ExplodedNodeSet &Dst){
   const Expr *Base = A->getBase()->IgnoreParens();
-  const Expr *Idx = A->getIdx()->IgnoreParens();
+  const Expr *Idx  = A->getIdx()->IgnoreParens();
 
   ExplodedNodeSet CheckerPreStmt;
   getCheckerManager().runCheckersForPreStmt(CheckerPreStmt, Pred, A, *this);
@@ -3282,9 +3314,8 @@ void ExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr *A,
   // The "like" case is for situations where C standard prohibits the type to
   // be an lvalue, e.g. taking the address of a subscript of an expression of
   // type "void *".
-  bool IsGLValueLike =
-      A->isGLValue() ||
-      (A->getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus);
+  bool IsGLValueLike = A->isGLValue() ||
+    (A->getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus);
 
   for (auto *Node : CheckerPreStmt) {
     const LocationContext *LCtx = Node->getLocationContext();
@@ -3299,10 +3330,11 @@ void ExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr *A,
       if (T->isVoidType())
         T = getContext().CharTy;
 
-      SVal V = state->getLValue(T, state->getSVal(Idx, LCtx),
+      SVal V = state->getLValue(T,
+                                state->getSVal(Idx, LCtx),
                                 state->getSVal(Base, LCtx));
       Bldr.generateNode(A, Node, state->BindExpr(A, LCtx, V), nullptr,
-                        ProgramPoint::PostLValueKind);
+          ProgramPoint::PostLValueKind);
     } else if (IsVectorType) {
       // FIXME: non-glvalue vector reads are not modelled.
       Bldr.generateNode(A, Node, state, nullptr);
@@ -3377,8 +3409,8 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
         // pointers as soon as they are used.
         if (!M->isGLValue()) {
           assert(M->getType()->isArrayType());
-          const auto *PE = dyn_cast<ImplicitCastExpr>(
-              I->getParentMap().getParentIgnoreParens(M));
+          const auto *PE =
+            dyn_cast<ImplicitCastExpr>(I->getParentMap().getParentIgnoreParens(M));
           if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
             llvm_unreachable("should always be wrapped in ArrayToPointerDecay");
           }
@@ -3427,17 +3459,18 @@ void ExprEngine::VisitAtomicExpr(const AtomicExpr *AE, ExplodedNode *Pred,
     }
 
     State = State->invalidateRegions(ValuesToInvalidate, AE,
-                                     currBldrCtx->blockCount(), LCtx,
-                                     /*CausedByPointerEscape*/ true,
-                                     /*Symbols=*/nullptr);
+                                    currBldrCtx->blockCount(),
+                                    LCtx,
+                                    /*CausedByPointerEscape*/true,
+                                    /*Symbols=*/nullptr);
 
     SVal ResultVal = UnknownVal();
     State = State->BindExpr(AE, LCtx, ResultVal);
-    Bldr.generateNode(AE, I, State, nullptr, ProgramPoint::PostStmtKind);
+    Bldr.generateNode(AE, I, State, nullptr,
+                      ProgramPoint::PostStmtKind);
   }
 
-  getCheckerManager().runCheckersForPostStmt(Dst, AfterInvalidateSet, AE,
-                                             *this);
+  getCheckerManager().runCheckersForPostStmt(Dst, AfterInvalidateSet, AE, *this);
 }
 
 // A value escapes in four possible cases:
@@ -3496,16 +3529,21 @@ ExprEngine::processPointerEscapedOnBind(ProgramStateRef State, SVal Loc,
                                      nullptr);
 }
 
-ProgramStateRef ExprEngine::notifyCheckersOfPointerEscape(
-    ProgramStateRef State, const InvalidatedSymbols *Invalidated,
-    ArrayRef<const MemRegion *> ExplicitRegions, const CallEvent *Call,
+ProgramStateRef
+ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State,
+    const InvalidatedSymbols *Invalidated,
+    ArrayRef<const MemRegion *> ExplicitRegions,
+    const CallEvent *Call,
     RegionAndSymbolInvalidationTraits &ITraits) {
   if (!Invalidated || Invalidated->empty())
     return State;
 
   if (!Call)
-    return getCheckerManager().runCheckersForPointerEscape(
-        State, *Invalidated, nullptr, PSK_EscapeOther, &ITraits);
+    return getCheckerManager().runCheckersForPointerEscape(State,
+                                                           *Invalidated,
+                                                           nullptr,
+                                                           PSK_EscapeOther,
+                                                           &ITraits);
 
   // If the symbols were invalidated by a call, we want to find out which ones
   // were invalidated directly due to being arguments to the call.
@@ -3523,15 +3561,13 @@ ProgramStateRef ExprEngine::notifyCheckersOfPointerEscape(
   }
 
   if (!SymbolsDirectlyInvalidated.empty())
-    State = getCheckerManager().runCheckersForPointerEscape(
-        State, SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall,
-        &ITraits);
+    State = getCheckerManager().runCheckersForPointerEscape(State,
+        SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall, &ITraits);
 
   // Notify about the symbols that get indirectly invalidated by the call.
   if (!SymbolsIndirectlyInvalidated.empty())
-    State = getCheckerManager().runCheckersForPointerEscape(
-        State, SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall,
-        &ITraits);
+    State = getCheckerManager().runCheckersForPointerEscape(State,
+        SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall, &ITraits);
 
   return State;
 }
@@ -3539,7 +3575,8 @@ ProgramStateRef ExprEngine::notifyCheckersOfPointerEscape(
 /// evalBind - Handle the semantics of binding a value to a specific location.
 ///  This method is used by evalStore and (soon) VisitDeclStmt, and others.
 void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
-                          ExplodedNode *Pred, SVal location, SVal Val,
+                          ExplodedNode *Pred,
+                          SVal location, SVal Val,
                           bool atDeclInit, const ProgramPoint *PP) {
   const LocationContext *LC = Pred->getLocationContext();
   PostStmt PS(StoreE, LC);
@@ -3556,8 +3593,8 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
   // If the location is not a 'Loc', it will already be handled by
   // the checkers.  There is nothing left to do.
   if (!isa<Loc>(location)) {
-    const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/ nullptr,
-                                     /*tag*/ nullptr);
+    const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/nullptr,
+                                     /*tag*/nullptr);
     ProgramStateRef state = Pred->getState();
     state = processPointerEscapedOnBind(state, location, Val, LC);
     Bldr.generateNode(L, state, Pred);
@@ -3572,8 +3609,8 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
     // When binding the value, pass on the hint that this is a initialization.
     // For initializations, we do not need to inform clients of region
     // changes.
-    state = state->bindLoc(location.castAs<Loc>(), Val, LC,
-                           /* notifyChanges = */ !atDeclInit);
+    state = state->bindLoc(location.castAs<Loc>(),
+                           Val, LC, /* notifyChanges = */ !atDeclInit);
 
     const MemRegion *LocReg = nullptr;
     if (std::optional<loc::MemRegionVal> LocRegVal =
@@ -3595,9 +3632,10 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
 ///  @param location The location to store the value
 ///  @param Val The value to be stored
 void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
-                           const Expr *LocationE, ExplodedNode *Pred,
-                           ProgramStateRef state, SVal location, SVal Val,
-                           const ProgramPointTag *tag) {
+                             const Expr *LocationE,
+                             ExplodedNode *Pred,
+                             ProgramStateRef state, SVal location, SVal Val,
+                             const ProgramPointTag *tag) {
   // Proceed with the store.  We use AssignE as the anchor for the PostStore
   // ProgramPoint if it is non-NULL, and LocationE otherwise.
   const Expr *StoreE = AssignE ? AssignE : LocationE;
@@ -3616,10 +3654,14 @@ void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
     evalBind(Dst, StoreE, I, location, Val, false);
 }
 
-void ExprEngine::evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx,
-                          const Expr *BoundEx, ExplodedNode *Pred,
-                          ProgramStateRef state, SVal location,
-                          const ProgramPointTag *tag, QualType LoadTy) {
+void ExprEngine::evalLoad(ExplodedNodeSet &Dst,
+                          const Expr *NodeEx,
+                          const Expr *BoundEx,
+                          ExplodedNode *Pred,
+                          ProgramStateRef state,
+                          SVal location,
+                          const ProgramPointTag *tag,
+                          QualType LoadTy) {
   assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
   assert(NodeEx);
   assert(BoundEx);
@@ -3650,9 +3692,12 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx,
   }
 }
 
-void ExprEngine::evalLocation(ExplodedNodeSet &Dst, const Stmt *NodeEx,
-                              const Stmt *BoundEx, ExplodedNode *Pred,
-                              ProgramStateRef state, SVal location,
+void ExprEngine::evalLocation(ExplodedNodeSet &Dst,
+                              const Stmt *NodeEx,
+                              const Stmt *BoundEx,
+                              ExplodedNode *Pred,
+                              ProgramStateRef state,
+                              SVal location,
                               bool isLoad) {
   StmtNodeBuilder BldrTop(Pred, Dst, *currBldrCtx);
   // Early checks for performance reason.
@@ -3677,17 +3722,18 @@ void ExprEngine::evalLocation(ExplodedNodeSet &Dst, const Stmt *NodeEx,
     Bldr.generateNode(NodeEx, Pred, state, &tag);
   }
   ExplodedNodeSet Tmp;
-  getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad, NodeEx,
-                                             BoundEx, *this);
+  getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad,
+                                             NodeEx, BoundEx, *this);
   BldrTop.addNodes(Tmp);
 }
 
-std::pair<const ProgramPointTag *, const ProgramPointTag *>
+std::pair<const ProgramPointTag *, const ProgramPointTag*>
 ExprEngine::geteagerlyAssumeBinOpBifurcationTags() {
-  static SimpleProgramPointTag eagerlyAssumeBinOpBifurcationTrue(
-      TagProviderName, "Eagerly Assume True"),
-      eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
-                                         "Eagerly Assume False");
+  static SimpleProgramPointTag
+         eagerlyAssumeBinOpBifurcationTrue(TagProviderName,
+                                           "Eagerly Assume True"),
+         eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
+                                            "Eagerly Assume False");
   return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
                         &eagerlyAssumeBinOpBifurcationFalse);
 }
@@ -3710,8 +3756,8 @@ void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
     SVal V = state->getSVal(Ex, Pred->getLocationContext());
     std::optional<nonloc::SymbolVal> SEV = V.getAs<nonloc::SymbolVal>();
     if (SEV && SEV->isExpression()) {
-      const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
-          geteagerlyAssumeBinOpBifurcationTags();
+      const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
+        geteagerlyAssumeBinOpBifurcationTags();
 
       ProgramStateRef StateTrue, StateFalse;
       std::tie(StateTrue, StateFalse) = state->assume(*SEV);
@@ -3768,14 +3814,13 @@ void ExprEngine::VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
 
 namespace llvm {
 
-template <>
-struct DOTGraphTraits<ExplodedGraph *> : public DefaultDOTGraphTraits {
-  DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
+template<>
+struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits {
+  DOTGraphTraits (bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
 
   static bool nodeHasBugReport(const ExplodedNode *N) {
     BugReporter &BR = static_cast<ExprEngine &>(
-                          N->getState()->getStateManager().getOwningEngine())
-                          .getBugReporter();
+      N->getState()->getStateManager().getOwningEngine()).getBugReporter();
 
     for (const auto &Class : BR.equivalenceClasses()) {
       for (const auto &Report : Class.getReports()) {
@@ -3818,7 +3863,7 @@ struct DOTGraphTraits<ExplodedGraph *> : public DefaultDOTGraphTraits {
     return N->isTrivial();
   }
 
-  static std::string getNodeLabel(const ExplodedNode *N, ExplodedGraph *G) {
+  static std::string getNodeLabel(const ExplodedNode *N, ExplodedGraph *G){
     std::string Buf;
     llvm::raw_string_ostream Out(Buf);
 
@@ -3826,7 +3871,8 @@ struct DOTGraphTraits<ExplodedGraph *> : public DefaultDOTGraphTraits {
     const unsigned int Space = 1;
     ProgramStateRef State = N->getState();
 
-    Out << "{ \"state_id\": " << State->getID() << ",\\l";
+    Out << "{ \"state_id\": " << State->getID()
+        << ",\\l";
 
     Indent(Out, Space, IsDot) << "\"program_points\": [\\l";
 
@@ -3841,9 +3887,9 @@ struct DOTGraphTraits<ExplodedGraph *> : public DefaultDOTGraphTraits {
             Out << '\"' << Tag->getTagDescription() << '\"';
           else
             Out << "null";
-          Out << ", \"node_id\": " << OtherNode->getID()
-              << ", \"is_sink\": " << OtherNode->isSink()
-              << ", \"has_report\": " << nodeHasBugReport(OtherNode) << " }";
+          Out << ", \"node_id\": " << OtherNode->getID() <<
+                 ", \"is_sink\": " << OtherNode->isSink() <<
+                 ", \"has_report\": " << nodeHasBugReport(OtherNode) << " }";
         },
         // Adds a comma and a new-line between each program point.
         [&](const ExplodedNode *) { Out << ",\\l"; },
@@ -3912,4 +3958,4 @@ void *ProgramStateTrait<ReplayWithoutInlining>::GDMIndex() {
   return &index;
 }
 
-void ExprEngine::anchor() {}
+void ExprEngine::anchor() { }

>From 32453aee0cb80d342a627505f3339b562630a13d Mon Sep 17 00:00:00 2001
From: T-Gruber <tobi.gruber at gmx.de>
Date: Thu, 13 Jun 2024 21:02:27 +0200
Subject: [PATCH 3/6] Removed unused locals in code snippets

---
 clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp b/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
index b5d25e98dba55..66cdac413301b 100644
--- a/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
+++ b/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
@@ -68,7 +68,6 @@ void addExprEngineVisitPostChecker(AnalysisASTConsumer &AnalysisConsumer,
 TEST(ExprEngineVisitTest, checkPreStmtGCCAsmStmt) {
   std::string Diags;
   EXPECT_TRUE(runCheckerOnCode<addExprEngineVisitPreChecker>(R"(
-    int a = 1;
     void top() {
       asm("");
     }
@@ -80,7 +79,6 @@ TEST(ExprEngineVisitTest, checkPreStmtGCCAsmStmt) {
 TEST(ExprEngineVisitTest, checkPostStmtGCCAsmStmt) {
   std::string Diags;
   EXPECT_TRUE(runCheckerOnCode<addExprEngineVisitPostChecker>(R"(
-    int a = 1;
     void top() {
       asm("");
     }

>From 945ac12275202e18e741bed63190f01baf2c2050 Mon Sep 17 00:00:00 2001
From: T-Gruber <tobi.gruber at gmx.de>
Date: Wed, 10 Jul 2024 10:35:36 +0200
Subject: [PATCH 4/6] Move break into braces

---
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 4bfa0a599da67..b541d8f637b21 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -2066,7 +2066,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
         VisitGCCAsmStmt(cast<GCCAsmStmt>(S), N, PostVisit);
       getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
       Bldr.addNodes(Dst);
-    } break;
+      break;
+    }
 
     case Stmt::MSAsmStmtClass:
       Bldr.takeNodes(Pred);

>From 28b646792249bad0a01d9724cc538df5d41736da Mon Sep 17 00:00:00 2001
From: T-Gruber <tobi.gruber at gmx.de>
Date: Wed, 10 Jul 2024 10:37:17 +0200
Subject: [PATCH 5/6] Adapted format of file header

---
 clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp b/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
index 66cdac413301b..e0006597f24d3 100644
--- a/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
+++ b/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
@@ -1,4 +1,4 @@
-//===- ExprEngineVisitTest.cpp -----------------------------------===//
+//===- ExprEngineVisitTest.cpp --------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+
 #include "CheckerRegistration.h"
 #include "clang/AST/Stmt.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"

>From 537c144979ce93befe25cabc8415446aba90ff81 Mon Sep 17 00:00:00 2001
From: T-Gruber <tobi.gruber at gmx.de>
Date: Wed, 10 Jul 2024 13:44:16 +0200
Subject: [PATCH 6/6] Reworked unittest

---
 .../StaticAnalyzer/ExprEngineVisitTest.cpp    | 38 +++++++++----------
 1 file changed, 17 insertions(+), 21 deletions(-)

diff --git a/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp b/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
index e0006597f24d3..a8579f9d0f90c 100644
--- a/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
+++ b/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-
 #include "CheckerRegistration.h"
 #include "clang/AST/Stmt.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
@@ -28,25 +27,22 @@ void emitErrorReport(CheckerContext &C, const BugType &Bug,
   }
 }
 
-class ExprEngineVisitPreChecker : public Checker<check::PreStmt<GCCAsmStmt>> {
-public:
-  void checkPreStmt(const GCCAsmStmt *ASM, CheckerContext &C) const {
-    emitErrorReport(C, Bug, "PreStmt<GCCAsmStmt>");
-  }
-
-private:
-  const BugType Bug{this, "GCCAsmStmtBug"};
-};
-
-class ExprEngineVisitPostChecker : public Checker<check::PostStmt<GCCAsmStmt>> {
-public:
-  void checkPostStmt(const GCCAsmStmt *ASM, CheckerContext &C) const {
-    emitErrorReport(C, Bug, "PostStmt<GCCAsmStmt>");
-  }
+#define CREATE_EXPR_ENGINE_CHECKER(CHECKER_NAME, CALLBACK, STMT_TYPE,          \
+                                   BUG_NAME)                                   \
+  class CHECKER_NAME : public Checker<check::CALLBACK<STMT_TYPE>> {            \
+  public:                                                                      \
+    void check##CALLBACK(const STMT_TYPE *ASM, CheckerContext &C) const {      \
+      emitErrorReport(C, Bug, "check" #CALLBACK "<" #STMT_TYPE ">");           \
+    }                                                                          \
+                                                                               \
+  private:                                                                     \
+    const BugType Bug{this, BUG_NAME};                                         \
+  };
 
-private:
-  const BugType Bug{this, "GCCAsmStmtBug"};
-};
+CREATE_EXPR_ENGINE_CHECKER(ExprEngineVisitPreChecker, PreStmt, GCCAsmStmt,
+                           "GCCAsmStmtBug")
+CREATE_EXPR_ENGINE_CHECKER(ExprEngineVisitPostChecker, PostStmt, GCCAsmStmt,
+                           "GCCAsmStmtBug")
 
 void addExprEngineVisitPreChecker(AnalysisASTConsumer &AnalysisConsumer,
                                   AnalyzerOptions &AnOpts) {
@@ -74,7 +70,7 @@ TEST(ExprEngineVisitTest, checkPreStmtGCCAsmStmt) {
     }
   )",
                                                              Diags));
-  EXPECT_EQ(Diags, "ExprEngineVisitPreChecker: PreStmt<GCCAsmStmt>\n");
+  EXPECT_EQ(Diags, "ExprEngineVisitPreChecker: checkPreStmt<GCCAsmStmt>\n");
 }
 
 TEST(ExprEngineVisitTest, checkPostStmtGCCAsmStmt) {
@@ -85,7 +81,7 @@ TEST(ExprEngineVisitTest, checkPostStmtGCCAsmStmt) {
     }
   )",
                                                               Diags));
-  EXPECT_EQ(Diags, "ExprEngineVisitPostChecker: PostStmt<GCCAsmStmt>\n");
+  EXPECT_EQ(Diags, "ExprEngineVisitPostChecker: checkPostStmt<GCCAsmStmt>\n");
 }
 
 } // namespace



More information about the cfe-commits mailing list