https://github.com/mxms0 created 
https://github.com/llvm/llvm-project/pull/176466

This PR adds support for toggling on/off warnings around static sized arrays. 
This supports / addresses https://github.com/llvm/llvm-project/issues/87284, 
for those who use -fsanitize=array-bounds which inserts checks for fixed sized 
arrays already.

>From 19944e88d79b1b8ebcc0bf343f251b52d8cc1868 Mon Sep 17 00:00:00 2001
From: mxms <[email protected]>
Date: Fri, 16 Jan 2026 19:33:44 +0000
Subject: [PATCH 1/4] [clang][-Wunsafe-buffer-usage] Add flag support for
 -Wunsafe-buffer-usage-in-static-sized-arrays

---
 .../Analysis/Analyses/UnsafeBufferUsage.h     |   5 +
 .../Analyses/UnsafeBufferUsageGadgets.def     |   2 +-
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +-
 .../clang/Basic/DiagnosticSemaKinds.td        |   2 +
 clang/lib/Analysis/UnsafeBufferUsage.cpp      |  19 +-
 clang/lib/Sema/AnalysisBasedWarnings.cpp      | 621 +++++++++---------
 6 files changed, 334 insertions(+), 318 deletions(-)

diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h 
b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
index ea41eb3becfcf..462dabcc41da7 100644
--- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
+++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
@@ -178,6 +178,11 @@ class UnsafeBufferUsageHandler {
   virtual bool
   ignoreUnsafeBufferInLibcCall(const SourceLocation &Loc) const = 0;
 
+  /// \return true iff array subscript accesses on fixed size arrays should NOT
+  /// be reported at `Loc`
+  virtual bool
+  ignoreUnsafeBufferInStaticSizedArray(const SourceLocation &Loc) const = 0;
+
   virtual std::string
   getUnsafeBufferUsageAttributeTextAt(SourceLocation Loc,
                                       StringRef WSSuffix = "") const = 0;
diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def 
b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
index f9bba5d54e9c7..129ce95c1c0e0 100644
--- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
+++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
@@ -33,12 +33,12 @@
 
 WARNING_GADGET(Increment)
 WARNING_GADGET(Decrement)
-WARNING_GADGET(ArraySubscript)
 WARNING_GADGET(PointerArithmetic)
 WARNING_GADGET(UnsafeBufferUsageAttr)
 WARNING_GADGET(UnsafeBufferUsageCtorAttr)
 WARNING_GADGET(DataInvocation)
 WARNING_GADGET(UniquePtrArrayAccess)
+WARNING_OPTIONAL_GADGET(ArraySubscript)
 WARNING_OPTIONAL_GADGET(UnsafeLibcFunctionCall)
 WARNING_OPTIONAL_GADGET(UnsafeFormatAttributedFunctionCall)
 WARNING_OPTIONAL_GADGET(SpanTwoParamConstructor) // Uses of `std::span(arg0, 
arg1)`
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 3764475fbd3df..f4717505e1bdd 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1774,7 +1774,8 @@ def ReadOnlyPlacementChecks : 
DiagGroup<"read-only-types">;
 def UnsafeBufferUsageInContainer : 
DiagGroup<"unsafe-buffer-usage-in-container">;
 def UnsafeBufferUsageInLibcCall : 
DiagGroup<"unsafe-buffer-usage-in-libc-call">;
 def UnsafeBufferUsageInUniquePtrArrayAccess : 
DiagGroup<"unsafe-buffer-usage-in-unique-ptr-array-access">;
-def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", 
[UnsafeBufferUsageInContainer, UnsafeBufferUsageInLibcCall, 
UnsafeBufferUsageInUniquePtrArrayAccess]>;
+def UnsafeBufferUsageInStaticSizedArray : 
DiagGroup<"unsafe-buffer-usage-in-static-sized-array">;
+def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", 
[UnsafeBufferUsageInContainer, UnsafeBufferUsageInLibcCall, 
UnsafeBufferUsageInUniquePtrArrayAccess, UnsafeBufferUsageInStaticSizedArray]>;
 
 // Warnings and notes InstallAPI verification.
 def InstallAPIViolation : DiagGroup<"installapi-violation">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index eb7a608f798b8..1ab3f537d36a3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13472,6 +13472,8 @@ def warn_unsafe_buffer_usage_in_container : Warning<
   InGroup<UnsafeBufferUsageInContainer>, DefaultIgnore;
 def warn_unsafe_buffer_usage_unique_ptr_array_access : Warning<"direct access 
using operator[] on std::unique_ptr<T[]> is unsafe due to lack of bounds 
checking">,
   InGroup<UnsafeBufferUsageInUniquePtrArrayAccess>, DefaultIgnore;
+def warn_unsafe_buffer_usage_in_static_sized_array : Warning<"direct access on 
T[N] is unsafe due to the lack of bounds checking">,
+  InGroup<UnsafeBufferUsageInStaticSizedArray>, DefaultIgnore;
 #ifndef NDEBUG
 // Not a user-facing diagnostic. Useful for debugging false negatives in
 // -fsafe-buffer-usage-suggestions (i.e. lack of -Wunsafe-buffer-usage fixits).
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp 
b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 6bb08102c0345..d7df7d8d46b61 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -667,7 +667,8 @@ static bool isSafeSpanTwoParamConstruct(const 
CXXConstructExpr &Node,
 }
 
 static bool isSafeArraySubscript(const ArraySubscriptExpr &Node,
-                                 const ASTContext &Ctx) {
+                                 const ASTContext &Ctx,
+                                 const bool IgnoreStaticSizedArrays) {
   // FIXME: Proper solution:
   //  - refactor Sema::CheckArrayAccess
   //    - split safe/OOB/unknown decision logic from diagnostics emitting code
@@ -689,6 +690,12 @@ static bool isSafeArraySubscript(const ArraySubscriptExpr 
&Node,
     return false;
   }
 
+  if (IgnoreStaticSizedArrays) {
+    // If we made it here, it means a size was found for the var being
+    // accessed. If it's fixed size, we can ignore it.
+    return true;
+  }
+
   Expr::EvalResult EVResult;
   const Expr *IndexExpr = Node.getIdx();
   if (!IndexExpr->isValueDependent() &&
@@ -1568,6 +1575,7 @@ class ArraySubscriptGadget : public WarningGadget {
   }
 
   static bool matches(const Stmt *S, const ASTContext &Ctx,
+                      const UnsafeBufferUsageHandler *Handler,
                       MatchResult &Result) {
     const auto *ASE = dyn_cast<ArraySubscriptExpr>(S);
     if (!ASE)
@@ -1578,7 +1586,10 @@ class ArraySubscriptGadget : public WarningGadget {
     const auto *Idx = dyn_cast<IntegerLiteral>(ASE->getIdx());
     bool IsSafeIndex = (Idx && Idx->getValue().isZero()) ||
                        isa<ArrayInitIndexExpr>(ASE->getIdx());
-    if (IsSafeIndex || isSafeArraySubscript(*ASE, Ctx))
+    if (IsSafeIndex ||
+        isSafeArraySubscript(
+            *ASE, Ctx,
+            Handler->ignoreUnsafeBufferInStaticSizedArray(S->getBeginLoc())))
       return false;
     Result.addNode(ArraySubscrTag, DynTypedNode::create(*ASE));
     return true;
@@ -2888,6 +2899,10 @@ std::set<const Expr *> clang::findUnsafePointers(const 
FunctionDecl *FD) {
     bool ignoreUnsafeBufferInLibcCall(const SourceLocation &) const override {
       return false;
     }
+    bool ignoreUnsafeBufferInStaticSizedArray(
+        const SourceLocation &Loc) const override {
+      return false;
+    }
     std::string getUnsafeBufferUsageAttributeTextAt(
         SourceLocation, StringRef WSSuffix = "") const override {
       return "";
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp 
b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 56d7db649afbe..437397d3126c2 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -67,61 +67,60 @@ using namespace clang;
 
//===----------------------------------------------------------------------===//
 
 namespace {
-  class UnreachableCodeHandler : public reachable_code::Callback {
-    Sema &S;
-    SourceRange PreviousSilenceableCondVal;
-
-  public:
-    UnreachableCodeHandler(Sema &s) : S(s) {}
-
-    void HandleUnreachable(reachable_code::UnreachableKind UK, SourceLocation 
L,
-                           SourceRange SilenceableCondVal, SourceRange R1,
-                           SourceRange R2, bool HasFallThroughAttr) override {
-      // If the diagnosed code is `[[fallthrough]];` and
-      // `-Wunreachable-code-fallthrough` is  enabled, suppress `code will 
never
-      // be executed` warning to avoid generating diagnostic twice
-      if (HasFallThroughAttr &&
-          
!S.getDiagnostics().isIgnored(diag::warn_unreachable_fallthrough_attr,
-                                        SourceLocation()))
-        return;
+class UnreachableCodeHandler : public reachable_code::Callback {
+  Sema &S;
+  SourceRange PreviousSilenceableCondVal;
 
-      // Avoid reporting multiple unreachable code diagnostics that are
-      // triggered by the same conditional value.
-      if (PreviousSilenceableCondVal.isValid() &&
-          SilenceableCondVal.isValid() &&
-          PreviousSilenceableCondVal == SilenceableCondVal)
-        return;
-      PreviousSilenceableCondVal = SilenceableCondVal;
+public:
+  UnreachableCodeHandler(Sema &s) : S(s) {}
+
+  void HandleUnreachable(reachable_code::UnreachableKind UK, SourceLocation L,
+                         SourceRange SilenceableCondVal, SourceRange R1,
+                         SourceRange R2, bool HasFallThroughAttr) override {
+    // If the diagnosed code is `[[fallthrough]];` and
+    // `-Wunreachable-code-fallthrough` is  enabled, suppress `code will never
+    // be executed` warning to avoid generating diagnostic twice
+    if (HasFallThroughAttr &&
+        !S.getDiagnostics().isIgnored(diag::warn_unreachable_fallthrough_attr,
+                                      SourceLocation()))
+      return;
 
-      unsigned diag = diag::warn_unreachable;
-      switch (UK) {
-        case reachable_code::UK_Break:
-          diag = diag::warn_unreachable_break;
-          break;
-        case reachable_code::UK_Return:
-          diag = diag::warn_unreachable_return;
-          break;
-        case reachable_code::UK_Loop_Increment:
-          diag = diag::warn_unreachable_loop_increment;
-          break;
-        case reachable_code::UK_Other:
-          break;
-      }
+    // Avoid reporting multiple unreachable code diagnostics that are
+    // triggered by the same conditional value.
+    if (PreviousSilenceableCondVal.isValid() && SilenceableCondVal.isValid() &&
+        PreviousSilenceableCondVal == SilenceableCondVal)
+      return;
+    PreviousSilenceableCondVal = SilenceableCondVal;
+
+    unsigned diag = diag::warn_unreachable;
+    switch (UK) {
+    case reachable_code::UK_Break:
+      diag = diag::warn_unreachable_break;
+      break;
+    case reachable_code::UK_Return:
+      diag = diag::warn_unreachable_return;
+      break;
+    case reachable_code::UK_Loop_Increment:
+      diag = diag::warn_unreachable_loop_increment;
+      break;
+    case reachable_code::UK_Other:
+      break;
+    }
 
-      S.Diag(L, diag) << R1 << R2;
+    S.Diag(L, diag) << R1 << R2;
 
-      SourceLocation Open = SilenceableCondVal.getBegin();
-      if (Open.isValid()) {
-        SourceLocation Close = SilenceableCondVal.getEnd();
-        Close = S.getLocForEndOfToken(Close);
-        if (Close.isValid()) {
-          S.Diag(Open, diag::note_unreachable_silence)
+    SourceLocation Open = SilenceableCondVal.getBegin();
+    if (Open.isValid()) {
+      SourceLocation Close = SilenceableCondVal.getEnd();
+      Close = S.getLocForEndOfToken(Close);
+      if (Close.isValid()) {
+        S.Diag(Open, diag::note_unreachable_silence)
             << FixItHint::CreateInsertion(Open, "/* DISABLES CODE */ (")
             << FixItHint::CreateInsertion(Close, ")");
-        }
       }
     }
-  };
+  }
+};
 } // anonymous namespace
 
 /// CheckUnreachable - Check for unreachable code.
@@ -291,7 +290,8 @@ static void checkRecursiveFunction(Sema &S, const 
FunctionDecl *FD,
     return;
 
   CFG *cfg = AC.getCFG();
-  if (!cfg) return;
+  if (!cfg)
+    return;
 
   // If the exit block is unreachable, skip processing the function.
   if (cfg->getExit().pred_empty())
@@ -326,10 +326,9 @@ static bool throwEscapes(Sema &S, const CXXThrowExpr *E, 
CFGBlock &ThrowBlock,
       if (Succ->getBlockID() == Body->getExit().getBlockID())
         return true;
 
-      if (auto *Catch =
-              dyn_cast_or_null<CXXCatchStmt>(Succ->getLabel())) {
+      if (auto *Catch = dyn_cast_or_null<CXXCatchStmt>(Succ->getLabel())) {
         QualType Caught = Catch->getCaughtType();
-        if (Caught.isNull() || // catch (...) catches everything
+        if (Caught.isNull() ||  // catch (...) catches everything
             !E->getSubExpr() || // throw; is considered cuaght by any handler
             S.handlerCanCatch(Caught, E->getSubExpr()->getType()))
           // Exception doesn't escape via this path.
@@ -348,7 +347,8 @@ static void visitReachableThrows(
     CFG *BodyCFG,
     llvm::function_ref<void(const CXXThrowExpr *, CFGBlock &)> Visit) {
   llvm::BitVector Reachable(BodyCFG->getNumBlockIDs());
-  clang::reachable_code::ScanReachableFromBlock(&BodyCFG->getEntry(), 
Reachable);
+  clang::reachable_code::ScanReachableFromBlock(&BodyCFG->getEntry(),
+                                                Reachable);
   for (CFGBlock *B : *BodyCFG) {
     if (!Reachable[B->getBlockID()])
       continue;
@@ -371,8 +371,8 @@ static void EmitDiagForCXXThrowInNonThrowingFunc(Sema &S, 
SourceLocation OpLoc,
         (isa<CXXDestructorDecl>(FD) ||
          FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
          FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete)) {
-      if (const auto *Ty = FD->getTypeSourceInfo()->getType()->
-                                         getAs<FunctionProtoType>())
+      if (const auto *Ty =
+              FD->getTypeSourceInfo()->getType()->getAs<FunctionProtoType>())
         S.Diag(FD->getLocation(), diag::note_throw_in_dtor)
             << !isa<CXXDestructorDecl>(FD) << !Ty->hasExceptionSpec()
             << FD->getExceptionSpecSourceRange();
@@ -389,10 +389,11 @@ static void checkThrowInNonThrowingFunc(Sema &S, const 
FunctionDecl *FD,
     return;
   if (BodyCFG->getExit().pred_empty())
     return;
-  visitReachableThrows(BodyCFG, [&](const CXXThrowExpr *Throw, CFGBlock 
&Block) {
-    if (throwEscapes(S, Throw, Block, BodyCFG))
-      EmitDiagForCXXThrowInNonThrowingFunc(S, Throw->getThrowLoc(), FD);
-  });
+  visitReachableThrows(
+      BodyCFG, [&](const CXXThrowExpr *Throw, CFGBlock &Block) {
+        if (throwEscapes(S, Throw, Block, BodyCFG))
+          EmitDiagForCXXThrowInNonThrowingFunc(S, Throw->getThrowLoc(), FD);
+      });
 }
 
 static bool isNoexcept(const FunctionDecl *FD) {
@@ -565,13 +566,14 @@ enum ControlFlowKind {
 /// will return.
 static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) {
   CFG *cfg = AC.getCFG();
-  if (!cfg) return UnknownFallThrough;
+  if (!cfg)
+    return UnknownFallThrough;
 
   // The CFG leaves in dead things, and we don't want the dead code paths to
   // confuse us, so we mark all live things first.
   llvm::BitVector live(cfg->getNumBlockIDs());
-  unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(),
-                                                          live);
+  unsigned count =
+      reachable_code::ScanReachableFromBlock(&cfg->getEntry(), live);
 
   bool AddEHEdges = AC.getAddEHEdges();
   if (!AddEHEdges && count != cfg->getNumBlockIDs())
@@ -624,7 +626,7 @@ static ControlFlowKind CheckFallThrough(AnalysisDeclContext 
&AC) {
     // statement (if it exists).
     CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend();
 
-    for ( ; ri != re ; ++ri)
+    for (; ri != re; ++ri)
       if (ri->getAs<CFGStmt>())
         break;
 
@@ -798,14 +800,12 @@ static void CheckFallThroughForBody(Sema &S, const Decl 
*D, const Stmt *Body,
     else
       ReturnsVoid = FD->getReturnType()->isVoidType();
     HasNoReturn = FD->isNoReturn() || FD->hasAttr<InferredNoReturnAttr>();
-  }
-  else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
+  } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
     ReturnsVoid = MD->getReturnType()->isVoidType();
     HasNoReturn = MD->hasAttr<NoReturnAttr>();
-  }
-  else if (isa<BlockDecl>(D)) {
+  } else if (isa<BlockDecl>(D)) {
     if (const FunctionType *FT =
-          BlockType->getPointeeType()->getAs<FunctionType>()) {
+            BlockType->getPointeeType()->getAs<FunctionType>()) {
       if (FT->getReturnType()->isVoidType())
         ReturnsVoid = true;
       if (FT->getNoReturnAttr())
@@ -817,7 +817,7 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, 
const Stmt *Body,
 
   // Short circuit for compilation speed.
   if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
-      return;
+    return;
   SourceLocation LBrace = Body->getBeginLoc(), RBrace = Body->getEndLoc();
 
   // cpu_dispatch functions permit empty function bodies for ICC compatibility.
@@ -894,7 +894,7 @@ class ContainsReference : public 
ConstEvaluatedExprVisitor<ContainsReference> {
   typedef ConstEvaluatedExprVisitor<ContainsReference> Inherited;
 
   ContainsReference(ASTContext &Context, const DeclRefExpr *Needle)
-    : Inherited(Context), FoundReference(false), Needle(Needle) {}
+      : Inherited(Context), FoundReference(false), Needle(Needle) {}
 
   void VisitExpr(const Expr *E) {
     // Stop evaluating if we already have a reference.
@@ -917,8 +917,7 @@ class ContainsReference : public 
ConstEvaluatedExprVisitor<ContainsReference> {
 
 static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
   QualType VariableTy = VD->getType().getCanonicalType();
-  if (VariableTy->isBlockPointerType() &&
-      !VD->hasAttr<BlocksAttr>()) {
+  if (VariableTy->isBlockPointerType() && !VD->hasAttr<BlocksAttr>()) {
     S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization)
         << VD->getDeclName()
         << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
@@ -940,16 +939,16 @@ static bool SuggestInitializationFixit(Sema &S, const 
VarDecl *VD) {
   if (Init.empty())
     return false;
 
-  S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
-    << FixItHint::CreateInsertion(Loc, Init);
+  S.Diag(Loc, diag::note_var_fixit_add_initialization)
+      << VD->getDeclName() << FixItHint::CreateInsertion(Loc, Init);
   return true;
 }
 
 /// Create a fixit to remove an if-like statement, on the assumption that its
 /// condition is CondVal.
 static void CreateIfFixit(Sema &S, const Stmt *If, const Stmt *Then,
-                          const Stmt *Else, bool CondVal,
-                          FixItHint &Fixit1, FixItHint &Fixit2) {
+                          const Stmt *Else, bool CondVal, FixItHint &Fixit1,
+                          FixItHint &Fixit2) {
   if (CondVal) {
     // If condition is always true, remove all but the 'then'.
     Fixit1 = FixItHint::CreateRemoval(
@@ -1016,9 +1015,9 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, 
const UninitUse &Use,
     // For all binary terminators, branch 0 is taken if the condition is true,
     // and branch 1 is taken if the condition is false.
     int RemoveDiagKind = -1;
-    const char *FixitStr =
-        S.getLangOpts().CPlusPlus ? (I->Output ? "true" : "false")
-                                  : (I->Output ? "1" : "0");
+    const char *FixitStr = S.getLangOpts().CPlusPlus
+                               ? (I->Output ? "true" : "false")
+                               : (I->Output ? "1" : "0");
     FixItHint Fixit1, Fixit2;
 
     switch (Term ? Term->getStmtClass() : Stmt::DeclStmtClass) {
@@ -1034,8 +1033,8 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, 
const UninitUse &Use,
       Str = "if";
       Range = IS->getCond()->getSourceRange();
       RemoveDiagKind = 0;
-      CreateIfFixit(S, IS, IS->getThen(), IS->getElse(),
-                    I->Output, Fixit1, Fixit2);
+      CreateIfFixit(S, IS, IS->getThen(), IS->getElse(), I->Output, Fixit1,
+                    Fixit2);
       break;
     }
     case Stmt::ConditionalOperatorClass: {
@@ -1044,8 +1043,8 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, 
const UninitUse &Use,
       Str = "?:";
       Range = CO->getCond()->getSourceRange();
       RemoveDiagKind = 0;
-      CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(),
-                    I->Output, Fixit1, Fixit2);
+      CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(), I->Output,
+                    Fixit1, Fixit2);
       break;
     }
     case Stmt::BinaryOperatorClass: {
@@ -1120,13 +1119,13 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, 
const UninitUse &Use,
     }
 
     S.Diag(Range.getBegin(), diag::warn_sometimes_uninit_var)
-      << VD->getDeclName() << IsCapturedByBlock << DiagKind
-      << Str << I->Output << Range;
+        << VD->getDeclName() << IsCapturedByBlock << DiagKind << Str
+        << I->Output << Range;
     S.Diag(User->getBeginLoc(), diag::note_uninit_var_use)
         << IsCapturedByBlock << User->getSourceRange();
     if (RemoveDiagKind != -1)
       S.Diag(Fixit1.RemoveRange.getBegin(), 
diag::note_uninit_fixit_remove_cond)
-        << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2;
+          << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2;
 
     Diagnosed = true;
   }
@@ -1296,32 +1295,32 @@ class FallthroughMapper : public 
DynamicRecursiveASTVisitor {
             // Don't care about other unreachable statements.
           }
         }
-          // If there are no unreachable statements, this may be a special
-          // case in CFG:
-          // case X: {
-          //    A a;  // A has a destructor.
-          //    break;
-          // }
-          // // <<<< This place is represented by a 'hanging' CFG block.
-          // case Y:
-          continue;
+        // If there are no unreachable statements, this may be a special
+        // case in CFG:
+        // case X: {
+        //    A a;  // A has a destructor.
+        //    break;
+        // }
+        // // <<<< This place is represented by a 'hanging' CFG block.
+        // case Y:
+        continue;
       }
 
-        const Stmt *LastStmt = getLastStmt(*P);
-        if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
-          markFallthroughVisited(AS);
-          ++AnnotatedCnt;
-          continue; // Fallthrough annotation, good.
-        }
+      const Stmt *LastStmt = getLastStmt(*P);
+      if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
+        markFallthroughVisited(AS);
+        ++AnnotatedCnt;
+        continue; // Fallthrough annotation, good.
+      }
 
-        if (!LastStmt) { // This block contains no executable statements.
-          // Traverse its predecessors.
-          std::copy(P->pred_begin(), P->pred_end(),
-                    std::back_inserter(BlockQueue));
-          continue;
-        }
+      if (!LastStmt) { // This block contains no executable statements.
+        // Traverse its predecessors.
+        std::copy(P->pred_begin(), P->pred_end(),
+                  std::back_inserter(BlockQueue));
+        continue;
+      }
 
-        ++UnannotatedCnt;
+      ++UnannotatedCnt;
     }
     return !!UnannotatedCnt;
   }
@@ -1337,64 +1336,63 @@ class FallthroughMapper : public 
DynamicRecursiveASTVisitor {
     return true;
   }
 
-    // We don't want to traverse local type declarations. We analyze their
-    // methods separately.
-    bool TraverseDecl(Decl *D) override { return true; }
-
-    // We analyze lambda bodies separately. Skip them here.
-    bool TraverseLambdaExpr(LambdaExpr *LE) override {
-      // Traverse the captures, but not the body.
-      for (const auto C : zip(LE->captures(), LE->capture_inits()))
-        TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
-      return true;
-    }
+  // We don't want to traverse local type declarations. We analyze their
+  // methods separately.
+  bool TraverseDecl(Decl *D) override { return true; }
 
-  private:
+  // We analyze lambda bodies separately. Skip them here.
+  bool TraverseLambdaExpr(LambdaExpr *LE) override {
+    // Traverse the captures, but not the body.
+    for (const auto C : zip(LE->captures(), LE->capture_inits()))
+      TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
+    return true;
+  }
 
-    static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
-      if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {
-        if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
-          return AS;
-      }
-      return nullptr;
+private:
+  static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
+    if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {
+      if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
+        return AS;
     }
+    return nullptr;
+  }
 
-    static const Stmt *getLastStmt(const CFGBlock &B) {
-      if (const Stmt *Term = B.getTerminatorStmt())
-        return Term;
-      for (const CFGElement &Elem : llvm::reverse(B))
-        if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>())
-          return CS->getStmt();
-      // Workaround to detect a statement thrown out by CFGBuilder:
-      //   case X: {} case Y:
-      //   case X: ; case Y:
-      if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))
-        if (!isa<SwitchCase>(SW->getSubStmt()))
-          return SW->getSubStmt();
+  static const Stmt *getLastStmt(const CFGBlock &B) {
+    if (const Stmt *Term = B.getTerminatorStmt())
+      return Term;
+    for (const CFGElement &Elem : llvm::reverse(B))
+      if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>())
+        return CS->getStmt();
+    // Workaround to detect a statement thrown out by CFGBuilder:
+    //   case X: {} case Y:
+    //   case X: ; case Y:
+    if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))
+      if (!isa<SwitchCase>(SW->getSubStmt()))
+        return SW->getSubStmt();
 
-      return nullptr;
-    }
+    return nullptr;
+  }
 
-    bool FoundSwitchStatements;
-    AttrStmts FallthroughStmts;
-    Sema &S;
-    llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
+  bool FoundSwitchStatements;
+  AttrStmts FallthroughStmts;
+  Sema &S;
+  llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
 };
 } // anonymous namespace
 
 static StringRef getFallthroughAttrSpelling(Preprocessor &PP,
                                             SourceLocation Loc) {
-  TokenValue FallthroughTokens[] = {
-    tok::l_square, tok::l_square,
-    PP.getIdentifierInfo("fallthrough"),
-    tok::r_square, tok::r_square
-  };
-
-  TokenValue ClangFallthroughTokens[] = {
-    tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"),
-    tok::coloncolon, PP.getIdentifierInfo("fallthrough"),
-    tok::r_square, tok::r_square
-  };
+  TokenValue FallthroughTokens[] = {tok::l_square, tok::l_square,
+                                    PP.getIdentifierInfo("fallthrough"),
+                                    tok::r_square, tok::r_square};
+
+  TokenValue ClangFallthroughTokens[] = {tok::l_square,
+                                         tok::l_square,
+                                         PP.getIdentifierInfo("clang"),
+                                         tok::coloncolon,
+                                         PP.getIdentifierInfo("fallthrough"),
+                                         tok::r_square,
+                                         tok::r_square};
 
   bool PreferClangAttr = !PP.getLangOpts().CPlusPlus17 && 
!PP.getLangOpts().C23;
 
@@ -1509,13 +1507,12 @@ static bool isInLoop(const ASTContext &Ctx, const 
ParentMap &PM,
 
 static void diagnoseRepeatedUseOfWeak(Sema &S,
                                       const sema::FunctionScopeInfo *CurFn,
-                                      const Decl *D,
-                                      const ParentMap &PM) {
+                                      const Decl *D, const ParentMap &PM) {
   typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy;
   typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap;
   typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector;
   typedef std::pair<const Stmt *, WeakObjectUseMap::const_iterator>
-  StmtUsesPair;
+      StmtUsesPair;
 
   ASTContext &Ctx = S.getASTContext();
 
@@ -1529,7 +1526,7 @@ static void diagnoseRepeatedUseOfWeak(Sema &S,
 
     // Find the first read of the weak object.
     WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end();
-    for ( ; UI != UE; ++UI) {
+    for (; UI != UE; ++UI) {
       if (UI->isUnsafe())
         break;
     }
@@ -1586,12 +1583,7 @@ static void diagnoseRepeatedUseOfWeak(Sema &S,
   // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.
   // FIXME: Should we use a common classification enum and the same set of
   // possibilities all throughout Sema?
-  enum {
-    Function,
-    Method,
-    Block,
-    Lambda
-  } FunctionKind;
+  enum { Function, Method, Block, Lambda } FunctionKind;
 
   if (isa<sema::BlockScopeInfo>(CurFn))
     FunctionKind = Block;
@@ -1622,12 +1614,7 @@ static void diagnoseRepeatedUseOfWeak(Sema &S,
     // Classify the weak object being accessed for better warning text.
     // This enum should stay in sync with the cases in
     // warn_arc_repeated_use_of_weak and 
warn_arc_possible_repeated_use_of_weak.
-    enum {
-      Variable,
-      Property,
-      ImplicitProperty,
-      Ivar
-    } ObjectKind;
+    enum { Variable, Property, ImplicitProperty, Ivar } ObjectKind;
 
     const NamedDecl *KeyProp = Key.getProperty();
     if (isa<VarDecl>(KeyProp))
@@ -1729,7 +1716,7 @@ class UninitValsDiagReporter : public 
UninitVariablesHandler {
   }
 
 private:
-  static bool hasAlwaysUninitializedUse(const UsesVec* vec) {
+  static bool hasAlwaysUninitializedUse(const UsesVec *vec) {
     return llvm::any_of(*vec, [](const UninitUse &U) {
       return U.getKind() == UninitUse::Always ||
              U.getKind() == UninitUse::AfterCall ||
@@ -1979,10 +1966,10 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
                : getNotes();
   }
 
- public:
+public:
   ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL)
-    : S(S), FunLocation(FL), FunEndLocation(FEL),
-      CurrentFunction(nullptr), Verbose(false) {}
+      : S(S), FunLocation(FL), FunEndLocation(FEL), CurrentFunction(nullptr),
+        Verbose(false) {}
 
   void setVerbose(bool b) { Verbose = b; }
 
@@ -2077,18 +2064,18 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
                                  bool ReentrancyMismatch) override {
     unsigned DiagID = 0;
     switch (LEK) {
-      case LEK_LockedSomePredecessors:
-        DiagID = diag::warn_lock_some_predecessors;
-        break;
-      case LEK_LockedSomeLoopIterations:
-        DiagID = diag::warn_expecting_lock_held_on_loop;
-        break;
-      case LEK_LockedAtEndOfFunction:
-        DiagID = diag::warn_no_unlock;
-        break;
-      case LEK_NotLockedAtEndOfFunction:
-        DiagID = diag::warn_expecting_locked;
-        break;
+    case LEK_LockedSomePredecessors:
+      DiagID = diag::warn_lock_some_predecessors;
+      break;
+    case LEK_LockedSomeLoopIterations:
+      DiagID = diag::warn_expecting_lock_held_on_loop;
+      break;
+    case LEK_LockedAtEndOfFunction:
+      DiagID = diag::warn_no_unlock;
+      break;
+    case LEK_NotLockedAtEndOfFunction:
+      DiagID = diag::warn_expecting_locked;
+      break;
     }
     if (LocEndOfScope.isInvalid())
       LocEndOfScope = FunEndLocation;
@@ -2134,7 +2121,7 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
       break;
     }
     PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
-      << D << getLockKindFromAccessKind(AK));
+                                         << D << 
getLockKindFromAccessKind(AK));
     Warnings.emplace_back(std::move(Warning), getNotes());
   }
 
@@ -2145,43 +2132,42 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
     unsigned DiagID = 0;
     if (PossibleMatch) {
       switch (POK) {
-        case POK_VarAccess:
-          DiagID = diag::warn_variable_requires_lock_precise;
-          break;
-        case POK_VarDereference:
-          DiagID = diag::warn_var_deref_requires_lock_precise;
-          break;
-        case POK_FunctionCall:
-          DiagID = diag::warn_fun_requires_lock_precise;
-          break;
-        case POK_PassByRef:
-          DiagID = diag::warn_guarded_pass_by_reference;
-          break;
-        case POK_PtPassByRef:
-          DiagID = diag::warn_pt_guarded_pass_by_reference;
-          break;
-        case POK_ReturnByRef:
-          DiagID = diag::warn_guarded_return_by_reference;
-          break;
-        case POK_PtReturnByRef:
-          DiagID = diag::warn_pt_guarded_return_by_reference;
-          break;
-        case POK_PassPointer:
-          DiagID = diag::warn_guarded_pass_pointer;
-          break;
-        case POK_PtPassPointer:
-          DiagID = diag::warn_pt_guarded_pass_pointer;
-          break;
-        case POK_ReturnPointer:
-          DiagID = diag::warn_guarded_return_pointer;
-          break;
-        case POK_PtReturnPointer:
-          DiagID = diag::warn_pt_guarded_return_pointer;
-          break;
+      case POK_VarAccess:
+        DiagID = diag::warn_variable_requires_lock_precise;
+        break;
+      case POK_VarDereference:
+        DiagID = diag::warn_var_deref_requires_lock_precise;
+        break;
+      case POK_FunctionCall:
+        DiagID = diag::warn_fun_requires_lock_precise;
+        break;
+      case POK_PassByRef:
+        DiagID = diag::warn_guarded_pass_by_reference;
+        break;
+      case POK_PtPassByRef:
+        DiagID = diag::warn_pt_guarded_pass_by_reference;
+        break;
+      case POK_ReturnByRef:
+        DiagID = diag::warn_guarded_return_by_reference;
+        break;
+      case POK_PtReturnByRef:
+        DiagID = diag::warn_pt_guarded_return_by_reference;
+        break;
+      case POK_PassPointer:
+        DiagID = diag::warn_guarded_pass_pointer;
+        break;
+      case POK_PtPassPointer:
+        DiagID = diag::warn_pt_guarded_pass_pointer;
+        break;
+      case POK_ReturnPointer:
+        DiagID = diag::warn_guarded_return_pointer;
+        break;
+      case POK_PtReturnPointer:
+        DiagID = diag::warn_pt_guarded_return_pointer;
+        break;
       }
-      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
-                                                       << D
-                                                       << LockName << LK);
+      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
+                                           << Kind << D << LockName << LK);
       PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match)
                                         << *PossibleMatch);
       if (Verbose && POK == POK_VarAccess) {
@@ -2193,43 +2179,42 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
         Warnings.emplace_back(std::move(Warning), getNotes(Note));
     } else {
       switch (POK) {
-        case POK_VarAccess:
-          DiagID = diag::warn_variable_requires_lock;
-          break;
-        case POK_VarDereference:
-          DiagID = diag::warn_var_deref_requires_lock;
-          break;
-        case POK_FunctionCall:
-          DiagID = diag::warn_fun_requires_lock;
-          break;
-        case POK_PassByRef:
-          DiagID = diag::warn_guarded_pass_by_reference;
-          break;
-        case POK_PtPassByRef:
-          DiagID = diag::warn_pt_guarded_pass_by_reference;
-          break;
-        case POK_ReturnByRef:
-          DiagID = diag::warn_guarded_return_by_reference;
-          break;
-        case POK_PtReturnByRef:
-          DiagID = diag::warn_pt_guarded_return_by_reference;
-          break;
-        case POK_PassPointer:
-          DiagID = diag::warn_guarded_pass_pointer;
-          break;
-        case POK_PtPassPointer:
-          DiagID = diag::warn_pt_guarded_pass_pointer;
-          break;
-        case POK_ReturnPointer:
-          DiagID = diag::warn_guarded_return_pointer;
-          break;
-        case POK_PtReturnPointer:
-          DiagID = diag::warn_pt_guarded_return_pointer;
-          break;
+      case POK_VarAccess:
+        DiagID = diag::warn_variable_requires_lock;
+        break;
+      case POK_VarDereference:
+        DiagID = diag::warn_var_deref_requires_lock;
+        break;
+      case POK_FunctionCall:
+        DiagID = diag::warn_fun_requires_lock;
+        break;
+      case POK_PassByRef:
+        DiagID = diag::warn_guarded_pass_by_reference;
+        break;
+      case POK_PtPassByRef:
+        DiagID = diag::warn_pt_guarded_pass_by_reference;
+        break;
+      case POK_ReturnByRef:
+        DiagID = diag::warn_guarded_return_by_reference;
+        break;
+      case POK_PtReturnByRef:
+        DiagID = diag::warn_pt_guarded_return_by_reference;
+        break;
+      case POK_PassPointer:
+        DiagID = diag::warn_guarded_pass_pointer;
+        break;
+      case POK_PtPassPointer:
+        DiagID = diag::warn_pt_guarded_pass_pointer;
+        break;
+      case POK_ReturnPointer:
+        DiagID = diag::warn_guarded_return_pointer;
+        break;
+      case POK_PtReturnPointer:
+        DiagID = diag::warn_pt_guarded_return_pointer;
+        break;
       }
-      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
-                                                       << D
-                                                       << LockName << LK);
+      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
+                                           << Kind << D << LockName << LK);
       if (Verbose && POK == POK_VarAccess) {
         PartialDiagnosticAt Note(D->getLocation(),
                                  S.PDiag(diag::note_guarded_by_declared_here));
@@ -2241,9 +2226,9 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
 
   void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,
                              SourceLocation Loc) override {
-    PartialDiagnosticAt Warning(Loc,
-        S.PDiag(diag::warn_acquire_requires_negative_cap)
-        << Kind << LockName << Neg);
+    PartialDiagnosticAt Warning(
+        Loc, S.PDiag(diag::warn_acquire_requires_negative_cap)
+                 << Kind << LockName << Neg);
     Warnings.emplace_back(std::move(Warning), getNotes());
   }
 
@@ -2263,22 +2248,20 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
 
   void handleLockAcquiredBefore(StringRef Kind, Name L1Name, Name L2Name,
                                 SourceLocation Loc) override {
-    PartialDiagnosticAt Warning(Loc,
-      S.PDiag(diag::warn_acquired_before) << Kind << L1Name << L2Name);
+    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_acquired_before)
+                                         << Kind << L1Name << L2Name);
     Warnings.emplace_back(std::move(Warning), getNotes());
   }
 
   void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) override {
-    PartialDiagnosticAt Warning(Loc,
-      S.PDiag(diag::warn_acquired_before_after_cycle) << L1Name);
+    PartialDiagnosticAt Warning(
+        Loc, S.PDiag(diag::warn_acquired_before_after_cycle) << L1Name);
     Warnings.emplace_back(std::move(Warning), getNotes());
   }
 
-  void enterFunction(const FunctionDecl* FD) override {
-    CurrentFunction = FD;
-  }
+  void enterFunction(const FunctionDecl *FD) override { CurrentFunction = FD; }
 
-  void leaveFunction(const FunctionDecl* FD) override {
+  void leaveFunction(const FunctionDecl *FD) override {
     CurrentFunction = nullptr;
   }
 };
@@ -2299,7 +2282,6 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
   DiagList Warnings;
 
 public:
-
   ConsumedWarningsHandler(Sema &S) : S(S) {}
 
   void emitDiagnostics() override {
@@ -2313,8 +2295,8 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
 
   void warnLoopStateMismatch(SourceLocation Loc,
                              StringRef VariableName) override {
-    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch) <<
-      VariableName);
+    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch)
+                                         << VariableName);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2324,9 +2306,9 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
                                         StringRef ExpectedState,
                                         StringRef ObservedState) override {
 
-    PartialDiagnosticAt Warning(Loc, S.PDiag(
-      diag::warn_param_return_typestate_mismatch) << VariableName <<
-        ExpectedState << ObservedState);
+    PartialDiagnosticAt Warning(
+        Loc, S.PDiag(diag::warn_param_return_typestate_mismatch)
+                 << VariableName << ExpectedState << ObservedState);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2334,16 +2316,18 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
   void warnParamTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
                                   StringRef ObservedState) override {
 
-    PartialDiagnosticAt Warning(Loc, S.PDiag(
-      diag::warn_param_typestate_mismatch) << ExpectedState << ObservedState);
+    PartialDiagnosticAt Warning(Loc,
+                                S.PDiag(diag::warn_param_typestate_mismatch)
+                                    << ExpectedState << ObservedState);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
 
   void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
                                               StringRef TypeName) override {
-    PartialDiagnosticAt Warning(Loc, S.PDiag(
-      diag::warn_return_typestate_for_unconsumable_type) << TypeName);
+    PartialDiagnosticAt Warning(
+        Loc, S.PDiag(diag::warn_return_typestate_for_unconsumable_type)
+                 << TypeName);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2351,8 +2335,9 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
   void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
                                    StringRef ObservedState) override {
 
-    PartialDiagnosticAt Warning(Loc, S.PDiag(
-      diag::warn_return_typestate_mismatch) << ExpectedState << ObservedState);
+    PartialDiagnosticAt Warning(Loc,
+                                S.PDiag(diag::warn_return_typestate_mismatch)
+                                    << ExpectedState << ObservedState);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2360,8 +2345,9 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
   void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State,
                                    SourceLocation Loc) override {
 
-    PartialDiagnosticAt Warning(Loc, S.PDiag(
-      diag::warn_use_of_temp_in_invalid_state) << MethodName << State);
+    PartialDiagnosticAt Warning(Loc,
+                                
S.PDiag(diag::warn_use_of_temp_in_invalid_state)
+                                    << MethodName << State);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2369,8 +2355,9 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
   void warnUseInInvalidState(StringRef MethodName, StringRef VariableName,
                              StringRef State, SourceLocation Loc) override {
 
-    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state) 
<<
-                                MethodName << VariableName << State);
+    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state)
+                                         << MethodName << VariableName
+                                         << State);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2386,7 +2373,7 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
 namespace {
 class UnsafeBufferUsageReporter : public UnsafeBufferUsageHandler {
   Sema &S;
-  bool SuggestSuggestions;  // Recommend -fsafe-buffer-usage-suggestions?
+  bool SuggestSuggestions; // Recommend -fsafe-buffer-usage-suggestions?
 
   // Lists as a string the names of variables in `VarGroupForVD` except for 
`VD`
   // itself:
@@ -2425,7 +2412,7 @@ class UnsafeBufferUsageReporter : public 
UnsafeBufferUsageHandler {
 
 public:
   UnsafeBufferUsageReporter(Sema &S, bool SuggestSuggestions)
-    : S(S), SuggestSuggestions(SuggestSuggestions) {}
+      : S(S), SuggestSuggestions(SuggestSuggestions) {}
 
   void handleUnsafeOperation(const Stmt *Operation, bool IsRelatedToDecl,
                              ASTContext &Ctx) override {
@@ -2602,7 +2589,7 @@ class UnsafeBufferUsageReporter : public 
UnsafeBufferUsageHandler {
 
 #ifndef NDEBUG
     if (areDebugNotesRequested())
-      for (const DebugNote &Note: DebugNotesByVar[Variable])
+      for (const DebugNote &Note : DebugNotesByVar[Variable])
         S.Diag(Note.first, diag::note_safe_buffer_debug_mode) << Note.second;
 #endif
   }
@@ -2629,6 +2616,12 @@ class UnsafeBufferUsageReporter : public 
UnsafeBufferUsageHandler {
     return S.Diags.isIgnored(diag::warn_unsafe_buffer_libc_call, Loc);
   }
 
+  bool ignoreUnsafeBufferInStaticSizedArray(
+      const SourceLocation &Loc) const override {
+    return S.Diags.isIgnored(
+        diag::warn_unsafe_buffer_usage_in_static_sized_array, Loc);
+  }
+
   // Returns the text representation of clang::unsafe_buffer_usage attribute.
   // `WSSuffix` holds customized "white-space"s, e.g., newline or whilespace
   // characters.
@@ -2698,8 +2691,7 @@ sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema 
&s)
       MaxCFGBlocksPerFunction(0), NumUninitAnalysisFunctions(0),
       NumUninitAnalysisVariables(0), MaxUninitAnalysisVariablesPerFunction(0),
       NumUninitAnalysisBlockVisits(0),
-      MaxUninitAnalysisBlockVisitsPerFunction(0) {
-}
+      MaxUninitAnalysisBlockVisitsPerFunction(0) {}
 
 // We need this here for unique_ptr with forward declared class.
 sema::AnalysisBasedWarnings::~AnalysisBasedWarnings() = default;
@@ -2943,7 +2935,7 @@ LifetimeSafetyTUAnalysis(Sema &S, TranslationUnitDecl *TU,
 }
 
 void clang::sema::AnalysisBasedWarnings::IssueWarnings(
-     TranslationUnitDecl *TU) {
+    TranslationUnitDecl *TU) {
   if (!TU)
     return; // This is unexpected, give up quietly.
 
@@ -2957,7 +2949,7 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
 
   // UnsafeBufferUsage analysis settings.
   bool UnsafeBufferUsageCanEmitSuggestions = S.getLangOpts().CPlusPlus20;
-  bool UnsafeBufferUsageShouldEmitSuggestions =  // Should != Can.
+  bool UnsafeBufferUsageShouldEmitSuggestions = // Should != Can.
       UnsafeBufferUsageCanEmitSuggestions &&
       DiagOpts.ShowSafeBufferUsageSuggestions;
   bool UnsafeBufferUsageShouldSuggestSuggestions =
@@ -3065,13 +3057,13 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
     AC.getCFGBuildOptions().setAllAlwaysAdd();
   } else {
     AC.getCFGBuildOptions()
-      .setAlwaysAdd(Stmt::BinaryOperatorClass)
-      .setAlwaysAdd(Stmt::CompoundAssignOperatorClass)
-      .setAlwaysAdd(Stmt::BlockExprClass)
-      .setAlwaysAdd(Stmt::CStyleCastExprClass)
-      .setAlwaysAdd(Stmt::DeclRefExprClass)
-      .setAlwaysAdd(Stmt::ImplicitCastExprClass)
-      .setAlwaysAdd(Stmt::UnaryOperatorClass);
+        .setAlwaysAdd(Stmt::BinaryOperatorClass)
+        .setAlwaysAdd(Stmt::CompoundAssignOperatorClass)
+        .setAlwaysAdd(Stmt::BlockExprClass)
+        .setAlwaysAdd(Stmt::CStyleCastExprClass)
+        .setAlwaysAdd(Stmt::DeclRefExprClass)
+        .setAlwaysAdd(Stmt::ImplicitCastExprClass)
+        .setAlwaysAdd(Stmt::UnaryOperatorClass);
   }
   if (EnableLifetimeSafetyAnalysis) {
     AC.getCFGBuildOptions().AddLifetime = true;
@@ -3153,12 +3145,10 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
         ++NumUninitAnalysisFunctions;
         NumUninitAnalysisVariables += stats.NumVariablesAnalyzed;
         NumUninitAnalysisBlockVisits += stats.NumBlockVisits;
-        MaxUninitAnalysisVariablesPerFunction =
-            std::max(MaxUninitAnalysisVariablesPerFunction,
-                     stats.NumVariablesAnalyzed);
-        MaxUninitAnalysisBlockVisitsPerFunction =
-            std::max(MaxUninitAnalysisBlockVisitsPerFunction,
-                     stats.NumBlockVisits);
+        MaxUninitAnalysisVariablesPerFunction = std::max(
+            MaxUninitAnalysisVariablesPerFunction, stats.NumVariablesAnalyzed);
+        MaxUninitAnalysisBlockVisitsPerFunction = std::max(
+            MaxUninitAnalysisBlockVisitsPerFunction, stats.NumBlockVisits);
       }
     }
   }
@@ -3196,7 +3186,6 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
       !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, D->getBeginLoc()))
     diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap());
 
-
   // Check for infinite self-recursion in functions
   if (!Diags.isIgnored(diag::warn_infinite_recursive_function,
                        D->getBeginLoc())) {
@@ -3227,8 +3216,8 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
       // If we successfully built a CFG for this context, record some more
       // detail information about it.
       NumCFGBlocks += cfg->getNumBlockIDs();
-      MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction,
-                                         cfg->getNumBlockIDs());
+      MaxCFGBlocksPerFunction =
+          std::max(MaxCFGBlocksPerFunction, cfg->getNumBlockIDs());
     } else {
       ++NumFunctionsWithBadCFGs;
     }
@@ -3240,7 +3229,7 @@ void clang::sema::AnalysisBasedWarnings::PrintStats() 
const {
 
   unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs;
   unsigned AvgCFGBlocksPerFunction =
-      !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt;
+      !NumCFGsBuilt ? 0 : NumCFGBlocks / NumCFGsBuilt;
   llvm::errs() << NumFunctionsAnalyzed << " functions analyzed ("
                << NumFunctionsWithBadCFGs << " w/o CFGs).\n"
                << "  " << NumCFGBlocks << " CFG blocks built.\n"
@@ -3249,10 +3238,14 @@ void clang::sema::AnalysisBasedWarnings::PrintStats() 
const {
                << "  " << MaxCFGBlocksPerFunction
                << " max CFG blocks per function.\n";
 
-  unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0
-      : NumUninitAnalysisVariables/NumUninitAnalysisFunctions;
-  unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0
-      : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions;
+  unsigned AvgUninitVariablesPerFunction =
+      !NumUninitAnalysisFunctions
+          ? 0
+          : NumUninitAnalysisVariables / NumUninitAnalysisFunctions;
+  unsigned AvgUninitBlockVisitsPerFunction =
+      !NumUninitAnalysisFunctions
+          ? 0
+          : NumUninitAnalysisBlockVisits / NumUninitAnalysisFunctions;
   llvm::errs() << NumUninitAnalysisFunctions
                << " functions analyzed for uninitialiazed variables\n"
                << "  " << NumUninitAnalysisVariables << " variables 
analyzed.\n"

>From 58f9857e0c70f3575884a6f7f3a92f46f51131ba Mon Sep 17 00:00:00 2001
From: mxms <[email protected]>
Date: Fri, 16 Jan 2026 19:33:44 +0000
Subject: [PATCH 2/4] [clang][-Wunsafe-buffer-usage] Add flag support for
 -Wunsafe-buffer-usage-in-static-sized-arrays

---
 ...afe-buffer-usage-in-static-sized-array.cpp | 159 ++++++++++++++++++
 1 file changed, 159 insertions(+)
 create mode 100644 
clang/test/SemaCXX/warn-unsafe-buffer-usage-in-static-sized-array.cpp

diff --git 
a/clang/test/SemaCXX/warn-unsafe-buffer-usage-in-static-sized-array.cpp 
b/clang/test/SemaCXX/warn-unsafe-buffer-usage-in-static-sized-array.cpp
new file mode 100644
index 0000000000000..c4813198bbd9a
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-in-static-sized-array.cpp
@@ -0,0 +1,159 @@
+// RUN: %clang_cc1 -std=c++20 -Wno-everything -Wunsafe-buffer-usage \
+// RUN:            -Wno-unsafe-buffer-usage-in-static-sized-array \
+// RUN:            -fsafe-buffer-usage-suggestions \
+// RUN:            -verify %s
+
+// CHECK-NOT: [-Wunsafe-buffer-usage]
+// expected-no-diagnostics
+
+void foo(unsigned idx) {
+  int buffer[10];
+  buffer[idx] = 0;
+}
+
+int global_buffer[10];
+void foo2(unsigned idx) { global_buffer[idx] = 0; }
+
+struct Foo {
+  int member_buffer[10];
+  int x;
+};
+
+void foo2(Foo &f, unsigned idx) { f.member_buffer[idx] = 0; }
+
+void constant_idx_safe(unsigned idx) {
+  int buffer[10];
+  buffer[9] = 0;
+}
+
+void constant_idx_safe0(unsigned idx) {
+  int buffer[10];
+  buffer[0] = 0;
+}
+
+int array[10];
+
+void circular_access_unsigned(unsigned idx) {
+  array[idx % 10];
+  array[idx % 11];
+  array[(idx + 3) % 10];
+  array[(--idx) % 8];
+  array[idx & 9 % 10];
+  array[9 & idx % 11];
+  array[12 % 10];
+}
+
+void circular_access_signed(int idx) { array[idx % 10]; }
+
+void masked_idx1(unsigned long long idx, Foo f) {
+  // Bitwise and operation
+  array[idx & 5] = 10;
+  array[5 & idx] = 12;
+  array[idx & 11 & 5] = 3;
+  array[idx & 11] = 20;
+  array[idx &= 5];
+  array[f.x & 5];
+  array[5 & f.x];
+  array[f.x & (-5)];
+}
+
+typedef unsigned long long uint64_t;
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+
+void type_conversions(uint64_t idx1, uint32_t idx2, uint8_t idx3) {
+  array[(uint32_t)idx1 & 3];
+  array[idx2 & 3];
+  array[idx3 & 3];
+}
+
+int array2[5];
+
+void masked_idx_safe(unsigned long long idx) {
+  array2[6 & 5];
+  array2[6 & idx & (idx + 1) & 5];
+}
+
+void constant_idx_unsafe(unsigned idx) {
+  int buffer[10];
+  buffer[10] = 0;
+}
+
+void constant_id_string(unsigned idx) {
+  char safe_char = "abc"[1];
+  safe_char = ""[0];
+  safe_char = "\0"[0];
+
+  char abcd[5] = "abc";
+  abcd[2];
+
+  char unsafe_char = "abc"[3];
+  unsafe_char = "abc"[-1];
+  unsafe_char = ""[1];
+  unsafe_char = ""[idx];
+}
+
+typedef float Float4x4[4][4];
+
+float two_dimension_array(Float4x4 &matrix, unsigned idx) {
+  float a = matrix[0][4];
+
+  a = matrix[0][3];
+
+  a = matrix[4][0];
+
+  a = matrix[idx][0];
+
+  a = matrix[0][idx];
+
+  a = matrix[idx][idx];
+
+  return matrix[1][1];
+}
+
+typedef float Float2x3x4[2][3][4];
+float multi_dimension_array(Float2x3x4 &matrix) {
+  float *f = matrix[0][2];
+  return matrix[1][2][3];
+}
+
+char array_strings[][11] = {"Apple", "Banana", "Cherry", "Date", "Elderberry"};
+
+char array_string[] = "123456";
+
+char access_strings() {
+  char c = array_strings[0][4];
+  c = array_strings[3][10];
+  c = array_string[5];
+  return c;
+}
+
+struct T {
+  int array[10];
+};
+
+const int index = 1;
+
+constexpr int get_const(int x) {
+  if (x < 3)
+    return ++x;
+  else
+    return x + 5;
+};
+
+void array_indexed_const_expr(unsigned idx) {
+  int arr[10];
+  arr[sizeof(int)] = 5;
+
+  int array[sizeof(T)];
+  array[sizeof(int)] = 5;
+  array[sizeof(T) - 1] = 3;
+
+  int k = arr[6 & 5];
+  k = arr[2 << index];
+  k = arr[8 << index];
+  k = arr[16 >> 1];
+  k = arr[get_const(index)];
+  k = arr[get_const(5)];
+  k = arr[get_const(4)];
+}

>From a0f4e48efe50af38c533701ea28ec59615d4d098 Mon Sep 17 00:00:00 2001
From: mxms <[email protected]>
Date: Fri, 16 Jan 2026 19:33:44 +0000
Subject: [PATCH 3/4] [clang][-Wunsafe-buffer-usage] Add flag support for
 -Wunsafe-buffer-usage-in-static-sized-arrays

---
 clang/lib/Sema/AnalysisBasedWarnings.cpp | 621 ++++++++++++-----------
 1 file changed, 314 insertions(+), 307 deletions(-)

diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp 
b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 437397d3126c2..56d7db649afbe 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -67,60 +67,61 @@ using namespace clang;
 
//===----------------------------------------------------------------------===//
 
 namespace {
-class UnreachableCodeHandler : public reachable_code::Callback {
-  Sema &S;
-  SourceRange PreviousSilenceableCondVal;
-
-public:
-  UnreachableCodeHandler(Sema &s) : S(s) {}
-
-  void HandleUnreachable(reachable_code::UnreachableKind UK, SourceLocation L,
-                         SourceRange SilenceableCondVal, SourceRange R1,
-                         SourceRange R2, bool HasFallThroughAttr) override {
-    // If the diagnosed code is `[[fallthrough]];` and
-    // `-Wunreachable-code-fallthrough` is  enabled, suppress `code will never
-    // be executed` warning to avoid generating diagnostic twice
-    if (HasFallThroughAttr &&
-        !S.getDiagnostics().isIgnored(diag::warn_unreachable_fallthrough_attr,
-                                      SourceLocation()))
-      return;
+  class UnreachableCodeHandler : public reachable_code::Callback {
+    Sema &S;
+    SourceRange PreviousSilenceableCondVal;
+
+  public:
+    UnreachableCodeHandler(Sema &s) : S(s) {}
+
+    void HandleUnreachable(reachable_code::UnreachableKind UK, SourceLocation 
L,
+                           SourceRange SilenceableCondVal, SourceRange R1,
+                           SourceRange R2, bool HasFallThroughAttr) override {
+      // If the diagnosed code is `[[fallthrough]];` and
+      // `-Wunreachable-code-fallthrough` is  enabled, suppress `code will 
never
+      // be executed` warning to avoid generating diagnostic twice
+      if (HasFallThroughAttr &&
+          
!S.getDiagnostics().isIgnored(diag::warn_unreachable_fallthrough_attr,
+                                        SourceLocation()))
+        return;
 
-    // Avoid reporting multiple unreachable code diagnostics that are
-    // triggered by the same conditional value.
-    if (PreviousSilenceableCondVal.isValid() && SilenceableCondVal.isValid() &&
-        PreviousSilenceableCondVal == SilenceableCondVal)
-      return;
-    PreviousSilenceableCondVal = SilenceableCondVal;
+      // Avoid reporting multiple unreachable code diagnostics that are
+      // triggered by the same conditional value.
+      if (PreviousSilenceableCondVal.isValid() &&
+          SilenceableCondVal.isValid() &&
+          PreviousSilenceableCondVal == SilenceableCondVal)
+        return;
+      PreviousSilenceableCondVal = SilenceableCondVal;
 
-    unsigned diag = diag::warn_unreachable;
-    switch (UK) {
-    case reachable_code::UK_Break:
-      diag = diag::warn_unreachable_break;
-      break;
-    case reachable_code::UK_Return:
-      diag = diag::warn_unreachable_return;
-      break;
-    case reachable_code::UK_Loop_Increment:
-      diag = diag::warn_unreachable_loop_increment;
-      break;
-    case reachable_code::UK_Other:
-      break;
-    }
+      unsigned diag = diag::warn_unreachable;
+      switch (UK) {
+        case reachable_code::UK_Break:
+          diag = diag::warn_unreachable_break;
+          break;
+        case reachable_code::UK_Return:
+          diag = diag::warn_unreachable_return;
+          break;
+        case reachable_code::UK_Loop_Increment:
+          diag = diag::warn_unreachable_loop_increment;
+          break;
+        case reachable_code::UK_Other:
+          break;
+      }
 
-    S.Diag(L, diag) << R1 << R2;
+      S.Diag(L, diag) << R1 << R2;
 
-    SourceLocation Open = SilenceableCondVal.getBegin();
-    if (Open.isValid()) {
-      SourceLocation Close = SilenceableCondVal.getEnd();
-      Close = S.getLocForEndOfToken(Close);
-      if (Close.isValid()) {
-        S.Diag(Open, diag::note_unreachable_silence)
+      SourceLocation Open = SilenceableCondVal.getBegin();
+      if (Open.isValid()) {
+        SourceLocation Close = SilenceableCondVal.getEnd();
+        Close = S.getLocForEndOfToken(Close);
+        if (Close.isValid()) {
+          S.Diag(Open, diag::note_unreachable_silence)
             << FixItHint::CreateInsertion(Open, "/* DISABLES CODE */ (")
             << FixItHint::CreateInsertion(Close, ")");
+        }
       }
     }
-  }
-};
+  };
 } // anonymous namespace
 
 /// CheckUnreachable - Check for unreachable code.
@@ -290,8 +291,7 @@ static void checkRecursiveFunction(Sema &S, const 
FunctionDecl *FD,
     return;
 
   CFG *cfg = AC.getCFG();
-  if (!cfg)
-    return;
+  if (!cfg) return;
 
   // If the exit block is unreachable, skip processing the function.
   if (cfg->getExit().pred_empty())
@@ -326,9 +326,10 @@ static bool throwEscapes(Sema &S, const CXXThrowExpr *E, 
CFGBlock &ThrowBlock,
       if (Succ->getBlockID() == Body->getExit().getBlockID())
         return true;
 
-      if (auto *Catch = dyn_cast_or_null<CXXCatchStmt>(Succ->getLabel())) {
+      if (auto *Catch =
+              dyn_cast_or_null<CXXCatchStmt>(Succ->getLabel())) {
         QualType Caught = Catch->getCaughtType();
-        if (Caught.isNull() ||  // catch (...) catches everything
+        if (Caught.isNull() || // catch (...) catches everything
             !E->getSubExpr() || // throw; is considered cuaght by any handler
             S.handlerCanCatch(Caught, E->getSubExpr()->getType()))
           // Exception doesn't escape via this path.
@@ -347,8 +348,7 @@ static void visitReachableThrows(
     CFG *BodyCFG,
     llvm::function_ref<void(const CXXThrowExpr *, CFGBlock &)> Visit) {
   llvm::BitVector Reachable(BodyCFG->getNumBlockIDs());
-  clang::reachable_code::ScanReachableFromBlock(&BodyCFG->getEntry(),
-                                                Reachable);
+  clang::reachable_code::ScanReachableFromBlock(&BodyCFG->getEntry(), 
Reachable);
   for (CFGBlock *B : *BodyCFG) {
     if (!Reachable[B->getBlockID()])
       continue;
@@ -371,8 +371,8 @@ static void EmitDiagForCXXThrowInNonThrowingFunc(Sema &S, 
SourceLocation OpLoc,
         (isa<CXXDestructorDecl>(FD) ||
          FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
          FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete)) {
-      if (const auto *Ty =
-              FD->getTypeSourceInfo()->getType()->getAs<FunctionProtoType>())
+      if (const auto *Ty = FD->getTypeSourceInfo()->getType()->
+                                         getAs<FunctionProtoType>())
         S.Diag(FD->getLocation(), diag::note_throw_in_dtor)
             << !isa<CXXDestructorDecl>(FD) << !Ty->hasExceptionSpec()
             << FD->getExceptionSpecSourceRange();
@@ -389,11 +389,10 @@ static void checkThrowInNonThrowingFunc(Sema &S, const 
FunctionDecl *FD,
     return;
   if (BodyCFG->getExit().pred_empty())
     return;
-  visitReachableThrows(
-      BodyCFG, [&](const CXXThrowExpr *Throw, CFGBlock &Block) {
-        if (throwEscapes(S, Throw, Block, BodyCFG))
-          EmitDiagForCXXThrowInNonThrowingFunc(S, Throw->getThrowLoc(), FD);
-      });
+  visitReachableThrows(BodyCFG, [&](const CXXThrowExpr *Throw, CFGBlock 
&Block) {
+    if (throwEscapes(S, Throw, Block, BodyCFG))
+      EmitDiagForCXXThrowInNonThrowingFunc(S, Throw->getThrowLoc(), FD);
+  });
 }
 
 static bool isNoexcept(const FunctionDecl *FD) {
@@ -566,14 +565,13 @@ enum ControlFlowKind {
 /// will return.
 static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) {
   CFG *cfg = AC.getCFG();
-  if (!cfg)
-    return UnknownFallThrough;
+  if (!cfg) return UnknownFallThrough;
 
   // The CFG leaves in dead things, and we don't want the dead code paths to
   // confuse us, so we mark all live things first.
   llvm::BitVector live(cfg->getNumBlockIDs());
-  unsigned count =
-      reachable_code::ScanReachableFromBlock(&cfg->getEntry(), live);
+  unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(),
+                                                          live);
 
   bool AddEHEdges = AC.getAddEHEdges();
   if (!AddEHEdges && count != cfg->getNumBlockIDs())
@@ -626,7 +624,7 @@ static ControlFlowKind CheckFallThrough(AnalysisDeclContext 
&AC) {
     // statement (if it exists).
     CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend();
 
-    for (; ri != re; ++ri)
+    for ( ; ri != re ; ++ri)
       if (ri->getAs<CFGStmt>())
         break;
 
@@ -800,12 +798,14 @@ static void CheckFallThroughForBody(Sema &S, const Decl 
*D, const Stmt *Body,
     else
       ReturnsVoid = FD->getReturnType()->isVoidType();
     HasNoReturn = FD->isNoReturn() || FD->hasAttr<InferredNoReturnAttr>();
-  } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
+  }
+  else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
     ReturnsVoid = MD->getReturnType()->isVoidType();
     HasNoReturn = MD->hasAttr<NoReturnAttr>();
-  } else if (isa<BlockDecl>(D)) {
+  }
+  else if (isa<BlockDecl>(D)) {
     if (const FunctionType *FT =
-            BlockType->getPointeeType()->getAs<FunctionType>()) {
+          BlockType->getPointeeType()->getAs<FunctionType>()) {
       if (FT->getReturnType()->isVoidType())
         ReturnsVoid = true;
       if (FT->getNoReturnAttr())
@@ -817,7 +817,7 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, 
const Stmt *Body,
 
   // Short circuit for compilation speed.
   if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
-    return;
+      return;
   SourceLocation LBrace = Body->getBeginLoc(), RBrace = Body->getEndLoc();
 
   // cpu_dispatch functions permit empty function bodies for ICC compatibility.
@@ -894,7 +894,7 @@ class ContainsReference : public 
ConstEvaluatedExprVisitor<ContainsReference> {
   typedef ConstEvaluatedExprVisitor<ContainsReference> Inherited;
 
   ContainsReference(ASTContext &Context, const DeclRefExpr *Needle)
-      : Inherited(Context), FoundReference(false), Needle(Needle) {}
+    : Inherited(Context), FoundReference(false), Needle(Needle) {}
 
   void VisitExpr(const Expr *E) {
     // Stop evaluating if we already have a reference.
@@ -917,7 +917,8 @@ class ContainsReference : public 
ConstEvaluatedExprVisitor<ContainsReference> {
 
 static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
   QualType VariableTy = VD->getType().getCanonicalType();
-  if (VariableTy->isBlockPointerType() && !VD->hasAttr<BlocksAttr>()) {
+  if (VariableTy->isBlockPointerType() &&
+      !VD->hasAttr<BlocksAttr>()) {
     S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization)
         << VD->getDeclName()
         << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
@@ -939,16 +940,16 @@ static bool SuggestInitializationFixit(Sema &S, const 
VarDecl *VD) {
   if (Init.empty())
     return false;
 
-  S.Diag(Loc, diag::note_var_fixit_add_initialization)
-      << VD->getDeclName() << FixItHint::CreateInsertion(Loc, Init);
+  S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
+    << FixItHint::CreateInsertion(Loc, Init);
   return true;
 }
 
 /// Create a fixit to remove an if-like statement, on the assumption that its
 /// condition is CondVal.
 static void CreateIfFixit(Sema &S, const Stmt *If, const Stmt *Then,
-                          const Stmt *Else, bool CondVal, FixItHint &Fixit1,
-                          FixItHint &Fixit2) {
+                          const Stmt *Else, bool CondVal,
+                          FixItHint &Fixit1, FixItHint &Fixit2) {
   if (CondVal) {
     // If condition is always true, remove all but the 'then'.
     Fixit1 = FixItHint::CreateRemoval(
@@ -1015,9 +1016,9 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, 
const UninitUse &Use,
     // For all binary terminators, branch 0 is taken if the condition is true,
     // and branch 1 is taken if the condition is false.
     int RemoveDiagKind = -1;
-    const char *FixitStr = S.getLangOpts().CPlusPlus
-                               ? (I->Output ? "true" : "false")
-                               : (I->Output ? "1" : "0");
+    const char *FixitStr =
+        S.getLangOpts().CPlusPlus ? (I->Output ? "true" : "false")
+                                  : (I->Output ? "1" : "0");
     FixItHint Fixit1, Fixit2;
 
     switch (Term ? Term->getStmtClass() : Stmt::DeclStmtClass) {
@@ -1033,8 +1034,8 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, 
const UninitUse &Use,
       Str = "if";
       Range = IS->getCond()->getSourceRange();
       RemoveDiagKind = 0;
-      CreateIfFixit(S, IS, IS->getThen(), IS->getElse(), I->Output, Fixit1,
-                    Fixit2);
+      CreateIfFixit(S, IS, IS->getThen(), IS->getElse(),
+                    I->Output, Fixit1, Fixit2);
       break;
     }
     case Stmt::ConditionalOperatorClass: {
@@ -1043,8 +1044,8 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, 
const UninitUse &Use,
       Str = "?:";
       Range = CO->getCond()->getSourceRange();
       RemoveDiagKind = 0;
-      CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(), I->Output,
-                    Fixit1, Fixit2);
+      CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(),
+                    I->Output, Fixit1, Fixit2);
       break;
     }
     case Stmt::BinaryOperatorClass: {
@@ -1119,13 +1120,13 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, 
const UninitUse &Use,
     }
 
     S.Diag(Range.getBegin(), diag::warn_sometimes_uninit_var)
-        << VD->getDeclName() << IsCapturedByBlock << DiagKind << Str
-        << I->Output << Range;
+      << VD->getDeclName() << IsCapturedByBlock << DiagKind
+      << Str << I->Output << Range;
     S.Diag(User->getBeginLoc(), diag::note_uninit_var_use)
         << IsCapturedByBlock << User->getSourceRange();
     if (RemoveDiagKind != -1)
       S.Diag(Fixit1.RemoveRange.getBegin(), 
diag::note_uninit_fixit_remove_cond)
-          << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2;
+        << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2;
 
     Diagnosed = true;
   }
@@ -1295,32 +1296,32 @@ class FallthroughMapper : public 
DynamicRecursiveASTVisitor {
             // Don't care about other unreachable statements.
           }
         }
-        // If there are no unreachable statements, this may be a special
-        // case in CFG:
-        // case X: {
-        //    A a;  // A has a destructor.
-        //    break;
-        // }
-        // // <<<< This place is represented by a 'hanging' CFG block.
-        // case Y:
-        continue;
+          // If there are no unreachable statements, this may be a special
+          // case in CFG:
+          // case X: {
+          //    A a;  // A has a destructor.
+          //    break;
+          // }
+          // // <<<< This place is represented by a 'hanging' CFG block.
+          // case Y:
+          continue;
       }
 
-      const Stmt *LastStmt = getLastStmt(*P);
-      if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
-        markFallthroughVisited(AS);
-        ++AnnotatedCnt;
-        continue; // Fallthrough annotation, good.
-      }
+        const Stmt *LastStmt = getLastStmt(*P);
+        if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
+          markFallthroughVisited(AS);
+          ++AnnotatedCnt;
+          continue; // Fallthrough annotation, good.
+        }
 
-      if (!LastStmt) { // This block contains no executable statements.
-        // Traverse its predecessors.
-        std::copy(P->pred_begin(), P->pred_end(),
-                  std::back_inserter(BlockQueue));
-        continue;
-      }
+        if (!LastStmt) { // This block contains no executable statements.
+          // Traverse its predecessors.
+          std::copy(P->pred_begin(), P->pred_end(),
+                    std::back_inserter(BlockQueue));
+          continue;
+        }
 
-      ++UnannotatedCnt;
+        ++UnannotatedCnt;
     }
     return !!UnannotatedCnt;
   }
@@ -1336,63 +1337,64 @@ class FallthroughMapper : public 
DynamicRecursiveASTVisitor {
     return true;
   }
 
-  // We don't want to traverse local type declarations. We analyze their
-  // methods separately.
-  bool TraverseDecl(Decl *D) override { return true; }
+    // We don't want to traverse local type declarations. We analyze their
+    // methods separately.
+    bool TraverseDecl(Decl *D) override { return true; }
 
-  // We analyze lambda bodies separately. Skip them here.
-  bool TraverseLambdaExpr(LambdaExpr *LE) override {
-    // Traverse the captures, but not the body.
-    for (const auto C : zip(LE->captures(), LE->capture_inits()))
-      TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
-    return true;
-  }
+    // We analyze lambda bodies separately. Skip them here.
+    bool TraverseLambdaExpr(LambdaExpr *LE) override {
+      // Traverse the captures, but not the body.
+      for (const auto C : zip(LE->captures(), LE->capture_inits()))
+        TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
+      return true;
+    }
 
-private:
-  static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
-    if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {
-      if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
-        return AS;
+  private:
+
+    static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
+      if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {
+        if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
+          return AS;
+      }
+      return nullptr;
     }
-    return nullptr;
-  }
 
-  static const Stmt *getLastStmt(const CFGBlock &B) {
-    if (const Stmt *Term = B.getTerminatorStmt())
-      return Term;
-    for (const CFGElement &Elem : llvm::reverse(B))
-      if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>())
-        return CS->getStmt();
-    // Workaround to detect a statement thrown out by CFGBuilder:
-    //   case X: {} case Y:
-    //   case X: ; case Y:
-    if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))
-      if (!isa<SwitchCase>(SW->getSubStmt()))
-        return SW->getSubStmt();
+    static const Stmt *getLastStmt(const CFGBlock &B) {
+      if (const Stmt *Term = B.getTerminatorStmt())
+        return Term;
+      for (const CFGElement &Elem : llvm::reverse(B))
+        if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>())
+          return CS->getStmt();
+      // Workaround to detect a statement thrown out by CFGBuilder:
+      //   case X: {} case Y:
+      //   case X: ; case Y:
+      if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))
+        if (!isa<SwitchCase>(SW->getSubStmt()))
+          return SW->getSubStmt();
 
-    return nullptr;
-  }
+      return nullptr;
+    }
 
-  bool FoundSwitchStatements;
-  AttrStmts FallthroughStmts;
-  Sema &S;
-  llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
+    bool FoundSwitchStatements;
+    AttrStmts FallthroughStmts;
+    Sema &S;
+    llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
 };
 } // anonymous namespace
 
 static StringRef getFallthroughAttrSpelling(Preprocessor &PP,
                                             SourceLocation Loc) {
-  TokenValue FallthroughTokens[] = {tok::l_square, tok::l_square,
-                                    PP.getIdentifierInfo("fallthrough"),
-                                    tok::r_square, tok::r_square};
-
-  TokenValue ClangFallthroughTokens[] = {tok::l_square,
-                                         tok::l_square,
-                                         PP.getIdentifierInfo("clang"),
-                                         tok::coloncolon,
-                                         PP.getIdentifierInfo("fallthrough"),
-                                         tok::r_square,
-                                         tok::r_square};
+  TokenValue FallthroughTokens[] = {
+    tok::l_square, tok::l_square,
+    PP.getIdentifierInfo("fallthrough"),
+    tok::r_square, tok::r_square
+  };
+
+  TokenValue ClangFallthroughTokens[] = {
+    tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"),
+    tok::coloncolon, PP.getIdentifierInfo("fallthrough"),
+    tok::r_square, tok::r_square
+  };
 
   bool PreferClangAttr = !PP.getLangOpts().CPlusPlus17 && 
!PP.getLangOpts().C23;
 
@@ -1507,12 +1509,13 @@ static bool isInLoop(const ASTContext &Ctx, const 
ParentMap &PM,
 
 static void diagnoseRepeatedUseOfWeak(Sema &S,
                                       const sema::FunctionScopeInfo *CurFn,
-                                      const Decl *D, const ParentMap &PM) {
+                                      const Decl *D,
+                                      const ParentMap &PM) {
   typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy;
   typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap;
   typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector;
   typedef std::pair<const Stmt *, WeakObjectUseMap::const_iterator>
-      StmtUsesPair;
+  StmtUsesPair;
 
   ASTContext &Ctx = S.getASTContext();
 
@@ -1526,7 +1529,7 @@ static void diagnoseRepeatedUseOfWeak(Sema &S,
 
     // Find the first read of the weak object.
     WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end();
-    for (; UI != UE; ++UI) {
+    for ( ; UI != UE; ++UI) {
       if (UI->isUnsafe())
         break;
     }
@@ -1583,7 +1586,12 @@ static void diagnoseRepeatedUseOfWeak(Sema &S,
   // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.
   // FIXME: Should we use a common classification enum and the same set of
   // possibilities all throughout Sema?
-  enum { Function, Method, Block, Lambda } FunctionKind;
+  enum {
+    Function,
+    Method,
+    Block,
+    Lambda
+  } FunctionKind;
 
   if (isa<sema::BlockScopeInfo>(CurFn))
     FunctionKind = Block;
@@ -1614,7 +1622,12 @@ static void diagnoseRepeatedUseOfWeak(Sema &S,
     // Classify the weak object being accessed for better warning text.
     // This enum should stay in sync with the cases in
     // warn_arc_repeated_use_of_weak and 
warn_arc_possible_repeated_use_of_weak.
-    enum { Variable, Property, ImplicitProperty, Ivar } ObjectKind;
+    enum {
+      Variable,
+      Property,
+      ImplicitProperty,
+      Ivar
+    } ObjectKind;
 
     const NamedDecl *KeyProp = Key.getProperty();
     if (isa<VarDecl>(KeyProp))
@@ -1716,7 +1729,7 @@ class UninitValsDiagReporter : public 
UninitVariablesHandler {
   }
 
 private:
-  static bool hasAlwaysUninitializedUse(const UsesVec *vec) {
+  static bool hasAlwaysUninitializedUse(const UsesVec* vec) {
     return llvm::any_of(*vec, [](const UninitUse &U) {
       return U.getKind() == UninitUse::Always ||
              U.getKind() == UninitUse::AfterCall ||
@@ -1966,10 +1979,10 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
                : getNotes();
   }
 
-public:
+ public:
   ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL)
-      : S(S), FunLocation(FL), FunEndLocation(FEL), CurrentFunction(nullptr),
-        Verbose(false) {}
+    : S(S), FunLocation(FL), FunEndLocation(FEL),
+      CurrentFunction(nullptr), Verbose(false) {}
 
   void setVerbose(bool b) { Verbose = b; }
 
@@ -2064,18 +2077,18 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
                                  bool ReentrancyMismatch) override {
     unsigned DiagID = 0;
     switch (LEK) {
-    case LEK_LockedSomePredecessors:
-      DiagID = diag::warn_lock_some_predecessors;
-      break;
-    case LEK_LockedSomeLoopIterations:
-      DiagID = diag::warn_expecting_lock_held_on_loop;
-      break;
-    case LEK_LockedAtEndOfFunction:
-      DiagID = diag::warn_no_unlock;
-      break;
-    case LEK_NotLockedAtEndOfFunction:
-      DiagID = diag::warn_expecting_locked;
-      break;
+      case LEK_LockedSomePredecessors:
+        DiagID = diag::warn_lock_some_predecessors;
+        break;
+      case LEK_LockedSomeLoopIterations:
+        DiagID = diag::warn_expecting_lock_held_on_loop;
+        break;
+      case LEK_LockedAtEndOfFunction:
+        DiagID = diag::warn_no_unlock;
+        break;
+      case LEK_NotLockedAtEndOfFunction:
+        DiagID = diag::warn_expecting_locked;
+        break;
     }
     if (LocEndOfScope.isInvalid())
       LocEndOfScope = FunEndLocation;
@@ -2121,7 +2134,7 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
       break;
     }
     PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
-                                         << D << 
getLockKindFromAccessKind(AK));
+      << D << getLockKindFromAccessKind(AK));
     Warnings.emplace_back(std::move(Warning), getNotes());
   }
 
@@ -2132,42 +2145,43 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
     unsigned DiagID = 0;
     if (PossibleMatch) {
       switch (POK) {
-      case POK_VarAccess:
-        DiagID = diag::warn_variable_requires_lock_precise;
-        break;
-      case POK_VarDereference:
-        DiagID = diag::warn_var_deref_requires_lock_precise;
-        break;
-      case POK_FunctionCall:
-        DiagID = diag::warn_fun_requires_lock_precise;
-        break;
-      case POK_PassByRef:
-        DiagID = diag::warn_guarded_pass_by_reference;
-        break;
-      case POK_PtPassByRef:
-        DiagID = diag::warn_pt_guarded_pass_by_reference;
-        break;
-      case POK_ReturnByRef:
-        DiagID = diag::warn_guarded_return_by_reference;
-        break;
-      case POK_PtReturnByRef:
-        DiagID = diag::warn_pt_guarded_return_by_reference;
-        break;
-      case POK_PassPointer:
-        DiagID = diag::warn_guarded_pass_pointer;
-        break;
-      case POK_PtPassPointer:
-        DiagID = diag::warn_pt_guarded_pass_pointer;
-        break;
-      case POK_ReturnPointer:
-        DiagID = diag::warn_guarded_return_pointer;
-        break;
-      case POK_PtReturnPointer:
-        DiagID = diag::warn_pt_guarded_return_pointer;
-        break;
+        case POK_VarAccess:
+          DiagID = diag::warn_variable_requires_lock_precise;
+          break;
+        case POK_VarDereference:
+          DiagID = diag::warn_var_deref_requires_lock_precise;
+          break;
+        case POK_FunctionCall:
+          DiagID = diag::warn_fun_requires_lock_precise;
+          break;
+        case POK_PassByRef:
+          DiagID = diag::warn_guarded_pass_by_reference;
+          break;
+        case POK_PtPassByRef:
+          DiagID = diag::warn_pt_guarded_pass_by_reference;
+          break;
+        case POK_ReturnByRef:
+          DiagID = diag::warn_guarded_return_by_reference;
+          break;
+        case POK_PtReturnByRef:
+          DiagID = diag::warn_pt_guarded_return_by_reference;
+          break;
+        case POK_PassPointer:
+          DiagID = diag::warn_guarded_pass_pointer;
+          break;
+        case POK_PtPassPointer:
+          DiagID = diag::warn_pt_guarded_pass_pointer;
+          break;
+        case POK_ReturnPointer:
+          DiagID = diag::warn_guarded_return_pointer;
+          break;
+        case POK_PtReturnPointer:
+          DiagID = diag::warn_pt_guarded_return_pointer;
+          break;
       }
-      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
-                                           << Kind << D << LockName << LK);
+      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
+                                                       << D
+                                                       << LockName << LK);
       PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match)
                                         << *PossibleMatch);
       if (Verbose && POK == POK_VarAccess) {
@@ -2179,42 +2193,43 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
         Warnings.emplace_back(std::move(Warning), getNotes(Note));
     } else {
       switch (POK) {
-      case POK_VarAccess:
-        DiagID = diag::warn_variable_requires_lock;
-        break;
-      case POK_VarDereference:
-        DiagID = diag::warn_var_deref_requires_lock;
-        break;
-      case POK_FunctionCall:
-        DiagID = diag::warn_fun_requires_lock;
-        break;
-      case POK_PassByRef:
-        DiagID = diag::warn_guarded_pass_by_reference;
-        break;
-      case POK_PtPassByRef:
-        DiagID = diag::warn_pt_guarded_pass_by_reference;
-        break;
-      case POK_ReturnByRef:
-        DiagID = diag::warn_guarded_return_by_reference;
-        break;
-      case POK_PtReturnByRef:
-        DiagID = diag::warn_pt_guarded_return_by_reference;
-        break;
-      case POK_PassPointer:
-        DiagID = diag::warn_guarded_pass_pointer;
-        break;
-      case POK_PtPassPointer:
-        DiagID = diag::warn_pt_guarded_pass_pointer;
-        break;
-      case POK_ReturnPointer:
-        DiagID = diag::warn_guarded_return_pointer;
-        break;
-      case POK_PtReturnPointer:
-        DiagID = diag::warn_pt_guarded_return_pointer;
-        break;
+        case POK_VarAccess:
+          DiagID = diag::warn_variable_requires_lock;
+          break;
+        case POK_VarDereference:
+          DiagID = diag::warn_var_deref_requires_lock;
+          break;
+        case POK_FunctionCall:
+          DiagID = diag::warn_fun_requires_lock;
+          break;
+        case POK_PassByRef:
+          DiagID = diag::warn_guarded_pass_by_reference;
+          break;
+        case POK_PtPassByRef:
+          DiagID = diag::warn_pt_guarded_pass_by_reference;
+          break;
+        case POK_ReturnByRef:
+          DiagID = diag::warn_guarded_return_by_reference;
+          break;
+        case POK_PtReturnByRef:
+          DiagID = diag::warn_pt_guarded_return_by_reference;
+          break;
+        case POK_PassPointer:
+          DiagID = diag::warn_guarded_pass_pointer;
+          break;
+        case POK_PtPassPointer:
+          DiagID = diag::warn_pt_guarded_pass_pointer;
+          break;
+        case POK_ReturnPointer:
+          DiagID = diag::warn_guarded_return_pointer;
+          break;
+        case POK_PtReturnPointer:
+          DiagID = diag::warn_pt_guarded_return_pointer;
+          break;
       }
-      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
-                                           << Kind << D << LockName << LK);
+      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
+                                                       << D
+                                                       << LockName << LK);
       if (Verbose && POK == POK_VarAccess) {
         PartialDiagnosticAt Note(D->getLocation(),
                                  S.PDiag(diag::note_guarded_by_declared_here));
@@ -2226,9 +2241,9 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
 
   void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,
                              SourceLocation Loc) override {
-    PartialDiagnosticAt Warning(
-        Loc, S.PDiag(diag::warn_acquire_requires_negative_cap)
-                 << Kind << LockName << Neg);
+    PartialDiagnosticAt Warning(Loc,
+        S.PDiag(diag::warn_acquire_requires_negative_cap)
+        << Kind << LockName << Neg);
     Warnings.emplace_back(std::move(Warning), getNotes());
   }
 
@@ -2248,20 +2263,22 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
 
   void handleLockAcquiredBefore(StringRef Kind, Name L1Name, Name L2Name,
                                 SourceLocation Loc) override {
-    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_acquired_before)
-                                         << Kind << L1Name << L2Name);
+    PartialDiagnosticAt Warning(Loc,
+      S.PDiag(diag::warn_acquired_before) << Kind << L1Name << L2Name);
     Warnings.emplace_back(std::move(Warning), getNotes());
   }
 
   void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) override {
-    PartialDiagnosticAt Warning(
-        Loc, S.PDiag(diag::warn_acquired_before_after_cycle) << L1Name);
+    PartialDiagnosticAt Warning(Loc,
+      S.PDiag(diag::warn_acquired_before_after_cycle) << L1Name);
     Warnings.emplace_back(std::move(Warning), getNotes());
   }
 
-  void enterFunction(const FunctionDecl *FD) override { CurrentFunction = FD; }
+  void enterFunction(const FunctionDecl* FD) override {
+    CurrentFunction = FD;
+  }
 
-  void leaveFunction(const FunctionDecl *FD) override {
+  void leaveFunction(const FunctionDecl* FD) override {
     CurrentFunction = nullptr;
   }
 };
@@ -2282,6 +2299,7 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
   DiagList Warnings;
 
 public:
+
   ConsumedWarningsHandler(Sema &S) : S(S) {}
 
   void emitDiagnostics() override {
@@ -2295,8 +2313,8 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
 
   void warnLoopStateMismatch(SourceLocation Loc,
                              StringRef VariableName) override {
-    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch)
-                                         << VariableName);
+    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch) <<
+      VariableName);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2306,9 +2324,9 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
                                         StringRef ExpectedState,
                                         StringRef ObservedState) override {
 
-    PartialDiagnosticAt Warning(
-        Loc, S.PDiag(diag::warn_param_return_typestate_mismatch)
-                 << VariableName << ExpectedState << ObservedState);
+    PartialDiagnosticAt Warning(Loc, S.PDiag(
+      diag::warn_param_return_typestate_mismatch) << VariableName <<
+        ExpectedState << ObservedState);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2316,18 +2334,16 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
   void warnParamTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
                                   StringRef ObservedState) override {
 
-    PartialDiagnosticAt Warning(Loc,
-                                S.PDiag(diag::warn_param_typestate_mismatch)
-                                    << ExpectedState << ObservedState);
+    PartialDiagnosticAt Warning(Loc, S.PDiag(
+      diag::warn_param_typestate_mismatch) << ExpectedState << ObservedState);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
 
   void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
                                               StringRef TypeName) override {
-    PartialDiagnosticAt Warning(
-        Loc, S.PDiag(diag::warn_return_typestate_for_unconsumable_type)
-                 << TypeName);
+    PartialDiagnosticAt Warning(Loc, S.PDiag(
+      diag::warn_return_typestate_for_unconsumable_type) << TypeName);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2335,9 +2351,8 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
   void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
                                    StringRef ObservedState) override {
 
-    PartialDiagnosticAt Warning(Loc,
-                                S.PDiag(diag::warn_return_typestate_mismatch)
-                                    << ExpectedState << ObservedState);
+    PartialDiagnosticAt Warning(Loc, S.PDiag(
+      diag::warn_return_typestate_mismatch) << ExpectedState << ObservedState);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2345,9 +2360,8 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
   void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State,
                                    SourceLocation Loc) override {
 
-    PartialDiagnosticAt Warning(Loc,
-                                
S.PDiag(diag::warn_use_of_temp_in_invalid_state)
-                                    << MethodName << State);
+    PartialDiagnosticAt Warning(Loc, S.PDiag(
+      diag::warn_use_of_temp_in_invalid_state) << MethodName << State);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2355,9 +2369,8 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
   void warnUseInInvalidState(StringRef MethodName, StringRef VariableName,
                              StringRef State, SourceLocation Loc) override {
 
-    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state)
-                                         << MethodName << VariableName
-                                         << State);
+    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state) 
<<
+                                MethodName << VariableName << State);
 
     Warnings.emplace_back(std::move(Warning), OptionalNotes());
   }
@@ -2373,7 +2386,7 @@ class ConsumedWarningsHandler : public 
ConsumedWarningsHandlerBase {
 namespace {
 class UnsafeBufferUsageReporter : public UnsafeBufferUsageHandler {
   Sema &S;
-  bool SuggestSuggestions; // Recommend -fsafe-buffer-usage-suggestions?
+  bool SuggestSuggestions;  // Recommend -fsafe-buffer-usage-suggestions?
 
   // Lists as a string the names of variables in `VarGroupForVD` except for 
`VD`
   // itself:
@@ -2412,7 +2425,7 @@ class UnsafeBufferUsageReporter : public 
UnsafeBufferUsageHandler {
 
 public:
   UnsafeBufferUsageReporter(Sema &S, bool SuggestSuggestions)
-      : S(S), SuggestSuggestions(SuggestSuggestions) {}
+    : S(S), SuggestSuggestions(SuggestSuggestions) {}
 
   void handleUnsafeOperation(const Stmt *Operation, bool IsRelatedToDecl,
                              ASTContext &Ctx) override {
@@ -2589,7 +2602,7 @@ class UnsafeBufferUsageReporter : public 
UnsafeBufferUsageHandler {
 
 #ifndef NDEBUG
     if (areDebugNotesRequested())
-      for (const DebugNote &Note : DebugNotesByVar[Variable])
+      for (const DebugNote &Note: DebugNotesByVar[Variable])
         S.Diag(Note.first, diag::note_safe_buffer_debug_mode) << Note.second;
 #endif
   }
@@ -2616,12 +2629,6 @@ class UnsafeBufferUsageReporter : public 
UnsafeBufferUsageHandler {
     return S.Diags.isIgnored(diag::warn_unsafe_buffer_libc_call, Loc);
   }
 
-  bool ignoreUnsafeBufferInStaticSizedArray(
-      const SourceLocation &Loc) const override {
-    return S.Diags.isIgnored(
-        diag::warn_unsafe_buffer_usage_in_static_sized_array, Loc);
-  }
-
   // Returns the text representation of clang::unsafe_buffer_usage attribute.
   // `WSSuffix` holds customized "white-space"s, e.g., newline or whilespace
   // characters.
@@ -2691,7 +2698,8 @@ sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema 
&s)
       MaxCFGBlocksPerFunction(0), NumUninitAnalysisFunctions(0),
       NumUninitAnalysisVariables(0), MaxUninitAnalysisVariablesPerFunction(0),
       NumUninitAnalysisBlockVisits(0),
-      MaxUninitAnalysisBlockVisitsPerFunction(0) {}
+      MaxUninitAnalysisBlockVisitsPerFunction(0) {
+}
 
 // We need this here for unique_ptr with forward declared class.
 sema::AnalysisBasedWarnings::~AnalysisBasedWarnings() = default;
@@ -2935,7 +2943,7 @@ LifetimeSafetyTUAnalysis(Sema &S, TranslationUnitDecl *TU,
 }
 
 void clang::sema::AnalysisBasedWarnings::IssueWarnings(
-    TranslationUnitDecl *TU) {
+     TranslationUnitDecl *TU) {
   if (!TU)
     return; // This is unexpected, give up quietly.
 
@@ -2949,7 +2957,7 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
 
   // UnsafeBufferUsage analysis settings.
   bool UnsafeBufferUsageCanEmitSuggestions = S.getLangOpts().CPlusPlus20;
-  bool UnsafeBufferUsageShouldEmitSuggestions = // Should != Can.
+  bool UnsafeBufferUsageShouldEmitSuggestions =  // Should != Can.
       UnsafeBufferUsageCanEmitSuggestions &&
       DiagOpts.ShowSafeBufferUsageSuggestions;
   bool UnsafeBufferUsageShouldSuggestSuggestions =
@@ -3057,13 +3065,13 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
     AC.getCFGBuildOptions().setAllAlwaysAdd();
   } else {
     AC.getCFGBuildOptions()
-        .setAlwaysAdd(Stmt::BinaryOperatorClass)
-        .setAlwaysAdd(Stmt::CompoundAssignOperatorClass)
-        .setAlwaysAdd(Stmt::BlockExprClass)
-        .setAlwaysAdd(Stmt::CStyleCastExprClass)
-        .setAlwaysAdd(Stmt::DeclRefExprClass)
-        .setAlwaysAdd(Stmt::ImplicitCastExprClass)
-        .setAlwaysAdd(Stmt::UnaryOperatorClass);
+      .setAlwaysAdd(Stmt::BinaryOperatorClass)
+      .setAlwaysAdd(Stmt::CompoundAssignOperatorClass)
+      .setAlwaysAdd(Stmt::BlockExprClass)
+      .setAlwaysAdd(Stmt::CStyleCastExprClass)
+      .setAlwaysAdd(Stmt::DeclRefExprClass)
+      .setAlwaysAdd(Stmt::ImplicitCastExprClass)
+      .setAlwaysAdd(Stmt::UnaryOperatorClass);
   }
   if (EnableLifetimeSafetyAnalysis) {
     AC.getCFGBuildOptions().AddLifetime = true;
@@ -3145,10 +3153,12 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
         ++NumUninitAnalysisFunctions;
         NumUninitAnalysisVariables += stats.NumVariablesAnalyzed;
         NumUninitAnalysisBlockVisits += stats.NumBlockVisits;
-        MaxUninitAnalysisVariablesPerFunction = std::max(
-            MaxUninitAnalysisVariablesPerFunction, stats.NumVariablesAnalyzed);
-        MaxUninitAnalysisBlockVisitsPerFunction = std::max(
-            MaxUninitAnalysisBlockVisitsPerFunction, stats.NumBlockVisits);
+        MaxUninitAnalysisVariablesPerFunction =
+            std::max(MaxUninitAnalysisVariablesPerFunction,
+                     stats.NumVariablesAnalyzed);
+        MaxUninitAnalysisBlockVisitsPerFunction =
+            std::max(MaxUninitAnalysisBlockVisitsPerFunction,
+                     stats.NumBlockVisits);
       }
     }
   }
@@ -3186,6 +3196,7 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
       !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, D->getBeginLoc()))
     diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap());
 
+
   // Check for infinite self-recursion in functions
   if (!Diags.isIgnored(diag::warn_infinite_recursive_function,
                        D->getBeginLoc())) {
@@ -3216,8 +3227,8 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
       // If we successfully built a CFG for this context, record some more
       // detail information about it.
       NumCFGBlocks += cfg->getNumBlockIDs();
-      MaxCFGBlocksPerFunction =
-          std::max(MaxCFGBlocksPerFunction, cfg->getNumBlockIDs());
+      MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction,
+                                         cfg->getNumBlockIDs());
     } else {
       ++NumFunctionsWithBadCFGs;
     }
@@ -3229,7 +3240,7 @@ void clang::sema::AnalysisBasedWarnings::PrintStats() 
const {
 
   unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs;
   unsigned AvgCFGBlocksPerFunction =
-      !NumCFGsBuilt ? 0 : NumCFGBlocks / NumCFGsBuilt;
+      !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt;
   llvm::errs() << NumFunctionsAnalyzed << " functions analyzed ("
                << NumFunctionsWithBadCFGs << " w/o CFGs).\n"
                << "  " << NumCFGBlocks << " CFG blocks built.\n"
@@ -3238,14 +3249,10 @@ void clang::sema::AnalysisBasedWarnings::PrintStats() 
const {
                << "  " << MaxCFGBlocksPerFunction
                << " max CFG blocks per function.\n";
 
-  unsigned AvgUninitVariablesPerFunction =
-      !NumUninitAnalysisFunctions
-          ? 0
-          : NumUninitAnalysisVariables / NumUninitAnalysisFunctions;
-  unsigned AvgUninitBlockVisitsPerFunction =
-      !NumUninitAnalysisFunctions
-          ? 0
-          : NumUninitAnalysisBlockVisits / NumUninitAnalysisFunctions;
+  unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0
+      : NumUninitAnalysisVariables/NumUninitAnalysisFunctions;
+  unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0
+      : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions;
   llvm::errs() << NumUninitAnalysisFunctions
                << " functions analyzed for uninitialiazed variables\n"
                << "  " << NumUninitAnalysisVariables << " variables 
analyzed.\n"

>From be7d92a1f658efac9862cb26cd50f6cba57e7d08 Mon Sep 17 00:00:00 2001
From: mxms <[email protected]>
Date: Fri, 16 Jan 2026 19:44:31 +0000
Subject: [PATCH 4/4] Revert/fix

---
 clang/lib/Sema/AnalysisBasedWarnings.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp 
b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 56d7db649afbe..ab6fc49ef8233 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2629,6 +2629,12 @@ class UnsafeBufferUsageReporter : public 
UnsafeBufferUsageHandler {
     return S.Diags.isIgnored(diag::warn_unsafe_buffer_libc_call, Loc);
   }
 
+  bool ignoreUnsafeBufferInStaticSizedArray(
+      const SourceLocation &Loc) const override {
+    return S.Diags.isIgnored(
+        diag::warn_unsafe_buffer_usage_in_static_sized_array, Loc);
+  }
+
   // Returns the text representation of clang::unsafe_buffer_usage attribute.
   // `WSSuffix` holds customized "white-space"s, e.g., newline or whilespace
   // characters.

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to