[clang] 7a0900f - [-Wunsafe-buffer-usage] Remove an unnecessary const-qualifier

David Blaikie via cfe-commits cfe-commits at lists.llvm.org
Tue May 16 14:54:12 PDT 2023


Oh, btw, you can use git-clang-format to only reformat the parts of the
code that have changed. That'd probably be safe/good as a precommit hook,
but yeah, reformatting whole files is no good.

On Tue, May 16, 2023 at 2:53 PM David Blaikie <dblaikie at gmail.com> wrote:

> Thanks!
>
> On Mon, May 15, 2023 at 11:21 AM Ziqing Luo <ziqing at udel.edu> wrote:
>
>> Hi,
>>
>> It is, but sorry I didn't realize that I have a pre-commit hook that
>> clang-formats my patch.  This is why there are so many differences.
>> I will revert and re-commit this change.
>>
>> -ziqing
>>
>>
>>
>> On Mon, May 15, 2023 at 11:11 AM David Blaikie <dblaikie at gmail.com>
>> wrote:
>>
>>> Is this patch the right one for the commit message? This doesn't look
>>> like "removing an unnecessary const qualifier"
>>>
>>> On Fri, May 12, 2023 at 2:47 PM via cfe-commits <
>>> cfe-commits at lists.llvm.org> wrote:
>>>
>>>>
>>>> Author: ziqingluo-90
>>>> Date: 2023-05-12T14:46:56-07:00
>>>> New Revision: 7a0900fd3e2d34bc1d513a97cf8fbdc1754252d7
>>>>
>>>> URL:
>>>> https://github.com/llvm/llvm-project/commit/7a0900fd3e2d34bc1d513a97cf8fbdc1754252d7
>>>> DIFF:
>>>> https://github.com/llvm/llvm-project/commit/7a0900fd3e2d34bc1d513a97cf8fbdc1754252d7.diff
>>>>
>>>> LOG: [-Wunsafe-buffer-usage] Remove an unnecessary const-qualifier
>>>>
>>>> A follow-up change for 6d861d498de1320d22771c329ec69f9419ef06b7:
>>>> remove an unnecessary const-qualifier so that the code doesn't have to
>>>> remove the qualifier explicitly using `std::remove_const_t`, which
>>>> triggers a warning at some bots (e.g.,
>>>> https://lab.llvm.org/buildbot/#/builders/247/builds/4442).
>>>>
>>>> Added:
>>>>
>>>>
>>>> Modified:
>>>>     clang/include/clang/Sema/AnalysisBasedWarnings.h
>>>>     clang/lib/Sema/AnalysisBasedWarnings.cpp
>>>>
>>>> Removed:
>>>>
>>>>
>>>>
>>>>
>>>> ################################################################################
>>>> diff  --git a/clang/include/clang/Sema/AnalysisBasedWarnings.h
>>>> b/clang/include/clang/Sema/AnalysisBasedWarnings.h
>>>> index c73506894db9d..7d0fa9541c352 100644
>>>> --- a/clang/include/clang/Sema/AnalysisBasedWarnings.h
>>>> +++ b/clang/include/clang/Sema/AnalysisBasedWarnings.h
>>>> @@ -24,7 +24,7 @@ class FunctionDecl;
>>>>  class QualType;
>>>>  class Sema;
>>>>  namespace sema {
>>>> -  class FunctionScopeInfo;
>>>> +class FunctionScopeInfo;
>>>>  }
>>>>
>>>>  namespace sema {
>>>> @@ -38,6 +38,7 @@ class AnalysisBasedWarnings {
>>>>      unsigned enableCheckUnreachable : 1;
>>>>      unsigned enableThreadSafetyAnalysis : 1;
>>>>      unsigned enableConsumedAnalysis : 1;
>>>> +
>>>>    public:
>>>>      Policy();
>>>>      void disableCheckFallThrough() { enableCheckFallThrough = 0; }
>>>> @@ -51,7 +52,7 @@ class AnalysisBasedWarnings {
>>>>    std::unique_ptr<InterProceduralData> IPData;
>>>>
>>>>    enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 };
>>>> -  llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD;
>>>> +  llvm::DenseMap<const FunctionDecl *, VisitFlag> VisitedFD;
>>>>
>>>>    /// \name Statistics
>>>>    /// @{
>>>> @@ -93,11 +94,11 @@ class AnalysisBasedWarnings {
>>>>    AnalysisBasedWarnings(Sema &s);
>>>>    ~AnalysisBasedWarnings();
>>>>
>>>> -  void IssueWarnings(Policy P, FunctionScopeInfo *fscope,
>>>> -                     const Decl *D, QualType BlockType);
>>>> +  void IssueWarnings(Policy P, FunctionScopeInfo *fscope, const Decl
>>>> *D,
>>>> +                     QualType BlockType);
>>>>
>>>>    // Issue warnings that require whole-translation-unit analysis.
>>>> -  void IssueWarnings(const TranslationUnitDecl *D);
>>>> +  void IssueWarnings(TranslationUnitDecl *D);
>>>>
>>>>    Policy getDefaultPolicy() { return DefaultPolicy; }
>>>>
>>>>
>>>> diff  --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp
>>>> b/clang/lib/Sema/AnalysisBasedWarnings.cpp
>>>> index 4d96f3b9ab32b..c2b6d362d966d 100644
>>>> --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
>>>> +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
>>>> @@ -1,4 +1,5 @@
>>>> -//=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis
>>>> -*- C++ -*-=//
>>>> +//=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis
>>>> -*- C++
>>>> +//-*-=//
>>>>  //
>>>>  // Part of the LLVM Project, under the Apache License v2.0 with LLVM
>>>> Exceptions.
>>>>  // See https://llvm.org/LICENSE.txt for license information.
>>>> @@ -26,7 +27,6 @@
>>>>  #include "clang/AST/StmtCXX.h"
>>>>  #include "clang/AST/StmtObjC.h"
>>>>  #include "clang/AST/StmtVisitor.h"
>>>> -#include "clang/AST/RecursiveASTVisitor.h"
>>>>  #include "clang/AST/Type.h"
>>>>  #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
>>>>  #include "clang/Analysis/Analyses/CalledOnceCheck.h"
>>>> @@ -64,61 +64,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;
>>>> -
>>>> -      // 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;
>>>> -      }
>>>> +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;
>>>> +
>>>> +    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.
>>>> @@ -278,7 +277,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())
>>>> @@ -314,10 +314,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.
>>>> @@ -336,7 +335,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;
>>>> @@ -359,8 +359,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();
>>>> @@ -377,10 +377,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) {
>>>> @@ -413,13 +414,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())
>>>> @@ -472,7 +474,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;
>>>>
>>>> @@ -546,14 +548,12 @@ struct CheckFallThroughDiagnostics {
>>>>    static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func)
>>>> {
>>>>      CheckFallThroughDiagnostics D;
>>>>      D.FuncLoc = Func->getLocation();
>>>> -    D.diag_MaybeFallThrough_HasNoReturn =
>>>> -      diag::warn_falloff_noreturn_function;
>>>> +    D.diag_MaybeFallThrough_HasNoReturn =
>>>> diag::warn_falloff_noreturn_function;
>>>>      D.diag_MaybeFallThrough_ReturnsNonVoid =
>>>> -      diag::warn_maybe_falloff_nonvoid_function;
>>>> -    D.diag_AlwaysFallThrough_HasNoReturn =
>>>> -      diag::warn_falloff_noreturn_function;
>>>> +        diag::warn_maybe_falloff_nonvoid_function;
>>>> +    D.diag_AlwaysFallThrough_HasNoReturn =
>>>> diag::warn_falloff_noreturn_function;
>>>>      D.diag_AlwaysFallThrough_ReturnsNonVoid =
>>>> -      diag::warn_falloff_nonvoid_function;
>>>> +        diag::warn_falloff_nonvoid_function;
>>>>
>>>>      // Don't suggest that virtual functions be marked "noreturn",
>>>> since they
>>>>      // might be overridden by non-noreturn functions.
>>>> @@ -567,8 +567,7 @@ struct CheckFallThroughDiagnostics {
>>>>        isTemplateInstantiation = Function->isTemplateInstantiation();
>>>>
>>>>      if (!isVirtualMethod && !isTemplateInstantiation)
>>>> -      D.diag_NeverFallThroughOrReturn =
>>>> -        diag::warn_suggest_noreturn_function;
>>>> +      D.diag_NeverFallThroughOrReturn =
>>>> diag::warn_suggest_noreturn_function;
>>>>      else
>>>>        D.diag_NeverFallThroughOrReturn = 0;
>>>>
>>>> @@ -593,13 +592,12 @@ struct CheckFallThroughDiagnostics {
>>>>    static CheckFallThroughDiagnostics MakeForBlock() {
>>>>      CheckFallThroughDiagnostics D;
>>>>      D.diag_MaybeFallThrough_HasNoReturn =
>>>> -      diag::err_noreturn_block_has_return_expr;
>>>> +        diag::err_noreturn_block_has_return_expr;
>>>>      D.diag_MaybeFallThrough_ReturnsNonVoid =
>>>> -      diag::err_maybe_falloff_nonvoid_block;
>>>> +        diag::err_maybe_falloff_nonvoid_block;
>>>>      D.diag_AlwaysFallThrough_HasNoReturn =
>>>> -      diag::err_noreturn_block_has_return_expr;
>>>> -    D.diag_AlwaysFallThrough_ReturnsNonVoid =
>>>> -      diag::err_falloff_nonvoid_block;
>>>> +        diag::err_noreturn_block_has_return_expr;
>>>> +    D.diag_AlwaysFallThrough_ReturnsNonVoid =
>>>> diag::err_falloff_nonvoid_block;
>>>>      D.diag_NeverFallThroughOrReturn = 0;
>>>>      D.funMode = Block;
>>>>      return D;
>>>> @@ -608,13 +606,12 @@ struct CheckFallThroughDiagnostics {
>>>>    static CheckFallThroughDiagnostics MakeForLambda() {
>>>>      CheckFallThroughDiagnostics D;
>>>>      D.diag_MaybeFallThrough_HasNoReturn =
>>>> -      diag::err_noreturn_lambda_has_return_expr;
>>>> +        diag::err_noreturn_lambda_has_return_expr;
>>>>      D.diag_MaybeFallThrough_ReturnsNonVoid =
>>>> -      diag::warn_maybe_falloff_nonvoid_lambda;
>>>> +        diag::warn_maybe_falloff_nonvoid_lambda;
>>>>      D.diag_AlwaysFallThrough_HasNoReturn =
>>>> -      diag::err_noreturn_lambda_has_return_expr;
>>>> -    D.diag_AlwaysFallThrough_ReturnsNonVoid =
>>>> -      diag::warn_falloff_nonvoid_lambda;
>>>> +        diag::err_noreturn_lambda_has_return_expr;
>>>> +    D.diag_AlwaysFallThrough_ReturnsNonVoid =
>>>> diag::warn_falloff_nonvoid_lambda;
>>>>      D.diag_NeverFallThroughOrReturn = 0;
>>>>      D.funMode = Lambda;
>>>>      return D;
>>>> @@ -666,14 +663,12 @@ static void CheckFallThroughForBody(Sema &S,
>>>> const Decl *D, const Stmt *Body,
>>>>      else
>>>>        ReturnsVoid = FD->getReturnType()->isVoidType();
>>>>      HasNoReturn = FD->isNoReturn();
>>>> -  }
>>>> -  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())
>>>> @@ -685,7 +680,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();
>>>>    auto EmitDiag = [&](SourceLocation Loc, unsigned DiagID) {
>>>>      if (IsCoroutine)
>>>> @@ -700,34 +695,34 @@ static void CheckFallThroughForBody(Sema &S,
>>>> const Decl *D, const Stmt *Body,
>>>>
>>>>    // Either in a function body compound statement, or a
>>>> function-try-block.
>>>>    switch (CheckFallThrough(AC)) {
>>>> -    case UnknownFallThrough:
>>>> -      break;
>>>> +  case UnknownFallThrough:
>>>> +    break;
>>>>
>>>> -    case MaybeFallThrough:
>>>> -      if (HasNoReturn)
>>>> -        EmitDiag(RBrace, CD.diag_MaybeFallThrough_HasNoReturn);
>>>> -      else if (!ReturnsVoid)
>>>> -        EmitDiag(RBrace, CD.diag_MaybeFallThrough_ReturnsNonVoid);
>>>> -      break;
>>>> -    case AlwaysFallThrough:
>>>> -      if (HasNoReturn)
>>>> -        EmitDiag(RBrace, CD.diag_AlwaysFallThrough_HasNoReturn);
>>>> -      else if (!ReturnsVoid)
>>>> -        EmitDiag(RBrace, CD.diag_AlwaysFallThrough_ReturnsNonVoid);
>>>> -      break;
>>>> -    case NeverFallThroughOrReturn:
>>>> -      if (ReturnsVoid && !HasNoReturn &&
>>>> CD.diag_NeverFallThroughOrReturn) {
>>>> -        if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
>>>> -          S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 0 << FD;
>>>> -        } else if (const ObjCMethodDecl *MD =
>>>> dyn_cast<ObjCMethodDecl>(D)) {
>>>> -          S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 1 << MD;
>>>> -        } else {
>>>> -          S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn);
>>>> -        }
>>>> +  case MaybeFallThrough:
>>>> +    if (HasNoReturn)
>>>> +      EmitDiag(RBrace, CD.diag_MaybeFallThrough_HasNoReturn);
>>>> +    else if (!ReturnsVoid)
>>>> +      EmitDiag(RBrace, CD.diag_MaybeFallThrough_ReturnsNonVoid);
>>>> +    break;
>>>> +  case AlwaysFallThrough:
>>>> +    if (HasNoReturn)
>>>> +      EmitDiag(RBrace, CD.diag_AlwaysFallThrough_HasNoReturn);
>>>> +    else if (!ReturnsVoid)
>>>> +      EmitDiag(RBrace, CD.diag_AlwaysFallThrough_ReturnsNonVoid);
>>>> +    break;
>>>> +  case NeverFallThroughOrReturn:
>>>> +    if (ReturnsVoid && !HasNoReturn &&
>>>> CD.diag_NeverFallThroughOrReturn) {
>>>> +      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
>>>> +        S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 0 << FD;
>>>> +      } else if (const ObjCMethodDecl *MD =
>>>> dyn_cast<ObjCMethodDecl>(D)) {
>>>> +        S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 1 << MD;
>>>> +      } else {
>>>> +        S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn);
>>>>        }
>>>> -      break;
>>>> -    case NeverFallThrough:
>>>> -      break;
>>>> +    }
>>>> +    break;
>>>> +  case NeverFallThrough:
>>>> +    break;
>>>>    }
>>>>  }
>>>>
>>>> @@ -747,7 +742,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.
>>>> @@ -770,8 +765,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 ");
>>>> @@ -793,16 +787,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(
>>>> @@ -838,10 +832,10 @@ static void DiagUninitUse(Sema &S, const VarDecl
>>>> *VD, const UninitUse &Use,
>>>>    case UninitUse::AfterDecl:
>>>>    case UninitUse::AfterCall:
>>>>      S.Diag(VD->getLocation(), diag::warn_sometimes_uninit_var)
>>>> -      << VD->getDeclName() << IsCapturedByBlock
>>>> -      << (Use.getKind() == UninitUse::AfterDecl ? 4 : 5)
>>>> -      << const_cast<DeclContext*>(VD->getLexicalDeclContext())
>>>> -      << VD->getSourceRange();
>>>> +        << VD->getDeclName() << IsCapturedByBlock
>>>> +        << (Use.getKind() == UninitUse::AfterDecl ? 4 : 5)
>>>> +        << const_cast<DeclContext *>(VD->getLexicalDeclContext())
>>>> +        << VD->getSourceRange();
>>>>      S.Diag(Use.getUser()->getBeginLoc(), diag::note_uninit_var_use)
>>>>          << IsCapturedByBlock << Use.getUser()->getSourceRange();
>>>>      return;
>>>> @@ -870,9 +864,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) {
>>>> @@ -888,8 +882,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: {
>>>> @@ -898,8 +892,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: {
>>>> @@ -974,13 +968,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;
>>>>    }
>>>> @@ -1055,81 +1049,77 @@ static bool DiagnoseUninitializedUse(Sema &S,
>>>> const VarDecl *VD,
>>>>  }
>>>>
>>>>  namespace {
>>>> -  class FallthroughMapper : public
>>>> RecursiveASTVisitor<FallthroughMapper> {
>>>> -  public:
>>>> -    FallthroughMapper(Sema &S)
>>>> -      : FoundSwitchStatements(false),
>>>> -        S(S) {
>>>> -    }
>>>> +class FallthroughMapper : public
>>>> RecursiveASTVisitor<FallthroughMapper> {
>>>> +public:
>>>> +  FallthroughMapper(Sema &S) : FoundSwitchStatements(false), S(S) {}
>>>>
>>>> -    bool foundSwitchStatements() const { return FoundSwitchStatements;
>>>> }
>>>> +  bool foundSwitchStatements() const { return FoundSwitchStatements; }
>>>>
>>>> -    void markFallthroughVisited(const AttributedStmt *Stmt) {
>>>> -      bool Found = FallthroughStmts.erase(Stmt);
>>>> -      assert(Found);
>>>> -      (void)Found;
>>>> -    }
>>>> +  void markFallthroughVisited(const AttributedStmt *Stmt) {
>>>> +    bool Found = FallthroughStmts.erase(Stmt);
>>>> +    assert(Found);
>>>> +    (void)Found;
>>>> +  }
>>>> +
>>>> +  typedef llvm::SmallPtrSet<const AttributedStmt *, 8> AttrStmts;
>>>> +
>>>> +  const AttrStmts &getFallthroughStmts() const { return
>>>> FallthroughStmts; }
>>>>
>>>> -    typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts;
>>>> +  void fillReachableBlocks(CFG *Cfg) {
>>>> +    assert(ReachableBlocks.empty() && "ReachableBlocks already
>>>> filled");
>>>> +    std::deque<const CFGBlock *> BlockQueue;
>>>>
>>>> -    const AttrStmts &getFallthroughStmts() const {
>>>> -      return FallthroughStmts;
>>>> +    ReachableBlocks.insert(&Cfg->getEntry());
>>>> +    BlockQueue.push_back(&Cfg->getEntry());
>>>> +    // Mark all case blocks reachable to avoid problems with switching
>>>> on
>>>> +    // constants, covered enums, etc.
>>>> +    // These blocks can contain fall-through annotations, and we don't
>>>> want to
>>>> +    // issue a warn_fallthrough_attr_unreachable for them.
>>>> +    for (const auto *B : *Cfg) {
>>>> +      const Stmt *L = B->getLabel();
>>>> +      if (L && isa<SwitchCase>(L) && ReachableBlocks.insert(B).second)
>>>> +        BlockQueue.push_back(B);
>>>>      }
>>>>
>>>> -    void fillReachableBlocks(CFG *Cfg) {
>>>> -      assert(ReachableBlocks.empty() && "ReachableBlocks already
>>>> filled");
>>>> -      std::deque<const CFGBlock *> BlockQueue;
>>>> -
>>>> -      ReachableBlocks.insert(&Cfg->getEntry());
>>>> -      BlockQueue.push_back(&Cfg->getEntry());
>>>> -      // Mark all case blocks reachable to avoid problems with
>>>> switching on
>>>> -      // constants, covered enums, etc.
>>>> -      // These blocks can contain fall-through annotations, and we
>>>> don't want to
>>>> -      // issue a warn_fallthrough_attr_unreachable for them.
>>>> -      for (const auto *B : *Cfg) {
>>>> -        const Stmt *L = B->getLabel();
>>>> -        if (L && isa<SwitchCase>(L) &&
>>>> ReachableBlocks.insert(B).second)
>>>> +    while (!BlockQueue.empty()) {
>>>> +      const CFGBlock *P = BlockQueue.front();
>>>> +      BlockQueue.pop_front();
>>>> +      for (const CFGBlock *B : P->succs()) {
>>>> +        if (B && ReachableBlocks.insert(B).second)
>>>>            BlockQueue.push_back(B);
>>>>        }
>>>> -
>>>> -      while (!BlockQueue.empty()) {
>>>> -        const CFGBlock *P = BlockQueue.front();
>>>> -        BlockQueue.pop_front();
>>>> -        for (const CFGBlock *B : P->succs()) {
>>>> -          if (B && ReachableBlocks.insert(B).second)
>>>> -            BlockQueue.push_back(B);
>>>> -        }
>>>> -      }
>>>>      }
>>>> +  }
>>>>
>>>> -    bool checkFallThroughIntoBlock(const CFGBlock &B, int
>>>> &AnnotatedCnt,
>>>> -                                   bool IsTemplateInstantiation) {
>>>> -      assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
>>>> +  bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt,
>>>> +                                 bool IsTemplateInstantiation) {
>>>> +    assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
>>>>
>>>> -      int UnannotatedCnt = 0;
>>>> -      AnnotatedCnt = 0;
>>>> +    int UnannotatedCnt = 0;
>>>> +    AnnotatedCnt = 0;
>>>>
>>>> -      std::deque<const CFGBlock*> BlockQueue(B.pred_begin(),
>>>> B.pred_end());
>>>> -      while (!BlockQueue.empty()) {
>>>> -        const CFGBlock *P = BlockQueue.front();
>>>> -        BlockQueue.pop_front();
>>>> -        if (!P) continue;
>>>> +    std::deque<const CFGBlock *> BlockQueue(B.pred_begin(),
>>>> B.pred_end());
>>>> +    while (!BlockQueue.empty()) {
>>>> +      const CFGBlock *P = BlockQueue.front();
>>>> +      BlockQueue.pop_front();
>>>> +      if (!P)
>>>> +        continue;
>>>>
>>>> -        const Stmt *Term = P->getTerminatorStmt();
>>>> -        if (Term && isa<SwitchStmt>(Term))
>>>> -          continue; // Switch statement, good.
>>>> +      const Stmt *Term = P->getTerminatorStmt();
>>>> +      if (Term && isa<SwitchStmt>(Term))
>>>> +        continue; // Switch statement, good.
>>>>
>>>> -        const SwitchCase *SW =
>>>> dyn_cast_or_null<SwitchCase>(P->getLabel());
>>>> -        if (SW && SW->getSubStmt() == B.getLabel() && P->begin() ==
>>>> P->end())
>>>> -          continue; // Previous case label has no statements, good.
>>>> +      const SwitchCase *SW =
>>>> dyn_cast_or_null<SwitchCase>(P->getLabel());
>>>> +      if (SW && SW->getSubStmt() == B.getLabel() && P->begin() ==
>>>> P->end())
>>>> +        continue; // Previous case label has no statements, good.
>>>>
>>>> -        const LabelStmt *L =
>>>> dyn_cast_or_null<LabelStmt>(P->getLabel());
>>>> -        if (L && L->getSubStmt() == B.getLabel() && P->begin() ==
>>>> P->end())
>>>> -          continue; // Case label is preceded with a normal label,
>>>> good.
>>>> +      const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel());
>>>> +      if (L && L->getSubStmt() == B.getLabel() && P->begin() ==
>>>> P->end())
>>>> +        continue; // Case label is preceded with a normal label, good.
>>>>
>>>> -        if (!ReachableBlocks.count(P)) {
>>>> -          for (const CFGElement &Elem : llvm::reverse(*P)) {
>>>> -            if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>()) {
>>>> +      if (!ReachableBlocks.count(P)) {
>>>> +        for (const CFGElement &Elem : llvm::reverse(*P)) {
>>>> +          if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>()) {
>>>>              if (const AttributedStmt *AS =
>>>> asFallThroughAttr(CS->getStmt())) {
>>>>                // Don't issue a warning for an unreachable fallthrough
>>>>                // attribute in template instantiations as it may not be
>>>> @@ -1142,110 +1132,109 @@ namespace {
>>>>                break;
>>>>              }
>>>>              // 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;
>>>> -        }
>>>> -
>>>> -        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 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;
>>>> +      }
>>>>
>>>> -        ++UnannotatedCnt;
>>>> +      const Stmt *LastStmt = getLastStmt(*P);
>>>> +      if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
>>>> +        markFallthroughVisited(AS);
>>>> +        ++AnnotatedCnt;
>>>> +        continue; // Fallthrough annotation, good.
>>>>        }
>>>> -      return !!UnannotatedCnt;
>>>> -    }
>>>>
>>>> -    // RecursiveASTVisitor setup.
>>>> -    bool shouldWalkTypesOfTypeLocs() const { return false; }
>>>> +      if (!LastStmt) { // This block contains no executable statements.
>>>> +        // Traverse its predecessors.
>>>> +        std::copy(P->pred_begin(), P->pred_end(),
>>>> +                  std::back_inserter(BlockQueue));
>>>> +        continue;
>>>> +      }
>>>>
>>>> -    bool VisitAttributedStmt(AttributedStmt *S) {
>>>> -      if (asFallThroughAttr(S))
>>>> -        FallthroughStmts.insert(S);
>>>> -      return true;
>>>> +      ++UnannotatedCnt;
>>>>      }
>>>> +    return !!UnannotatedCnt;
>>>> +  }
>>>>
>>>> -    bool VisitSwitchStmt(SwitchStmt *S) {
>>>> -      FoundSwitchStatements = true;
>>>> -      return true;
>>>> -    }
>>>> +  // RecursiveASTVisitor setup.
>>>> +  bool shouldWalkTypesOfTypeLocs() const { return false; }
>>>>
>>>> -    // We don't want to traverse local type declarations. We analyze
>>>> their
>>>> -    // methods separately.
>>>> -    bool TraverseDecl(Decl *D) { return true; }
>>>> +  bool VisitAttributedStmt(AttributedStmt *S) {
>>>> +    if (asFallThroughAttr(S))
>>>> +      FallthroughStmts.insert(S);
>>>> +    return true;
>>>> +  }
>>>>
>>>> -    // We analyze lambda bodies separately. Skip them here.
>>>> -    bool TraverseLambdaExpr(LambdaExpr *LE) {
>>>> -      // 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;
>>>> -    }
>>>> +  bool VisitSwitchStmt(SwitchStmt *S) {
>>>> +    FoundSwitchStatements = true;
>>>> +    return true;
>>>> +  }
>>>>
>>>> -  private:
>>>> +  // We don't want to traverse local type declarations. We analyze
>>>> their
>>>> +  // methods separately.
>>>> +  bool TraverseDecl(Decl *D) { 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;
>>>> -    }
>>>> +  // We analyze lambda bodies separately. Skip them here.
>>>> +  bool TraverseLambdaExpr(LambdaExpr *LE) {
>>>> +    // 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 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;
>>>> +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;
>>>> +  }
>>>>
>>>> -    bool FoundSwitchStatements;
>>>> -    AttrStmts FallthroughStmts;
>>>> -    Sema &S;
>>>> -    llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
>>>> -  };
>>>> +  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;
>>>> +  }
>>>> +
>>>> +  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().C2x;
>>>>
>>>> @@ -1360,13 +1349,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();
>>>>
>>>> @@ -1380,7 +1368,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;
>>>>      }
>>>> @@ -1437,12 +1425,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;
>>>> @@ -1473,12 +1456,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))
>>>> @@ -1643,7 +1621,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 ||
>>>> @@ -1839,10 +1817,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; }
>>>>
>>>> @@ -1904,24 +1882,24 @@ class ThreadSafetyReporter : public
>>>> clang::threadSafety::ThreadSafetyHandler {
>>>>                                   LockErrorKind LEK) 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;
>>>>
>>>> -    PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << Kind
>>>> -                                                               <<
>>>> LockName);
>>>> +    PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID)
>>>> +                                                   << Kind <<
>>>> LockName);
>>>>      Warnings.emplace_back(std::move(Warning),
>>>>                            makeLockedHereNote(LocLocked, Kind));
>>>>    }
>>>> @@ -1941,11 +1919,11 @@ class ThreadSafetyReporter : public
>>>> clang::threadSafety::ThreadSafetyHandler {
>>>>                           AccessKind AK, SourceLocation Loc) override {
>>>>      assert((POK == POK_VarAccess || POK == POK_VarDereference) &&
>>>>             "Only works for variables");
>>>> -    unsigned DiagID = POK == POK_VarAccess?
>>>> -                        diag::warn_variable_requires_any_lock:
>>>> -                        diag::warn_var_deref_requires_any_lock;
>>>> +    unsigned DiagID = POK == POK_VarAccess
>>>> +                          ? diag::warn_variable_requires_any_lock
>>>> +                          : diag::warn_var_deref_requires_any_lock;
>>>>      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
>>>> -      << D << getLockKindFromAccessKind(AK));
>>>> +                                         << D <<
>>>> getLockKindFromAccessKind(AK));
>>>>      Warnings.emplace_back(std::move(Warning), getNotes());
>>>>    }
>>>>
>>>> @@ -1956,25 +1934,24 @@ 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_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;
>>>>        }
>>>> -      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) {
>>>> @@ -1986,25 +1963,24 @@ 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_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;
>>>>        }
>>>> -      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));
>>>> @@ -2016,9 +1992,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());
>>>>    }
>>>>
>>>> @@ -2038,22 +2014,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;
>>>>    }
>>>>  };
>>>> @@ -2074,7 +2048,6 @@ class ConsumedWarningsHandler : public
>>>> ConsumedWarningsHandlerBase {
>>>>    DiagList Warnings;
>>>>
>>>>  public:
>>>> -
>>>>    ConsumedWarningsHandler(Sema &S) : S(S) {}
>>>>
>>>>    void emitDiagnostics() override {
>>>> @@ -2088,8 +2061,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());
>>>>    }
>>>> @@ -2099,9 +2072,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());
>>>>    }
>>>> @@ -2109,16 +2082,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());
>>>>    }
>>>> @@ -2126,8 +2101,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());
>>>>    }
>>>> @@ -2135,8 +2111,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());
>>>>    }
>>>> @@ -2144,8 +2121,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());
>>>>    }
>>>> @@ -2340,7 +2318,7 @@ class CallableVisitor : public
>>>> RecursiveASTVisitor<CallableVisitor> {
>>>>  };
>>>>
>>>>  void clang::sema::AnalysisBasedWarnings::IssueWarnings(
>>>> -    const TranslationUnitDecl *TU) {
>>>> +    TranslationUnitDecl *TU) {
>>>>    if (!TU)
>>>>      return; // This is unexpected, give up quietly.
>>>>
>>>> @@ -2370,9 +2348,7 @@ void
>>>> clang::sema::AnalysisBasedWarnings::IssueWarnings(
>>>>    // reasoning. Check if any of them is enabled at all before scanning
>>>> the AST:
>>>>    if (!Diags.isIgnored(diag::warn_unsafe_buffer_operation,
>>>> SourceLocation()) ||
>>>>        !Diags.isIgnored(diag::warn_unsafe_buffer_variable,
>>>> SourceLocation())) {
>>>> -    CallableVisitor(CallAnalyzers)
>>>> -        .TraverseTranslationUnitDecl(
>>>> -            std::remove_const_t<TranslationUnitDecl *>(TU));
>>>> +    CallableVisitor(CallAnalyzers).TraverseTranslationUnitDecl(TU);
>>>>    }
>>>>  }
>>>>
>>>> @@ -2430,16 +2406,15 @@ void
>>>> clang::sema::AnalysisBasedWarnings::IssueWarnings(
>>>>        P.enableConsumedAnalysis) {
>>>>      // Unreachable code analysis and thread safety require a
>>>> linearized CFG.
>>>>      AC.getCFGBuildOptions().setAllAlwaysAdd();
>>>> -  }
>>>> -  else {
>>>> +  } 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);
>>>>    }
>>>>
>>>>    // Install the logical handler.
>>>> @@ -2493,15 +2468,14 @@ void
>>>> clang::sema::AnalysisBasedWarnings::IssueWarnings(
>>>>    // Warning: check missing 'return'
>>>>    if (P.enableCheckFallThrough) {
>>>>      const CheckFallThroughDiagnostics &CD =
>>>> -        (isa<BlockDecl>(D)
>>>> -             ? CheckFallThroughDiagnostics::MakeForBlock()
>>>> -             : (isa<CXXMethodDecl>(D) &&
>>>> -                cast<CXXMethodDecl>(D)->getOverloadedOperator() ==
>>>> OO_Call &&
>>>> -                cast<CXXMethodDecl>(D)->getParent()->isLambda())
>>>> -                   ? CheckFallThroughDiagnostics::MakeForLambda()
>>>> -                   : (fscope->isCoroutine()
>>>> -                          ?
>>>> CheckFallThroughDiagnostics::MakeForCoroutine(D)
>>>> -                          :
>>>> CheckFallThroughDiagnostics::MakeForFunction(D)));
>>>> +        (isa<BlockDecl>(D) ?
>>>> CheckFallThroughDiagnostics::MakeForBlock()
>>>> +         : (isa<CXXMethodDecl>(D) &&
>>>> +            cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call
>>>> &&
>>>> +            cast<CXXMethodDecl>(D)->getParent()->isLambda())
>>>> +             ? CheckFallThroughDiagnostics::MakeForLambda()
>>>> +             : (fscope->isCoroutine()
>>>> +                    ? CheckFallThroughDiagnostics::MakeForCoroutine(D)
>>>> +                    :
>>>> CheckFallThroughDiagnostics::MakeForFunction(D)));
>>>>      CheckFallThroughForBody(S, D, Body, BlockType, CD, AC, fscope);
>>>>    }
>>>>
>>>> @@ -2555,12 +2529,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);
>>>>        }
>>>>      }
>>>>    }
>>>> @@ -2589,7 +2561,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())) {
>>>> @@ -2617,8 +2588,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;
>>>>      }
>>>> @@ -2630,7 +2601,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"
>>>> @@ -2639,10 +2610,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"
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> cfe-commits at lists.llvm.org
>>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>>
>>>
>>
>> --
>> Ziqing Luo, Ph.D.
>> Computer & Information Science Department
>> Verified Software Lab
>> University of Delaware
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230516/c4aafc42/attachment-0001.html>


More information about the cfe-commits mailing list