brintos

brintos / llvm-project-archived public Read only

0
0
Text · 116.7 KiB · 43d2b9a Raw
3207 lines · cpp
1//=== AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis ------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines analysis_warnings::[Policy,Executor].10// Together they are used by Sema to issue warnings based on inexpensive11// static analysis algorithms in libAnalysis.12//13//===----------------------------------------------------------------------===//14 15#include "clang/Sema/AnalysisBasedWarnings.h"16#include "clang/AST/Decl.h"17#include "clang/AST/DeclCXX.h"18#include "clang/AST/DeclObjC.h"19#include "clang/AST/DynamicRecursiveASTVisitor.h"20#include "clang/AST/EvaluatedExprVisitor.h"21#include "clang/AST/Expr.h"22#include "clang/AST/ExprCXX.h"23#include "clang/AST/ExprObjC.h"24#include "clang/AST/OperationKinds.h"25#include "clang/AST/ParentMap.h"26#include "clang/AST/StmtCXX.h"27#include "clang/AST/StmtObjC.h"28#include "clang/AST/Type.h"29#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"30#include "clang/Analysis/Analyses/CalledOnceCheck.h"31#include "clang/Analysis/Analyses/Consumed.h"32#include "clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h"33#include "clang/Analysis/Analyses/ReachableCode.h"34#include "clang/Analysis/Analyses/ThreadSafety.h"35#include "clang/Analysis/Analyses/UninitializedValues.h"36#include "clang/Analysis/Analyses/UnsafeBufferUsage.h"37#include "clang/Analysis/AnalysisDeclContext.h"38#include "clang/Analysis/CFG.h"39#include "clang/Analysis/CFGStmtMap.h"40#include "clang/Analysis/FlowSensitive/DataflowWorklist.h"41#include "clang/Basic/Diagnostic.h"42#include "clang/Basic/DiagnosticSema.h"43#include "clang/Basic/SourceLocation.h"44#include "clang/Basic/SourceManager.h"45#include "clang/Lex/Preprocessor.h"46#include "clang/Sema/ScopeInfo.h"47#include "clang/Sema/SemaInternal.h"48#include "llvm/ADT/ArrayRef.h"49#include "llvm/ADT/BitVector.h"50#include "llvm/ADT/DenseMap.h"51#include "llvm/ADT/MapVector.h"52#include "llvm/ADT/STLFunctionalExtras.h"53#include "llvm/ADT/SmallVector.h"54#include "llvm/ADT/StringRef.h"55#include "llvm/Support/Debug.h"56#include <algorithm>57#include <deque>58#include <iterator>59#include <optional>60 61using namespace clang;62 63//===----------------------------------------------------------------------===//64// Unreachable code analysis.65//===----------------------------------------------------------------------===//66 67namespace {68  class UnreachableCodeHandler : public reachable_code::Callback {69    Sema &S;70    SourceRange PreviousSilenceableCondVal;71 72  public:73    UnreachableCodeHandler(Sema &s) : S(s) {}74 75    void HandleUnreachable(reachable_code::UnreachableKind UK, SourceLocation L,76                           SourceRange SilenceableCondVal, SourceRange R1,77                           SourceRange R2, bool HasFallThroughAttr) override {78      // If the diagnosed code is `[[fallthrough]];` and79      // `-Wunreachable-code-fallthrough` is  enabled, suppress `code will never80      // be executed` warning to avoid generating diagnostic twice81      if (HasFallThroughAttr &&82          !S.getDiagnostics().isIgnored(diag::warn_unreachable_fallthrough_attr,83                                        SourceLocation()))84        return;85 86      // Avoid reporting multiple unreachable code diagnostics that are87      // triggered by the same conditional value.88      if (PreviousSilenceableCondVal.isValid() &&89          SilenceableCondVal.isValid() &&90          PreviousSilenceableCondVal == SilenceableCondVal)91        return;92      PreviousSilenceableCondVal = SilenceableCondVal;93 94      unsigned diag = diag::warn_unreachable;95      switch (UK) {96        case reachable_code::UK_Break:97          diag = diag::warn_unreachable_break;98          break;99        case reachable_code::UK_Return:100          diag = diag::warn_unreachable_return;101          break;102        case reachable_code::UK_Loop_Increment:103          diag = diag::warn_unreachable_loop_increment;104          break;105        case reachable_code::UK_Other:106          break;107      }108 109      S.Diag(L, diag) << R1 << R2;110 111      SourceLocation Open = SilenceableCondVal.getBegin();112      if (Open.isValid()) {113        SourceLocation Close = SilenceableCondVal.getEnd();114        Close = S.getLocForEndOfToken(Close);115        if (Close.isValid()) {116          S.Diag(Open, diag::note_unreachable_silence)117            << FixItHint::CreateInsertion(Open, "/* DISABLES CODE */ (")118            << FixItHint::CreateInsertion(Close, ")");119        }120      }121    }122  };123} // anonymous namespace124 125/// CheckUnreachable - Check for unreachable code.126static void CheckUnreachable(Sema &S, AnalysisDeclContext &AC) {127  // As a heuristic prune all diagnostics not in the main file.  Currently128  // the majority of warnings in headers are false positives.  These129  // are largely caused by configuration state, e.g. preprocessor130  // defined code, etc.131  //132  // Note that this is also a performance optimization.  Analyzing133  // headers many times can be expensive.134  if (!S.getSourceManager().isInMainFile(AC.getDecl()->getBeginLoc()))135    return;136 137  UnreachableCodeHandler UC(S);138  reachable_code::FindUnreachableCode(AC, S.getPreprocessor(), UC);139}140 141namespace {142/// Warn on logical operator errors in CFGBuilder143class LogicalErrorHandler : public CFGCallback {144  Sema &S;145 146public:147  LogicalErrorHandler(Sema &S) : S(S) {}148 149  static bool HasMacroID(const Expr *E) {150    if (E->getExprLoc().isMacroID())151      return true;152 153    // Recurse to children.154    for (const Stmt *SubStmt : E->children())155      if (const Expr *SubExpr = dyn_cast_or_null<Expr>(SubStmt))156        if (HasMacroID(SubExpr))157          return true;158 159    return false;160  }161 162  void logicAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) override {163    if (HasMacroID(B))164      return;165 166    unsigned DiagID = isAlwaysTrue167                          ? diag::warn_tautological_negation_or_compare168                          : diag::warn_tautological_negation_and_compare;169    SourceRange DiagRange = B->getSourceRange();170    S.Diag(B->getExprLoc(), DiagID) << DiagRange;171  }172 173  void compareAlwaysTrue(const BinaryOperator *B,174                         bool isAlwaysTrueOrFalse) override {175    if (HasMacroID(B))176      return;177 178    SourceRange DiagRange = B->getSourceRange();179    S.Diag(B->getExprLoc(), diag::warn_tautological_overlap_comparison)180        << DiagRange << isAlwaysTrueOrFalse;181  }182 183  void compareBitwiseEquality(const BinaryOperator *B,184                              bool isAlwaysTrue) override {185    if (HasMacroID(B))186      return;187 188    SourceRange DiagRange = B->getSourceRange();189    S.Diag(B->getExprLoc(), diag::warn_comparison_bitwise_always)190        << DiagRange << isAlwaysTrue;191  }192 193  void compareBitwiseOr(const BinaryOperator *B) override {194    if (HasMacroID(B))195      return;196 197    SourceRange DiagRange = B->getSourceRange();198    S.Diag(B->getExprLoc(), diag::warn_comparison_bitwise_or) << DiagRange;199  }200 201  static bool hasActiveDiagnostics(DiagnosticsEngine &Diags,202                                   SourceLocation Loc) {203    return !Diags.isIgnored(diag::warn_tautological_overlap_comparison, Loc) ||204           !Diags.isIgnored(diag::warn_comparison_bitwise_or, Loc) ||205           !Diags.isIgnored(diag::warn_tautological_negation_and_compare, Loc);206  }207};208} // anonymous namespace209 210//===----------------------------------------------------------------------===//211// Check for infinite self-recursion in functions212//===----------------------------------------------------------------------===//213 214// Returns true if the function is called anywhere within the CFGBlock.215// For member functions, the additional condition of being call from the216// this pointer is required.217static bool hasRecursiveCallInPath(const FunctionDecl *FD, CFGBlock &Block) {218  // Process all the Stmt's in this block to find any calls to FD.219  for (const auto &B : Block) {220    if (B.getKind() != CFGElement::Statement)221      continue;222 223    const CallExpr *CE = dyn_cast<CallExpr>(B.getAs<CFGStmt>()->getStmt());224    if (!CE || !CE->getCalleeDecl() ||225        CE->getCalleeDecl()->getCanonicalDecl() != FD)226      continue;227 228    // Skip function calls which are qualified with a templated class.229    if (const DeclRefExpr *DRE =230            dyn_cast<DeclRefExpr>(CE->getCallee()->IgnoreParenImpCasts()))231      if (NestedNameSpecifier NNS = DRE->getQualifier();232          NNS.getKind() == NestedNameSpecifier::Kind::Type)233        if (isa_and_nonnull<TemplateSpecializationType>(NNS.getAsType()))234          continue;235 236    const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE);237    if (!MCE || isa<CXXThisExpr>(MCE->getImplicitObjectArgument()) ||238        !MCE->getMethodDecl()->isVirtual())239      return true;240  }241  return false;242}243 244// Returns true if every path from the entry block passes through a call to FD.245static bool checkForRecursiveFunctionCall(const FunctionDecl *FD, CFG *cfg) {246  llvm::SmallPtrSet<CFGBlock *, 16> Visited;247  llvm::SmallVector<CFGBlock *, 16> WorkList;248  // Keep track of whether we found at least one recursive path.249  bool foundRecursion = false;250 251  const unsigned ExitID = cfg->getExit().getBlockID();252 253  // Seed the work list with the entry block.254  WorkList.push_back(&cfg->getEntry());255 256  while (!WorkList.empty()) {257    CFGBlock *Block = WorkList.pop_back_val();258 259    for (auto I = Block->succ_begin(), E = Block->succ_end(); I != E; ++I) {260      if (CFGBlock *SuccBlock = *I) {261        if (!Visited.insert(SuccBlock).second)262          continue;263 264        // Found a path to the exit node without a recursive call.265        if (ExitID == SuccBlock->getBlockID())266          return false;267 268        // If the successor block contains a recursive call, end analysis there.269        if (hasRecursiveCallInPath(FD, *SuccBlock)) {270          foundRecursion = true;271          continue;272        }273 274        WorkList.push_back(SuccBlock);275      }276    }277  }278  return foundRecursion;279}280 281static void checkRecursiveFunction(Sema &S, const FunctionDecl *FD,282                                   const Stmt *Body, AnalysisDeclContext &AC) {283  FD = FD->getCanonicalDecl();284 285  // Only run on non-templated functions and non-templated members of286  // templated classes.287  if (FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate &&288      FD->getTemplatedKind() != FunctionDecl::TK_MemberSpecialization)289    return;290 291  CFG *cfg = AC.getCFG();292  if (!cfg) return;293 294  // If the exit block is unreachable, skip processing the function.295  if (cfg->getExit().pred_empty())296    return;297 298  // Emit diagnostic if a recursive function call is detected for all paths.299  if (checkForRecursiveFunctionCall(FD, cfg))300    S.Diag(Body->getBeginLoc(), diag::warn_infinite_recursive_function);301}302 303//===----------------------------------------------------------------------===//304// Check for throw in a non-throwing function.305//===----------------------------------------------------------------------===//306 307/// Determine whether an exception thrown by E, unwinding from ThrowBlock,308/// can reach ExitBlock.309static bool throwEscapes(Sema &S, const CXXThrowExpr *E, CFGBlock &ThrowBlock,310                         CFG *Body) {311  SmallVector<CFGBlock *, 16> Stack;312  llvm::BitVector Queued(Body->getNumBlockIDs());313 314  Stack.push_back(&ThrowBlock);315  Queued[ThrowBlock.getBlockID()] = true;316 317  while (!Stack.empty()) {318    CFGBlock &UnwindBlock = *Stack.pop_back_val();319 320    for (auto &Succ : UnwindBlock.succs()) {321      if (!Succ.isReachable() || Queued[Succ->getBlockID()])322        continue;323 324      if (Succ->getBlockID() == Body->getExit().getBlockID())325        return true;326 327      if (auto *Catch =328              dyn_cast_or_null<CXXCatchStmt>(Succ->getLabel())) {329        QualType Caught = Catch->getCaughtType();330        if (Caught.isNull() || // catch (...) catches everything331            !E->getSubExpr() || // throw; is considered cuaght by any handler332            S.handlerCanCatch(Caught, E->getSubExpr()->getType()))333          // Exception doesn't escape via this path.334          break;335      } else {336        Stack.push_back(Succ);337        Queued[Succ->getBlockID()] = true;338      }339    }340  }341 342  return false;343}344 345static void visitReachableThrows(346    CFG *BodyCFG,347    llvm::function_ref<void(const CXXThrowExpr *, CFGBlock &)> Visit) {348  llvm::BitVector Reachable(BodyCFG->getNumBlockIDs());349  clang::reachable_code::ScanReachableFromBlock(&BodyCFG->getEntry(), Reachable);350  for (CFGBlock *B : *BodyCFG) {351    if (!Reachable[B->getBlockID()])352      continue;353    for (CFGElement &E : *B) {354      std::optional<CFGStmt> S = E.getAs<CFGStmt>();355      if (!S)356        continue;357      if (auto *Throw = dyn_cast<CXXThrowExpr>(S->getStmt()))358        Visit(Throw, *B);359    }360  }361}362 363static void EmitDiagForCXXThrowInNonThrowingFunc(Sema &S, SourceLocation OpLoc,364                                                 const FunctionDecl *FD) {365  if (!S.getSourceManager().isInSystemHeader(OpLoc) &&366      FD->getTypeSourceInfo()) {367    S.Diag(OpLoc, diag::warn_throw_in_noexcept_func) << FD;368    if (S.getLangOpts().CPlusPlus11 &&369        (isa<CXXDestructorDecl>(FD) ||370         FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||371         FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete)) {372      if (const auto *Ty = FD->getTypeSourceInfo()->getType()->373                                         getAs<FunctionProtoType>())374        S.Diag(FD->getLocation(), diag::note_throw_in_dtor)375            << !isa<CXXDestructorDecl>(FD) << !Ty->hasExceptionSpec()376            << FD->getExceptionSpecSourceRange();377    } else378      S.Diag(FD->getLocation(), diag::note_throw_in_function)379          << FD->getExceptionSpecSourceRange();380  }381}382 383static void checkThrowInNonThrowingFunc(Sema &S, const FunctionDecl *FD,384                                        AnalysisDeclContext &AC) {385  CFG *BodyCFG = AC.getCFG();386  if (!BodyCFG)387    return;388  if (BodyCFG->getExit().pred_empty())389    return;390  visitReachableThrows(BodyCFG, [&](const CXXThrowExpr *Throw, CFGBlock &Block) {391    if (throwEscapes(S, Throw, Block, BodyCFG))392      EmitDiagForCXXThrowInNonThrowingFunc(S, Throw->getThrowLoc(), FD);393  });394}395 396static bool isNoexcept(const FunctionDecl *FD) {397  const auto *FPT = FD->getType()->castAs<FunctionProtoType>();398  if (FPT->isNothrow() || FD->hasAttr<NoThrowAttr>())399    return true;400  return false;401}402 403/// Checks if the given expression is a reference to a function with404/// 'noreturn' attribute.405static bool isReferenceToNoReturn(const Expr *E) {406  if (auto *DRef = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))407    if (auto *FD = dyn_cast<FunctionDecl>(DRef->getDecl()))408      return FD->isNoReturn();409  return false;410}411 412/// Checks if the given variable, which is assumed to be a function pointer, is413/// initialized with a function having 'noreturn' attribute.414static bool isInitializedWithNoReturn(const VarDecl *VD) {415  if (const Expr *Init = VD->getInit()) {416    if (auto *ListInit = dyn_cast<InitListExpr>(Init);417        ListInit && ListInit->getNumInits() > 0)418      Init = ListInit->getInit(0);419    return isReferenceToNoReturn(Init);420  }421  return false;422}423 424namespace {425 426/// Looks for statements, that can define value of the given variable.427struct TransferFunctions : public StmtVisitor<TransferFunctions> {428  const VarDecl *Var;429  std::optional<bool> AllValuesAreNoReturn;430 431  TransferFunctions(const VarDecl *VD) : Var(VD) {}432 433  void reset() { AllValuesAreNoReturn = std::nullopt; }434 435  void VisitDeclStmt(DeclStmt *DS) {436    for (auto *DI : DS->decls())437      if (auto *VD = dyn_cast<VarDecl>(DI))438        if (VarDecl *Def = VD->getDefinition())439          if (Def == Var)440            AllValuesAreNoReturn = isInitializedWithNoReturn(Def);441  }442 443  void VisitUnaryOperator(UnaryOperator *UO) {444    if (UO->getOpcode() == UO_AddrOf) {445      if (auto *DRef =446              dyn_cast<DeclRefExpr>(UO->getSubExpr()->IgnoreParenCasts()))447        if (DRef->getDecl() == Var)448          AllValuesAreNoReturn = false;449    }450  }451 452  void VisitBinaryOperator(BinaryOperator *BO) {453    if (BO->getOpcode() == BO_Assign)454      if (auto *DRef = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParenCasts()))455        if (DRef->getDecl() == Var)456          AllValuesAreNoReturn = isReferenceToNoReturn(BO->getRHS());457  }458 459  void VisitCallExpr(CallExpr *CE) {460    for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end(); I != E;461         ++I) {462      const Expr *Arg = *I;463      if (Arg->isGLValue() && !Arg->getType().isConstQualified())464        if (auto *DRef = dyn_cast<DeclRefExpr>(Arg->IgnoreParenCasts()))465          if (auto VD = dyn_cast<VarDecl>(DRef->getDecl()))466            if (VD->getDefinition() == Var)467              AllValuesAreNoReturn = false;468    }469  }470};471} // namespace472 473// Checks if all possible values of the given variable are functions with474// 'noreturn' attribute.475static bool areAllValuesNoReturn(const VarDecl *VD, const CFGBlock &VarBlk,476                                 AnalysisDeclContext &AC) {477  // The set of possible values of a constant variable is determined by478  // its initializer, unless it is a function parameter.479  if (!isa<ParmVarDecl>(VD) && VD->getType().isConstant(AC.getASTContext())) {480    if (const VarDecl *Def = VD->getDefinition())481      return isInitializedWithNoReturn(Def);482    return false;483  }484 485  // In multithreaded environment the value of a global variable may be changed486  // asynchronously.487  if (!VD->getDeclContext()->isFunctionOrMethod())488    return false;489 490  // Check the condition "all values are noreturn". It is satisfied if the491  // variable is set to "noreturn" value in the current block or all its492  // predecessors satisfies the condition.493  using MapTy = llvm::DenseMap<const CFGBlock *, std::optional<bool>>;494  using ValueTy = MapTy::value_type;495  MapTy BlocksToCheck;496  BlocksToCheck[&VarBlk] = std::nullopt;497  const auto BlockSatisfiesCondition = [](ValueTy Item) {498    return Item.getSecond().value_or(false);499  };500 501  TransferFunctions TF(VD);502  BackwardDataflowWorklist Worklist(*AC.getCFG(), AC);503  llvm::DenseSet<const CFGBlock *> Visited;504  Worklist.enqueueBlock(&VarBlk);505  while (const CFGBlock *B = Worklist.dequeue()) {506    if (Visited.contains(B))507      continue;508    Visited.insert(B);509    // First check the current block.510    for (CFGBlock::const_reverse_iterator ri = B->rbegin(), re = B->rend();511         ri != re; ++ri) {512      if (std::optional<CFGStmt> cs = ri->getAs<CFGStmt>()) {513        const Stmt *S = cs->getStmt();514        TF.reset();515        TF.Visit(const_cast<Stmt *>(S));516        if (TF.AllValuesAreNoReturn) {517          if (!TF.AllValuesAreNoReturn.value())518            return false;519          BlocksToCheck[B] = true;520          break;521        }522      }523    }524 525    // If all checked blocks satisfy the condition, the check is finished.526    if (llvm::all_of(BlocksToCheck, BlockSatisfiesCondition))527      return true;528 529    // If this block does not contain the variable definition, check530    // its predecessors.531    if (!BlocksToCheck[B]) {532      Worklist.enqueuePredecessors(B);533      BlocksToCheck.erase(B);534      for (const auto &PredBlk : B->preds())535        if (!BlocksToCheck.contains(PredBlk))536          BlocksToCheck[PredBlk] = std::nullopt;537    }538  }539 540  return false;541}542 543//===----------------------------------------------------------------------===//544// Check for missing return value.545//===----------------------------------------------------------------------===//546 547enum ControlFlowKind {548  UnknownFallThrough,549  NeverFallThrough,550  MaybeFallThrough,551  AlwaysFallThrough,552  NeverFallThroughOrReturn553};554 555/// CheckFallThrough - Check that we don't fall off the end of a556/// Statement that should return a value.557///558/// \returns AlwaysFallThrough iff we always fall off the end of the statement,559/// MaybeFallThrough iff we might or might not fall off the end,560/// NeverFallThroughOrReturn iff we never fall off the end of the statement or561/// return.  We assume NeverFallThrough iff we never fall off the end of the562/// statement but we may return.  We assume that functions not marked noreturn563/// will return.564static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) {565  CFG *cfg = AC.getCFG();566  if (!cfg) return UnknownFallThrough;567 568  // The CFG leaves in dead things, and we don't want the dead code paths to569  // confuse us, so we mark all live things first.570  llvm::BitVector live(cfg->getNumBlockIDs());571  unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(),572                                                          live);573 574  bool AddEHEdges = AC.getAddEHEdges();575  if (!AddEHEdges && count != cfg->getNumBlockIDs())576    // When there are things remaining dead, and we didn't add EH edges577    // from CallExprs to the catch clauses, we have to go back and578    // mark them as live.579    for (const auto *B : *cfg) {580      if (!live[B->getBlockID()]) {581        if (B->preds().empty()) {582          const Stmt *Term = B->getTerminatorStmt();583          if (isa_and_nonnull<CXXTryStmt>(Term))584            // When not adding EH edges from calls, catch clauses585            // can otherwise seem dead.  Avoid noting them as dead.586            count += reachable_code::ScanReachableFromBlock(B, live);587          continue;588        }589      }590    }591 592  // Now we know what is live, we check the live precessors of the exit block593  // and look for fall through paths, being careful to ignore normal returns,594  // and exceptional paths.595  bool HasLiveReturn = false;596  bool HasFakeEdge = false;597  bool HasPlainEdge = false;598  bool HasAbnormalEdge = false;599 600  // Ignore default cases that aren't likely to be reachable because all601  // enums in a switch(X) have explicit case statements.602  CFGBlock::FilterOptions FO;603  FO.IgnoreDefaultsWithCoveredEnums = 1;604 605  for (CFGBlock::filtered_pred_iterator I =606           cfg->getExit().filtered_pred_start_end(FO);607       I.hasMore(); ++I) {608    const CFGBlock &B = **I;609    if (!live[B.getBlockID()])610      continue;611 612    // Skip blocks which contain an element marked as no-return. They don't613    // represent actually viable edges into the exit block, so mark them as614    // abnormal.615    if (B.hasNoReturnElement()) {616      HasAbnormalEdge = true;617      continue;618    }619 620    // Destructors can appear after the 'return' in the CFG.  This is621    // normal.  We need to look pass the destructors for the return622    // statement (if it exists).623    CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend();624 625    for ( ; ri != re ; ++ri)626      if (ri->getAs<CFGStmt>())627        break;628 629    // No more CFGElements in the block?630    if (ri == re) {631      const Stmt *Term = B.getTerminatorStmt();632      if (Term && (isa<CXXTryStmt>(Term) || isa<ObjCAtTryStmt>(Term))) {633        HasAbnormalEdge = true;634        continue;635      }636      // A labeled empty statement, or the entry block...637      HasPlainEdge = true;638      continue;639    }640 641    CFGStmt CS = ri->castAs<CFGStmt>();642    const Stmt *S = CS.getStmt();643    if (isa<ReturnStmt>(S) || isa<CoreturnStmt>(S)) {644      HasLiveReturn = true;645      continue;646    }647    if (isa<ObjCAtThrowStmt>(S)) {648      HasFakeEdge = true;649      continue;650    }651    if (isa<CXXThrowExpr>(S)) {652      HasFakeEdge = true;653      continue;654    }655    if (isa<MSAsmStmt>(S)) {656      // TODO: Verify this is correct.657      HasFakeEdge = true;658      HasLiveReturn = true;659      continue;660    }661    if (isa<CXXTryStmt>(S)) {662      HasAbnormalEdge = true;663      continue;664    }665    if (!llvm::is_contained(B.succs(), &cfg->getExit())) {666      HasAbnormalEdge = true;667      continue;668    }669    if (auto *Call = dyn_cast<CallExpr>(S)) {670      const Expr *Callee = Call->getCallee();671      if (Callee->getType()->isPointerType())672        if (auto *DeclRef =673                dyn_cast<DeclRefExpr>(Callee->IgnoreParenImpCasts()))674          if (auto *VD = dyn_cast<VarDecl>(DeclRef->getDecl()))675            if (areAllValuesNoReturn(VD, B, AC)) {676              HasAbnormalEdge = true;677              continue;678            }679    }680 681    HasPlainEdge = true;682  }683  if (!HasPlainEdge) {684    if (HasLiveReturn)685      return NeverFallThrough;686    return NeverFallThroughOrReturn;687  }688  if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn)689    return MaybeFallThrough;690  // This says AlwaysFallThrough for calls to functions that are not marked691  // noreturn, that don't return.  If people would like this warning to be more692  // accurate, such functions should be marked as noreturn.693  return AlwaysFallThrough;694}695 696namespace {697 698struct CheckFallThroughDiagnostics {699  unsigned diag_FallThrough_HasNoReturn = 0;700  unsigned diag_FallThrough_ReturnsNonVoid = 0;701  unsigned diag_NeverFallThroughOrReturn = 0;702  unsigned FunKind; // TODO: use diag::FalloffFunctionKind703  SourceLocation FuncLoc;704 705  static CheckFallThroughDiagnostics MakeForFunction(Sema &S,706                                                     const Decl *Func) {707    CheckFallThroughDiagnostics D;708    D.FuncLoc = Func->getLocation();709    D.diag_FallThrough_HasNoReturn = diag::warn_noreturn_has_return_expr;710    D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;711 712    // Don't suggest that virtual functions be marked "noreturn", since they713    // might be overridden by non-noreturn functions.714    bool isVirtualMethod = false;715    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func))716      isVirtualMethod = Method->isVirtual();717 718    // Don't suggest that template instantiations be marked "noreturn"719    bool isTemplateInstantiation = false;720    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func)) {721      isTemplateInstantiation = Function->isTemplateInstantiation();722      if (!S.getLangOpts().CPlusPlus && !S.getLangOpts().C99 &&723          Function->isMain()) {724        D.diag_FallThrough_ReturnsNonVoid = diag::ext_main_no_return;725      }726    }727 728    if (!isVirtualMethod && !isTemplateInstantiation)729      D.diag_NeverFallThroughOrReturn = diag::warn_suggest_noreturn_function;730 731    D.FunKind = diag::FalloffFunctionKind::Function;732    return D;733  }734 735  static CheckFallThroughDiagnostics MakeForCoroutine(const Decl *Func) {736    CheckFallThroughDiagnostics D;737    D.FuncLoc = Func->getLocation();738    D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;739    D.FunKind = diag::FalloffFunctionKind::Coroutine;740    return D;741  }742 743  static CheckFallThroughDiagnostics MakeForBlock() {744    CheckFallThroughDiagnostics D;745    D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;746    D.diag_FallThrough_ReturnsNonVoid = diag::err_falloff_nonvoid;747    D.FunKind = diag::FalloffFunctionKind::Block;748    return D;749  }750 751  static CheckFallThroughDiagnostics MakeForLambda() {752    CheckFallThroughDiagnostics D;753    D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;754    D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;755    D.FunKind = diag::FalloffFunctionKind::Lambda;756    return D;757  }758 759  bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid,760                        bool HasNoReturn) const {761    if (FunKind == diag::FalloffFunctionKind::Function) {762      return (ReturnsVoid ||763              D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&764             (!HasNoReturn ||765              D.isIgnored(diag::warn_noreturn_has_return_expr, FuncLoc)) &&766             (!ReturnsVoid ||767              D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc));768    }769    if (FunKind == diag::FalloffFunctionKind::Coroutine) {770      return (ReturnsVoid ||771              D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&772             (!HasNoReturn);773    }774    // For blocks / lambdas.775    return ReturnsVoid && !HasNoReturn;776  }777};778 779} // anonymous namespace780 781/// CheckFallThroughForBody - Check that we don't fall off the end of a782/// function that should return a value.  Check that we don't fall off the end783/// of a noreturn function.  We assume that functions and blocks not marked784/// noreturn will return.785static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,786                                    QualType BlockType,787                                    const CheckFallThroughDiagnostics &CD,788                                    AnalysisDeclContext &AC) {789 790  bool ReturnsVoid = false;791  bool HasNoReturn = false;792 793  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {794    if (const auto *CBody = dyn_cast<CoroutineBodyStmt>(Body))795      ReturnsVoid = CBody->getFallthroughHandler() != nullptr;796    else797      ReturnsVoid = FD->getReturnType()->isVoidType();798    HasNoReturn = FD->isNoReturn() || FD->hasAttr<InferredNoReturnAttr>();799  }800  else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {801    ReturnsVoid = MD->getReturnType()->isVoidType();802    HasNoReturn = MD->hasAttr<NoReturnAttr>();803  }804  else if (isa<BlockDecl>(D)) {805    if (const FunctionType *FT =806          BlockType->getPointeeType()->getAs<FunctionType>()) {807      if (FT->getReturnType()->isVoidType())808        ReturnsVoid = true;809      if (FT->getNoReturnAttr())810        HasNoReturn = true;811    }812  }813 814  DiagnosticsEngine &Diags = S.getDiagnostics();815 816  // Short circuit for compilation speed.817  if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))818      return;819  SourceLocation LBrace = Body->getBeginLoc(), RBrace = Body->getEndLoc();820 821  // cpu_dispatch functions permit empty function bodies for ICC compatibility.822  if (D->getAsFunction() && D->getAsFunction()->isCPUDispatchMultiVersion())823    return;824 825  // Either in a function body compound statement, or a function-try-block.826  switch (int FallThroughType = CheckFallThrough(AC)) {827  case UnknownFallThrough:828    break;829 830  case MaybeFallThrough:831  case AlwaysFallThrough:832    if (HasNoReturn) {833      if (CD.diag_FallThrough_HasNoReturn)834        S.Diag(RBrace, CD.diag_FallThrough_HasNoReturn) << CD.FunKind;835    } else if (!ReturnsVoid && CD.diag_FallThrough_ReturnsNonVoid) {836      // If the final statement is a call to an always-throwing function,837      // don't warn about the fall-through.838      if (D->getAsFunction()) {839        if (const auto *CS = dyn_cast<CompoundStmt>(Body);840            CS && !CS->body_empty()) {841          const Stmt *LastStmt = CS->body_back();842          // Unwrap ExprWithCleanups if necessary.843          if (const auto *EWC = dyn_cast<ExprWithCleanups>(LastStmt)) {844            LastStmt = EWC->getSubExpr();845          }846          if (const auto *CE = dyn_cast<CallExpr>(LastStmt)) {847            if (const FunctionDecl *Callee = CE->getDirectCallee();848                Callee && Callee->hasAttr<InferredNoReturnAttr>()) {849              return; // Don't warn about fall-through.850            }851          }852          // Direct throw.853          if (isa<CXXThrowExpr>(LastStmt)) {854            return; // Don't warn about fall-through.855          }856        }857      }858      bool NotInAllControlPaths = FallThroughType == MaybeFallThrough;859      S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid)860          << CD.FunKind << NotInAllControlPaths;861    }862    break;863  case NeverFallThroughOrReturn:864    if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {865      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {866        S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 0 << FD;867      } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {868        S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 1 << MD;869      } else {870        S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn);871      }872    }873    break;874  case NeverFallThrough:875    break;876  }877}878 879//===----------------------------------------------------------------------===//880// -Wuninitialized881//===----------------------------------------------------------------------===//882 883namespace {884/// ContainsReference - A visitor class to search for references to885/// a particular declaration (the needle) within any evaluated component of an886/// expression (recursively).887class ContainsReference : public ConstEvaluatedExprVisitor<ContainsReference> {888  bool FoundReference;889  const DeclRefExpr *Needle;890 891public:892  typedef ConstEvaluatedExprVisitor<ContainsReference> Inherited;893 894  ContainsReference(ASTContext &Context, const DeclRefExpr *Needle)895    : Inherited(Context), FoundReference(false), Needle(Needle) {}896 897  void VisitExpr(const Expr *E) {898    // Stop evaluating if we already have a reference.899    if (FoundReference)900      return;901 902    Inherited::VisitExpr(E);903  }904 905  void VisitDeclRefExpr(const DeclRefExpr *E) {906    if (E == Needle)907      FoundReference = true;908    else909      Inherited::VisitDeclRefExpr(E);910  }911 912  bool doesContainReference() const { return FoundReference; }913};914} // anonymous namespace915 916static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) {917  QualType VariableTy = VD->getType().getCanonicalType();918  if (VariableTy->isBlockPointerType() &&919      !VD->hasAttr<BlocksAttr>()) {920    S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization)921        << VD->getDeclName()922        << FixItHint::CreateInsertion(VD->getLocation(), "__block ");923    return true;924  }925 926  // Don't issue a fixit if there is already an initializer.927  if (VD->getInit())928    return false;929 930  // Don't suggest a fixit inside macros.931  if (VD->getEndLoc().isMacroID())932    return false;933 934  SourceLocation Loc = S.getLocForEndOfToken(VD->getEndLoc());935 936  // Suggest possible initialization (if any).937  std::string Init = S.getFixItZeroInitializerForType(VariableTy, Loc);938  if (Init.empty())939    return false;940 941  S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()942    << FixItHint::CreateInsertion(Loc, Init);943  return true;944}945 946/// Create a fixit to remove an if-like statement, on the assumption that its947/// condition is CondVal.948static void CreateIfFixit(Sema &S, const Stmt *If, const Stmt *Then,949                          const Stmt *Else, bool CondVal,950                          FixItHint &Fixit1, FixItHint &Fixit2) {951  if (CondVal) {952    // If condition is always true, remove all but the 'then'.953    Fixit1 = FixItHint::CreateRemoval(954        CharSourceRange::getCharRange(If->getBeginLoc(), Then->getBeginLoc()));955    if (Else) {956      SourceLocation ElseKwLoc = S.getLocForEndOfToken(Then->getEndLoc());957      Fixit2 =958          FixItHint::CreateRemoval(SourceRange(ElseKwLoc, Else->getEndLoc()));959    }960  } else {961    // If condition is always false, remove all but the 'else'.962    if (Else)963      Fixit1 = FixItHint::CreateRemoval(CharSourceRange::getCharRange(964          If->getBeginLoc(), Else->getBeginLoc()));965    else966      Fixit1 = FixItHint::CreateRemoval(If->getSourceRange());967  }968}969 970/// DiagUninitUse -- Helper function to produce a diagnostic for an971/// uninitialized use of a variable.972static void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,973                          bool IsCapturedByBlock) {974  bool Diagnosed = false;975 976  switch (Use.getKind()) {977  case UninitUse::Always:978    S.Diag(Use.getUser()->getBeginLoc(), diag::warn_uninit_var)979        << VD->getDeclName() << IsCapturedByBlock980        << Use.getUser()->getSourceRange();981    return;982 983  case UninitUse::AfterDecl:984  case UninitUse::AfterCall:985    S.Diag(VD->getLocation(), diag::warn_sometimes_uninit_var)986        << VD->getDeclName() << IsCapturedByBlock987        << (Use.getKind() == UninitUse::AfterDecl ? 4 : 5)988        << VD->getLexicalDeclContext() << VD->getSourceRange();989    S.Diag(Use.getUser()->getBeginLoc(), diag::note_uninit_var_use)990        << IsCapturedByBlock << Use.getUser()->getSourceRange();991    return;992 993  case UninitUse::Maybe:994  case UninitUse::Sometimes:995    // Carry on to report sometimes-uninitialized branches, if possible,996    // or a 'may be used uninitialized' diagnostic otherwise.997    break;998  }999 1000  // Diagnose each branch which leads to a sometimes-uninitialized use.1001  for (UninitUse::branch_iterator I = Use.branch_begin(), E = Use.branch_end();1002       I != E; ++I) {1003    assert(Use.getKind() == UninitUse::Sometimes);1004 1005    const Expr *User = Use.getUser();1006    const Stmt *Term = I->Terminator;1007 1008    // Information used when building the diagnostic.1009    unsigned DiagKind;1010    StringRef Str;1011    SourceRange Range;1012 1013    // FixIts to suppress the diagnostic by removing the dead condition.1014    // For all binary terminators, branch 0 is taken if the condition is true,1015    // and branch 1 is taken if the condition is false.1016    int RemoveDiagKind = -1;1017    const char *FixitStr =1018        S.getLangOpts().CPlusPlus ? (I->Output ? "true" : "false")1019                                  : (I->Output ? "1" : "0");1020    FixItHint Fixit1, Fixit2;1021 1022    switch (Term ? Term->getStmtClass() : Stmt::DeclStmtClass) {1023    default:1024      // Don't know how to report this. Just fall back to 'may be used1025      // uninitialized'. FIXME: Can this happen?1026      continue;1027 1028    // "condition is true / condition is false".1029    case Stmt::IfStmtClass: {1030      const IfStmt *IS = cast<IfStmt>(Term);1031      DiagKind = 0;1032      Str = "if";1033      Range = IS->getCond()->getSourceRange();1034      RemoveDiagKind = 0;1035      CreateIfFixit(S, IS, IS->getThen(), IS->getElse(),1036                    I->Output, Fixit1, Fixit2);1037      break;1038    }1039    case Stmt::ConditionalOperatorClass: {1040      const ConditionalOperator *CO = cast<ConditionalOperator>(Term);1041      DiagKind = 0;1042      Str = "?:";1043      Range = CO->getCond()->getSourceRange();1044      RemoveDiagKind = 0;1045      CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(),1046                    I->Output, Fixit1, Fixit2);1047      break;1048    }1049    case Stmt::BinaryOperatorClass: {1050      const BinaryOperator *BO = cast<BinaryOperator>(Term);1051      if (!BO->isLogicalOp())1052        continue;1053      DiagKind = 0;1054      Str = BO->getOpcodeStr();1055      Range = BO->getLHS()->getSourceRange();1056      RemoveDiagKind = 0;1057      if ((BO->getOpcode() == BO_LAnd && I->Output) ||1058          (BO->getOpcode() == BO_LOr && !I->Output))1059        // true && y -> y, false || y -> y.1060        Fixit1 = FixItHint::CreateRemoval(1061            SourceRange(BO->getBeginLoc(), BO->getOperatorLoc()));1062      else1063        // false && y -> false, true || y -> true.1064        Fixit1 = FixItHint::CreateReplacement(BO->getSourceRange(), FixitStr);1065      break;1066    }1067 1068    // "loop is entered / loop is exited".1069    case Stmt::WhileStmtClass:1070      DiagKind = 1;1071      Str = "while";1072      Range = cast<WhileStmt>(Term)->getCond()->getSourceRange();1073      RemoveDiagKind = 1;1074      Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);1075      break;1076    case Stmt::ForStmtClass:1077      DiagKind = 1;1078      Str = "for";1079      Range = cast<ForStmt>(Term)->getCond()->getSourceRange();1080      RemoveDiagKind = 1;1081      if (I->Output)1082        Fixit1 = FixItHint::CreateRemoval(Range);1083      else1084        Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);1085      break;1086    case Stmt::CXXForRangeStmtClass:1087      if (I->Output == 1) {1088        // The use occurs if a range-based for loop's body never executes.1089        // That may be impossible, and there's no syntactic fix for this,1090        // so treat it as a 'may be uninitialized' case.1091        continue;1092      }1093      DiagKind = 1;1094      Str = "for";1095      Range = cast<CXXForRangeStmt>(Term)->getRangeInit()->getSourceRange();1096      break;1097 1098    // "condition is true / loop is exited".1099    case Stmt::DoStmtClass:1100      DiagKind = 2;1101      Str = "do";1102      Range = cast<DoStmt>(Term)->getCond()->getSourceRange();1103      RemoveDiagKind = 1;1104      Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);1105      break;1106 1107    // "switch case is taken".1108    case Stmt::CaseStmtClass:1109      DiagKind = 3;1110      Str = "case";1111      Range = cast<CaseStmt>(Term)->getLHS()->getSourceRange();1112      break;1113    case Stmt::DefaultStmtClass:1114      DiagKind = 3;1115      Str = "default";1116      Range = cast<DefaultStmt>(Term)->getDefaultLoc();1117      break;1118    }1119 1120    S.Diag(Range.getBegin(), diag::warn_sometimes_uninit_var)1121      << VD->getDeclName() << IsCapturedByBlock << DiagKind1122      << Str << I->Output << Range;1123    S.Diag(User->getBeginLoc(), diag::note_uninit_var_use)1124        << IsCapturedByBlock << User->getSourceRange();1125    if (RemoveDiagKind != -1)1126      S.Diag(Fixit1.RemoveRange.getBegin(), diag::note_uninit_fixit_remove_cond)1127        << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2;1128 1129    Diagnosed = true;1130  }1131 1132  if (!Diagnosed)1133    S.Diag(Use.getUser()->getBeginLoc(), diag::warn_maybe_uninit_var)1134        << VD->getDeclName() << IsCapturedByBlock1135        << Use.getUser()->getSourceRange();1136}1137 1138/// Diagnose uninitialized const reference usages.1139static bool DiagnoseUninitializedConstRefUse(Sema &S, const VarDecl *VD,1140                                             const UninitUse &Use) {1141  S.Diag(Use.getUser()->getBeginLoc(), diag::warn_uninit_const_reference)1142      << VD->getDeclName() << Use.getUser()->getSourceRange();1143  return !S.getDiagnostics().isLastDiagnosticIgnored();1144}1145 1146/// Diagnose uninitialized const pointer usages.1147static bool DiagnoseUninitializedConstPtrUse(Sema &S, const VarDecl *VD,1148                                             const UninitUse &Use) {1149  S.Diag(Use.getUser()->getBeginLoc(), diag::warn_uninit_const_pointer)1150      << VD->getDeclName() << Use.getUser()->getSourceRange();1151  return !S.getDiagnostics().isLastDiagnosticIgnored();1152}1153 1154/// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an1155/// uninitialized variable. This manages the different forms of diagnostic1156/// emitted for particular types of uses. Returns true if the use was diagnosed1157/// as a warning. If a particular use is one we omit warnings for, returns1158/// false.1159static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,1160                                     const UninitUse &Use,1161                                     bool alwaysReportSelfInit = false) {1162  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Use.getUser())) {1163    // Inspect the initializer of the variable declaration which is1164    // being referenced prior to its initialization. We emit1165    // specialized diagnostics for self-initialization, and we1166    // specifically avoid warning about self references which take the1167    // form of:1168    //1169    //   int x = x;1170    //1171    // This is used to indicate to GCC that 'x' is intentionally left1172    // uninitialized. Proven code paths which access 'x' in1173    // an uninitialized state after this will still warn.1174    if (const Expr *Initializer = VD->getInit()) {1175      if (!alwaysReportSelfInit && DRE == Initializer->IgnoreParenImpCasts())1176        return false;1177 1178      ContainsReference CR(S.Context, DRE);1179      CR.Visit(Initializer);1180      if (CR.doesContainReference()) {1181        S.Diag(DRE->getBeginLoc(), diag::warn_uninit_self_reference_in_init)1182            << VD->getDeclName() << VD->getLocation() << DRE->getSourceRange();1183        return !S.getDiagnostics().isLastDiagnosticIgnored();1184      }1185    }1186 1187    DiagUninitUse(S, VD, Use, false);1188  } else {1189    const BlockExpr *BE = cast<BlockExpr>(Use.getUser());1190    if (VD->getType()->isBlockPointerType() && !VD->hasAttr<BlocksAttr>())1191      S.Diag(BE->getBeginLoc(),1192             diag::warn_uninit_byref_blockvar_captured_by_block)1193          << VD->getDeclName()1194          << VD->getType().getQualifiers().hasObjCLifetime();1195    else1196      DiagUninitUse(S, VD, Use, true);1197  }1198 1199  // Report where the variable was declared when the use wasn't within1200  // the initializer of that declaration & we didn't already suggest1201  // an initialization fixit.1202  if (!SuggestInitializationFixit(S, VD))1203    S.Diag(VD->getBeginLoc(), diag::note_var_declared_here)1204        << VD->getDeclName();1205 1206  return !S.getDiagnostics().isLastDiagnosticIgnored();1207}1208 1209namespace {1210class FallthroughMapper : public DynamicRecursiveASTVisitor {1211public:1212  FallthroughMapper(Sema &S) : FoundSwitchStatements(false), S(S) {1213    ShouldWalkTypesOfTypeLocs = false;1214  }1215 1216  bool foundSwitchStatements() const { return FoundSwitchStatements; }1217 1218  void markFallthroughVisited(const AttributedStmt *Stmt) {1219    bool Found = FallthroughStmts.erase(Stmt);1220    assert(Found);1221    (void)Found;1222  }1223 1224  typedef llvm::SmallPtrSet<const AttributedStmt *, 8> AttrStmts;1225 1226  const AttrStmts &getFallthroughStmts() const { return FallthroughStmts; }1227 1228  void fillReachableBlocks(CFG *Cfg) {1229    assert(ReachableBlocks.empty() && "ReachableBlocks already filled");1230    std::deque<const CFGBlock *> BlockQueue;1231 1232    ReachableBlocks.insert(&Cfg->getEntry());1233    BlockQueue.push_back(&Cfg->getEntry());1234    // Mark all case blocks reachable to avoid problems with switching on1235    // constants, covered enums, etc.1236    // These blocks can contain fall-through annotations, and we don't want to1237    // issue a warn_fallthrough_attr_unreachable for them.1238    for (const auto *B : *Cfg) {1239      const Stmt *L = B->getLabel();1240      if (isa_and_nonnull<SwitchCase>(L) && ReachableBlocks.insert(B).second)1241        BlockQueue.push_back(B);1242    }1243 1244    while (!BlockQueue.empty()) {1245      const CFGBlock *P = BlockQueue.front();1246      BlockQueue.pop_front();1247      for (const CFGBlock *B : P->succs()) {1248        if (B && ReachableBlocks.insert(B).second)1249          BlockQueue.push_back(B);1250      }1251    }1252  }1253 1254  bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt,1255                                 bool IsTemplateInstantiation) {1256    assert(!ReachableBlocks.empty() && "ReachableBlocks empty");1257 1258    int UnannotatedCnt = 0;1259    AnnotatedCnt = 0;1260 1261    std::deque<const CFGBlock *> BlockQueue(B.pred_begin(), B.pred_end());1262    while (!BlockQueue.empty()) {1263      const CFGBlock *P = BlockQueue.front();1264      BlockQueue.pop_front();1265      if (!P)1266        continue;1267 1268      const Stmt *Term = P->getTerminatorStmt();1269      if (isa_and_nonnull<SwitchStmt>(Term))1270        continue; // Switch statement, good.1271 1272      const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel());1273      if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end())1274        continue; // Previous case label has no statements, good.1275 1276      const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel());1277      if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end())1278        continue; // Case label is preceded with a normal label, good.1279 1280      if (!ReachableBlocks.count(P)) {1281        for (const CFGElement &Elem : llvm::reverse(*P)) {1282          if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>()) {1283            if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) {1284              // Don't issue a warning for an unreachable fallthrough1285              // attribute in template instantiations as it may not be1286              // unreachable in all instantiations of the template.1287              if (!IsTemplateInstantiation)1288                S.Diag(AS->getBeginLoc(),1289                       diag::warn_unreachable_fallthrough_attr);1290              markFallthroughVisited(AS);1291              ++AnnotatedCnt;1292              break;1293            }1294            // Don't care about other unreachable statements.1295          }1296        }1297          // If there are no unreachable statements, this may be a special1298          // case in CFG:1299          // case X: {1300          //    A a;  // A has a destructor.1301          //    break;1302          // }1303          // // <<<< This place is represented by a 'hanging' CFG block.1304          // case Y:1305          continue;1306      }1307 1308        const Stmt *LastStmt = getLastStmt(*P);1309        if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {1310          markFallthroughVisited(AS);1311          ++AnnotatedCnt;1312          continue; // Fallthrough annotation, good.1313        }1314 1315        if (!LastStmt) { // This block contains no executable statements.1316          // Traverse its predecessors.1317          std::copy(P->pred_begin(), P->pred_end(),1318                    std::back_inserter(BlockQueue));1319          continue;1320        }1321 1322        ++UnannotatedCnt;1323    }1324    return !!UnannotatedCnt;1325  }1326 1327  bool VisitAttributedStmt(AttributedStmt *S) override {1328    if (asFallThroughAttr(S))1329      FallthroughStmts.insert(S);1330    return true;1331  }1332 1333  bool VisitSwitchStmt(SwitchStmt *S) override {1334    FoundSwitchStatements = true;1335    return true;1336  }1337 1338    // We don't want to traverse local type declarations. We analyze their1339    // methods separately.1340    bool TraverseDecl(Decl *D) override { return true; }1341 1342    // We analyze lambda bodies separately. Skip them here.1343    bool TraverseLambdaExpr(LambdaExpr *LE) override {1344      // Traverse the captures, but not the body.1345      for (const auto C : zip(LE->captures(), LE->capture_inits()))1346        TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));1347      return true;1348    }1349 1350  private:1351 1352    static const AttributedStmt *asFallThroughAttr(const Stmt *S) {1353      if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {1354        if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))1355          return AS;1356      }1357      return nullptr;1358    }1359 1360    static const Stmt *getLastStmt(const CFGBlock &B) {1361      if (const Stmt *Term = B.getTerminatorStmt())1362        return Term;1363      for (const CFGElement &Elem : llvm::reverse(B))1364        if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>())1365          return CS->getStmt();1366      // Workaround to detect a statement thrown out by CFGBuilder:1367      //   case X: {} case Y:1368      //   case X: ; case Y:1369      if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))1370        if (!isa<SwitchCase>(SW->getSubStmt()))1371          return SW->getSubStmt();1372 1373      return nullptr;1374    }1375 1376    bool FoundSwitchStatements;1377    AttrStmts FallthroughStmts;1378    Sema &S;1379    llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;1380};1381} // anonymous namespace1382 1383static StringRef getFallthroughAttrSpelling(Preprocessor &PP,1384                                            SourceLocation Loc) {1385  TokenValue FallthroughTokens[] = {1386    tok::l_square, tok::l_square,1387    PP.getIdentifierInfo("fallthrough"),1388    tok::r_square, tok::r_square1389  };1390 1391  TokenValue ClangFallthroughTokens[] = {1392    tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"),1393    tok::coloncolon, PP.getIdentifierInfo("fallthrough"),1394    tok::r_square, tok::r_square1395  };1396 1397  bool PreferClangAttr = !PP.getLangOpts().CPlusPlus17 && !PP.getLangOpts().C23;1398 1399  StringRef MacroName;1400  if (PreferClangAttr)1401    MacroName = PP.getLastMacroWithSpelling(Loc, ClangFallthroughTokens);1402  if (MacroName.empty())1403    MacroName = PP.getLastMacroWithSpelling(Loc, FallthroughTokens);1404  if (MacroName.empty() && !PreferClangAttr)1405    MacroName = PP.getLastMacroWithSpelling(Loc, ClangFallthroughTokens);1406  if (MacroName.empty()) {1407    if (!PreferClangAttr)1408      MacroName = "[[fallthrough]]";1409    else if (PP.getLangOpts().CPlusPlus)1410      MacroName = "[[clang::fallthrough]]";1411    else1412      MacroName = "__attribute__((fallthrough))";1413  }1414  return MacroName;1415}1416 1417static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC,1418                                            bool PerFunction) {1419  FallthroughMapper FM(S);1420  FM.TraverseStmt(AC.getBody());1421 1422  if (!FM.foundSwitchStatements())1423    return;1424 1425  if (PerFunction && FM.getFallthroughStmts().empty())1426    return;1427 1428  CFG *Cfg = AC.getCFG();1429 1430  if (!Cfg)1431    return;1432 1433  FM.fillReachableBlocks(Cfg);1434 1435  for (const CFGBlock *B : llvm::reverse(*Cfg)) {1436    const Stmt *Label = B->getLabel();1437 1438    if (!isa_and_nonnull<SwitchCase>(Label))1439      continue;1440 1441    int AnnotatedCnt;1442 1443    bool IsTemplateInstantiation = false;1444    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(AC.getDecl()))1445      IsTemplateInstantiation = Function->isTemplateInstantiation();1446    if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt,1447                                      IsTemplateInstantiation))1448      continue;1449 1450    S.Diag(Label->getBeginLoc(),1451           PerFunction ? diag::warn_unannotated_fallthrough_per_function1452                       : diag::warn_unannotated_fallthrough);1453 1454    if (!AnnotatedCnt) {1455      SourceLocation L = Label->getBeginLoc();1456      if (L.isMacroID())1457        continue;1458 1459      const Stmt *Term = B->getTerminatorStmt();1460      // Skip empty cases.1461      while (B->empty() && !Term && B->succ_size() == 1) {1462        B = *B->succ_begin();1463        Term = B->getTerminatorStmt();1464      }1465      if (!(B->empty() && isa_and_nonnull<BreakStmt>(Term))) {1466        Preprocessor &PP = S.getPreprocessor();1467        StringRef AnnotationSpelling = getFallthroughAttrSpelling(PP, L);1468        SmallString<64> TextToInsert(AnnotationSpelling);1469        TextToInsert += "; ";1470        S.Diag(L, diag::note_insert_fallthrough_fixit)1471            << AnnotationSpelling1472            << FixItHint::CreateInsertion(L, TextToInsert);1473      }1474      S.Diag(L, diag::note_insert_break_fixit)1475          << FixItHint::CreateInsertion(L, "break; ");1476    }1477  }1478 1479  for (const auto *F : FM.getFallthroughStmts())1480    S.Diag(F->getBeginLoc(), diag::err_fallthrough_attr_invalid_placement);1481}1482 1483static bool isInLoop(const ASTContext &Ctx, const ParentMap &PM,1484                     const Stmt *S) {1485  assert(S);1486 1487  do {1488    switch (S->getStmtClass()) {1489    case Stmt::ForStmtClass:1490    case Stmt::WhileStmtClass:1491    case Stmt::CXXForRangeStmtClass:1492    case Stmt::ObjCForCollectionStmtClass:1493      return true;1494    case Stmt::DoStmtClass: {1495      Expr::EvalResult Result;1496      if (!cast<DoStmt>(S)->getCond()->EvaluateAsInt(Result, Ctx))1497        return true;1498      return Result.Val.getInt().getBoolValue();1499    }1500    default:1501      break;1502    }1503  } while ((S = PM.getParent(S)));1504 1505  return false;1506}1507 1508static void diagnoseRepeatedUseOfWeak(Sema &S,1509                                      const sema::FunctionScopeInfo *CurFn,1510                                      const Decl *D,1511                                      const ParentMap &PM) {1512  typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy;1513  typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap;1514  typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector;1515  typedef std::pair<const Stmt *, WeakObjectUseMap::const_iterator>1516  StmtUsesPair;1517 1518  ASTContext &Ctx = S.getASTContext();1519 1520  const WeakObjectUseMap &WeakMap = CurFn->getWeakObjectUses();1521 1522  // Extract all weak objects that are referenced more than once.1523  SmallVector<StmtUsesPair, 8> UsesByStmt;1524  for (WeakObjectUseMap::const_iterator I = WeakMap.begin(), E = WeakMap.end();1525       I != E; ++I) {1526    const WeakUseVector &Uses = I->second;1527 1528    // Find the first read of the weak object.1529    WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end();1530    for ( ; UI != UE; ++UI) {1531      if (UI->isUnsafe())1532        break;1533    }1534 1535    // If there were only writes to this object, don't warn.1536    if (UI == UE)1537      continue;1538 1539    // If there was only one read, followed by any number of writes, and the1540    // read is not within a loop, don't warn. Additionally, don't warn in a1541    // loop if the base object is a local variable -- local variables are often1542    // changed in loops.1543    if (UI == Uses.begin()) {1544      WeakUseVector::const_iterator UI2 = UI;1545      for (++UI2; UI2 != UE; ++UI2)1546        if (UI2->isUnsafe())1547          break;1548 1549      if (UI2 == UE) {1550        if (!isInLoop(Ctx, PM, UI->getUseExpr()))1551          continue;1552 1553        const WeakObjectProfileTy &Profile = I->first;1554        if (!Profile.isExactProfile())1555          continue;1556 1557        const NamedDecl *Base = Profile.getBase();1558        if (!Base)1559          Base = Profile.getProperty();1560        assert(Base && "A profile always has a base or property.");1561 1562        if (const VarDecl *BaseVar = dyn_cast<VarDecl>(Base))1563          if (BaseVar->hasLocalStorage() && !isa<ParmVarDecl>(Base))1564            continue;1565      }1566    }1567 1568    UsesByStmt.push_back(StmtUsesPair(UI->getUseExpr(), I));1569  }1570 1571  if (UsesByStmt.empty())1572    return;1573 1574  // Sort by first use so that we emit the warnings in a deterministic order.1575  SourceManager &SM = S.getSourceManager();1576  llvm::sort(UsesByStmt,1577             [&SM](const StmtUsesPair &LHS, const StmtUsesPair &RHS) {1578               return SM.isBeforeInTranslationUnit(LHS.first->getBeginLoc(),1579                                                   RHS.first->getBeginLoc());1580             });1581 1582  // Classify the current code body for better warning text.1583  // This enum should stay in sync with the cases in1584  // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.1585  // FIXME: Should we use a common classification enum and the same set of1586  // possibilities all throughout Sema?1587  enum {1588    Function,1589    Method,1590    Block,1591    Lambda1592  } FunctionKind;1593 1594  if (isa<sema::BlockScopeInfo>(CurFn))1595    FunctionKind = Block;1596  else if (isa<sema::LambdaScopeInfo>(CurFn))1597    FunctionKind = Lambda;1598  else if (isa<ObjCMethodDecl>(D))1599    FunctionKind = Method;1600  else1601    FunctionKind = Function;1602 1603  // Iterate through the sorted problems and emit warnings for each.1604  for (const auto &P : UsesByStmt) {1605    const Stmt *FirstRead = P.first;1606    const WeakObjectProfileTy &Key = P.second->first;1607    const WeakUseVector &Uses = P.second->second;1608 1609    // For complicated expressions like 'a.b.c' and 'x.b.c', WeakObjectProfileTy1610    // may not contain enough information to determine that these are different1611    // properties. We can only be 100% sure of a repeated use in certain cases,1612    // and we adjust the diagnostic kind accordingly so that the less certain1613    // case can be turned off if it is too noisy.1614    unsigned DiagKind;1615    if (Key.isExactProfile())1616      DiagKind = diag::warn_arc_repeated_use_of_weak;1617    else1618      DiagKind = diag::warn_arc_possible_repeated_use_of_weak;1619 1620    // Classify the weak object being accessed for better warning text.1621    // This enum should stay in sync with the cases in1622    // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.1623    enum {1624      Variable,1625      Property,1626      ImplicitProperty,1627      Ivar1628    } ObjectKind;1629 1630    const NamedDecl *KeyProp = Key.getProperty();1631    if (isa<VarDecl>(KeyProp))1632      ObjectKind = Variable;1633    else if (isa<ObjCPropertyDecl>(KeyProp))1634      ObjectKind = Property;1635    else if (isa<ObjCMethodDecl>(KeyProp))1636      ObjectKind = ImplicitProperty;1637    else if (isa<ObjCIvarDecl>(KeyProp))1638      ObjectKind = Ivar;1639    else1640      llvm_unreachable("Unexpected weak object kind!");1641 1642    // Do not warn about IBOutlet weak property receivers being set to null1643    // since they are typically only used from the main thread.1644    if (const ObjCPropertyDecl *Prop = dyn_cast<ObjCPropertyDecl>(KeyProp))1645      if (Prop->hasAttr<IBOutletAttr>())1646        continue;1647 1648    // Show the first time the object was read.1649    S.Diag(FirstRead->getBeginLoc(), DiagKind)1650        << int(ObjectKind) << KeyProp << int(FunctionKind)1651        << FirstRead->getSourceRange();1652 1653    // Print all the other accesses as notes.1654    for (const auto &Use : Uses) {1655      if (Use.getUseExpr() == FirstRead)1656        continue;1657      S.Diag(Use.getUseExpr()->getBeginLoc(),1658             diag::note_arc_weak_also_accessed_here)1659          << Use.getUseExpr()->getSourceRange();1660    }1661  }1662}1663 1664namespace clang {1665namespace {1666typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes;1667typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;1668typedef std::list<DelayedDiag> DiagList;1669 1670struct SortDiagBySourceLocation {1671  SourceManager &SM;1672  SortDiagBySourceLocation(SourceManager &SM) : SM(SM) {}1673 1674  bool operator()(const DelayedDiag &left, const DelayedDiag &right) {1675    // Although this call will be slow, this is only called when outputting1676    // multiple warnings.1677    return SM.isBeforeInTranslationUnit(left.first.first, right.first.first);1678  }1679};1680} // anonymous namespace1681} // namespace clang1682 1683namespace {1684class UninitValsDiagReporter : public UninitVariablesHandler {1685  Sema &S;1686  typedef SmallVector<UninitUse, 2> UsesVec;1687  typedef llvm::PointerIntPair<UsesVec *, 1, bool> MappedType;1688  // Prefer using MapVector to DenseMap, so that iteration order will be1689  // the same as insertion order. This is needed to obtain a deterministic1690  // order of diagnostics when calling flushDiagnostics().1691  typedef llvm::MapVector<const VarDecl *, MappedType> UsesMap;1692  UsesMap uses;1693 1694public:1695  UninitValsDiagReporter(Sema &S) : S(S) {}1696  ~UninitValsDiagReporter() override { flushDiagnostics(); }1697 1698  MappedType &getUses(const VarDecl *vd) {1699    MappedType &V = uses[vd];1700    if (!V.getPointer())1701      V.setPointer(new UsesVec());1702    return V;1703  }1704 1705  void handleUseOfUninitVariable(const VarDecl *vd,1706                                 const UninitUse &use) override {1707    getUses(vd).getPointer()->push_back(use);1708  }1709 1710  void handleSelfInit(const VarDecl *vd) override { getUses(vd).setInt(true); }1711 1712  void flushDiagnostics() {1713    for (const auto &P : uses) {1714      const VarDecl *vd = P.first;1715      const MappedType &V = P.second;1716 1717      UsesVec *vec = V.getPointer();1718      bool hasSelfInit = V.getInt();1719 1720      diagnoseUnitializedVar(vd, hasSelfInit, vec);1721 1722      // Release the uses vector.1723      delete vec;1724    }1725 1726    uses.clear();1727  }1728 1729private:1730  static bool hasAlwaysUninitializedUse(const UsesVec* vec) {1731    return llvm::any_of(*vec, [](const UninitUse &U) {1732      return U.getKind() == UninitUse::Always ||1733             U.getKind() == UninitUse::AfterCall ||1734             U.getKind() == UninitUse::AfterDecl;1735    });1736  }1737 1738  // Print the diagnostic for the variable.  We try to warn only on the first1739  // point at which a variable is used uninitialized.  After the first1740  // diagnostic is printed, further diagnostics for this variable are skipped.1741  void diagnoseUnitializedVar(const VarDecl *vd, bool hasSelfInit,1742                              UsesVec *vec) {1743    // Specially handle the case where we have uses of an uninitialized1744    // variable, but the root cause is an idiomatic self-init.  We want1745    // to report the diagnostic at the self-init since that is the root cause.1746    if (hasSelfInit && hasAlwaysUninitializedUse(vec)) {1747      if (DiagnoseUninitializedUse(S, vd,1748                                   UninitUse(vd->getInit()->IgnoreParenCasts(),1749                                             /*isAlwaysUninit=*/true),1750                                   /*alwaysReportSelfInit=*/true))1751        return;1752    }1753 1754    // Sort the uses by their SourceLocations.  While not strictly1755    // guaranteed to produce them in line/column order, this will provide1756    // a stable ordering.1757    llvm::sort(*vec, [](const UninitUse &a, const UninitUse &b) {1758      // Prefer the direct use of an uninitialized variable over its use via1759      // constant reference or pointer.1760      if (a.isConstRefOrPtrUse() != b.isConstRefOrPtrUse())1761        return b.isConstRefOrPtrUse();1762      // Prefer a more confident report over a less confident one.1763      if (a.getKind() != b.getKind())1764        return a.getKind() > b.getKind();1765      return a.getUser()->getBeginLoc() < b.getUser()->getBeginLoc();1766    });1767 1768    for (const auto &U : *vec) {1769      if (U.isConstRefUse()) {1770        if (DiagnoseUninitializedConstRefUse(S, vd, U))1771          return;1772      } else if (U.isConstPtrUse()) {1773        if (DiagnoseUninitializedConstPtrUse(S, vd, U))1774          return;1775      } else {1776        // If we have self-init, downgrade all uses to 'may be uninitialized'.1777        UninitUse Use = hasSelfInit ? UninitUse(U.getUser(), false) : U;1778        if (DiagnoseUninitializedUse(S, vd, Use))1779          return;1780      }1781    }1782  }1783};1784 1785/// Inter-procedural data for the called-once checker.1786class CalledOnceInterProceduralData {1787public:1788  // Add the delayed warning for the given block.1789  void addDelayedWarning(const BlockDecl *Block,1790                         PartialDiagnosticAt &&Warning) {1791    DelayedBlockWarnings[Block].emplace_back(std::move(Warning));1792  }1793  // Report all of the warnings we've gathered for the given block.1794  void flushWarnings(const BlockDecl *Block, Sema &S) {1795    for (const PartialDiagnosticAt &Delayed : DelayedBlockWarnings[Block])1796      S.Diag(Delayed.first, Delayed.second);1797 1798    discardWarnings(Block);1799  }1800  // Discard all of the warnings we've gathered for the given block.1801  void discardWarnings(const BlockDecl *Block) {1802    DelayedBlockWarnings.erase(Block);1803  }1804 1805private:1806  using DelayedDiagnostics = SmallVector<PartialDiagnosticAt, 2>;1807  llvm::DenseMap<const BlockDecl *, DelayedDiagnostics> DelayedBlockWarnings;1808};1809 1810class CalledOnceCheckReporter : public CalledOnceCheckHandler {1811public:1812  CalledOnceCheckReporter(Sema &S, CalledOnceInterProceduralData &Data)1813      : S(S), Data(Data) {}1814  void handleDoubleCall(const ParmVarDecl *Parameter, const Expr *Call,1815                        const Expr *PrevCall, bool IsCompletionHandler,1816                        bool Poised) override {1817    auto DiagToReport = IsCompletionHandler1818                            ? diag::warn_completion_handler_called_twice1819                            : diag::warn_called_once_gets_called_twice;1820    S.Diag(Call->getBeginLoc(), DiagToReport) << Parameter;1821    S.Diag(PrevCall->getBeginLoc(), diag::note_called_once_gets_called_twice)1822        << Poised;1823  }1824 1825  void handleNeverCalled(const ParmVarDecl *Parameter,1826                         bool IsCompletionHandler) override {1827    auto DiagToReport = IsCompletionHandler1828                            ? diag::warn_completion_handler_never_called1829                            : diag::warn_called_once_never_called;1830    S.Diag(Parameter->getBeginLoc(), DiagToReport)1831        << Parameter << /* Captured */ false;1832  }1833 1834  void handleNeverCalled(const ParmVarDecl *Parameter, const Decl *Function,1835                         const Stmt *Where, NeverCalledReason Reason,1836                         bool IsCalledDirectly,1837                         bool IsCompletionHandler) override {1838    auto DiagToReport = IsCompletionHandler1839                            ? diag::warn_completion_handler_never_called_when1840                            : diag::warn_called_once_never_called_when;1841    PartialDiagnosticAt Warning(Where->getBeginLoc(), S.PDiag(DiagToReport)1842                                                          << Parameter1843                                                          << IsCalledDirectly1844                                                          << (unsigned)Reason);1845 1846    if (const auto *Block = dyn_cast<BlockDecl>(Function)) {1847      // We shouldn't report these warnings on blocks immediately1848      Data.addDelayedWarning(Block, std::move(Warning));1849    } else {1850      S.Diag(Warning.first, Warning.second);1851    }1852  }1853 1854  void handleCapturedNeverCalled(const ParmVarDecl *Parameter,1855                                 const Decl *Where,1856                                 bool IsCompletionHandler) override {1857    auto DiagToReport = IsCompletionHandler1858                            ? diag::warn_completion_handler_never_called1859                            : diag::warn_called_once_never_called;1860    S.Diag(Where->getBeginLoc(), DiagToReport)1861        << Parameter << /* Captured */ true;1862  }1863 1864  void1865  handleBlockThatIsGuaranteedToBeCalledOnce(const BlockDecl *Block) override {1866    Data.flushWarnings(Block, S);1867  }1868 1869  void handleBlockWithNoGuarantees(const BlockDecl *Block) override {1870    Data.discardWarnings(Block);1871  }1872 1873private:1874  Sema &S;1875  CalledOnceInterProceduralData &Data;1876};1877 1878constexpr unsigned CalledOnceWarnings[] = {1879    diag::warn_called_once_never_called,1880    diag::warn_called_once_never_called_when,1881    diag::warn_called_once_gets_called_twice};1882 1883constexpr unsigned CompletionHandlerWarnings[]{1884    diag::warn_completion_handler_never_called,1885    diag::warn_completion_handler_never_called_when,1886    diag::warn_completion_handler_called_twice};1887 1888bool shouldAnalyzeCalledOnceImpl(llvm::ArrayRef<unsigned> DiagIDs,1889                                 const DiagnosticsEngine &Diags,1890                                 SourceLocation At) {1891  return llvm::any_of(DiagIDs, [&Diags, At](unsigned DiagID) {1892    return !Diags.isIgnored(DiagID, At);1893  });1894}1895 1896bool shouldAnalyzeCalledOnceConventions(const DiagnosticsEngine &Diags,1897                                        SourceLocation At) {1898  return shouldAnalyzeCalledOnceImpl(CompletionHandlerWarnings, Diags, At);1899}1900 1901bool shouldAnalyzeCalledOnceParameters(const DiagnosticsEngine &Diags,1902                                       SourceLocation At) {1903  return shouldAnalyzeCalledOnceImpl(CalledOnceWarnings, Diags, At) ||1904         shouldAnalyzeCalledOnceConventions(Diags, At);1905}1906} // anonymous namespace1907 1908//===----------------------------------------------------------------------===//1909// -Wthread-safety1910//===----------------------------------------------------------------------===//1911namespace clang {1912namespace threadSafety {1913namespace {1914class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {1915  Sema &S;1916  DiagList Warnings;1917  SourceLocation FunLocation, FunEndLocation;1918 1919  const FunctionDecl *CurrentFunction;1920  bool Verbose;1921 1922  OptionalNotes getNotes() const {1923    if (Verbose && CurrentFunction) {1924      PartialDiagnosticAt FNote(CurrentFunction->getBody()->getBeginLoc(),1925                                S.PDiag(diag::note_thread_warning_in_fun)1926                                    << CurrentFunction);1927      return OptionalNotes(1, FNote);1928    }1929    return OptionalNotes();1930  }1931 1932  OptionalNotes getNotes(const PartialDiagnosticAt &Note) const {1933    OptionalNotes ONS(1, Note);1934    if (Verbose && CurrentFunction) {1935      PartialDiagnosticAt FNote(CurrentFunction->getBody()->getBeginLoc(),1936                                S.PDiag(diag::note_thread_warning_in_fun)1937                                    << CurrentFunction);1938      ONS.push_back(std::move(FNote));1939    }1940    return ONS;1941  }1942 1943  OptionalNotes getNotes(const PartialDiagnosticAt &Note1,1944                         const PartialDiagnosticAt &Note2) const {1945    OptionalNotes ONS;1946    ONS.push_back(Note1);1947    ONS.push_back(Note2);1948    if (Verbose && CurrentFunction) {1949      PartialDiagnosticAt FNote(CurrentFunction->getBody()->getBeginLoc(),1950                                S.PDiag(diag::note_thread_warning_in_fun)1951                                    << CurrentFunction);1952      ONS.push_back(std::move(FNote));1953    }1954    return ONS;1955  }1956 1957  OptionalNotes makeLockedHereNote(SourceLocation LocLocked, StringRef Kind) {1958    return LocLocked.isValid()1959               ? getNotes(PartialDiagnosticAt(1960                     LocLocked, S.PDiag(diag::note_locked_here) << Kind))1961               : getNotes();1962  }1963 1964  OptionalNotes makeUnlockedHereNote(SourceLocation LocUnlocked,1965                                     StringRef Kind) {1966    return LocUnlocked.isValid()1967               ? getNotes(PartialDiagnosticAt(1968                     LocUnlocked, S.PDiag(diag::note_unlocked_here) << Kind))1969               : getNotes();1970  }1971 1972  OptionalNotes makeManagedMismatchNoteForParam(SourceLocation DeclLoc) {1973    return DeclLoc.isValid()1974               ? getNotes(PartialDiagnosticAt(1975                     DeclLoc,1976                     S.PDiag(diag::note_managed_mismatch_here_for_param)))1977               : getNotes();1978  }1979 1980 public:1981  ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL)1982    : S(S), FunLocation(FL), FunEndLocation(FEL),1983      CurrentFunction(nullptr), Verbose(false) {}1984 1985  void setVerbose(bool b) { Verbose = b; }1986 1987  /// Emit all buffered diagnostics in order of sourcelocation.1988  /// We need to output diagnostics produced while iterating through1989  /// the lockset in deterministic order, so this function orders diagnostics1990  /// and outputs them.1991  void emitDiagnostics() {1992    Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));1993    for (const auto &Diag : Warnings) {1994      S.Diag(Diag.first.first, Diag.first.second);1995      for (const auto &Note : Diag.second)1996        S.Diag(Note.first, Note.second);1997    }1998  }1999 2000  void handleUnmatchedUnderlyingMutexes(SourceLocation Loc, SourceLocation DLoc,2001                                        Name scopeName, StringRef Kind,2002                                        Name expected, Name actual) override {2003    PartialDiagnosticAt Warning(Loc,2004                                S.PDiag(diag::warn_unmatched_underlying_mutexes)2005                                    << Kind << scopeName << expected << actual);2006    Warnings.emplace_back(std::move(Warning),2007                          makeManagedMismatchNoteForParam(DLoc));2008  }2009 2010  void handleExpectMoreUnderlyingMutexes(SourceLocation Loc,2011                                         SourceLocation DLoc, Name scopeName,2012                                         StringRef Kind,2013                                         Name expected) override {2014    PartialDiagnosticAt Warning(2015        Loc, S.PDiag(diag::warn_expect_more_underlying_mutexes)2016                 << Kind << scopeName << expected);2017    Warnings.emplace_back(std::move(Warning),2018                          makeManagedMismatchNoteForParam(DLoc));2019  }2020 2021  void handleExpectFewerUnderlyingMutexes(SourceLocation Loc,2022                                          SourceLocation DLoc, Name scopeName,2023                                          StringRef Kind,2024                                          Name actual) override {2025    PartialDiagnosticAt Warning(2026        Loc, S.PDiag(diag::warn_expect_fewer_underlying_mutexes)2027                 << Kind << scopeName << actual);2028    Warnings.emplace_back(std::move(Warning),2029                          makeManagedMismatchNoteForParam(DLoc));2030  }2031 2032  void handleInvalidLockExp(SourceLocation Loc) override {2033    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_cannot_resolve_lock)2034                                         << Loc);2035    Warnings.emplace_back(std::move(Warning), getNotes());2036  }2037 2038  void handleUnmatchedUnlock(StringRef Kind, Name LockName, SourceLocation Loc,2039                             SourceLocation LocPreviousUnlock) override {2040    if (Loc.isInvalid())2041      Loc = FunLocation;2042    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_but_no_lock)2043                                         << Kind << LockName);2044    Warnings.emplace_back(std::move(Warning),2045                          makeUnlockedHereNote(LocPreviousUnlock, Kind));2046  }2047 2048  void handleIncorrectUnlockKind(StringRef Kind, Name LockName,2049                                 LockKind Expected, LockKind Received,2050                                 SourceLocation LocLocked,2051                                 SourceLocation LocUnlock) override {2052    if (LocUnlock.isInvalid())2053      LocUnlock = FunLocation;2054    PartialDiagnosticAt Warning(2055        LocUnlock, S.PDiag(diag::warn_unlock_kind_mismatch)2056                       << Kind << LockName << Received << Expected);2057    Warnings.emplace_back(std::move(Warning),2058                          makeLockedHereNote(LocLocked, Kind));2059  }2060 2061  void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation LocLocked,2062                        SourceLocation LocDoubleLock) override {2063    if (LocDoubleLock.isInvalid())2064      LocDoubleLock = FunLocation;2065    PartialDiagnosticAt Warning(LocDoubleLock, S.PDiag(diag::warn_double_lock)2066                                                   << Kind << LockName);2067    Warnings.emplace_back(std::move(Warning),2068                          makeLockedHereNote(LocLocked, Kind));2069  }2070 2071  void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,2072                                 SourceLocation LocLocked,2073                                 SourceLocation LocEndOfScope,2074                                 LockErrorKind LEK,2075                                 bool ReentrancyMismatch) override {2076    unsigned DiagID = 0;2077    switch (LEK) {2078      case LEK_LockedSomePredecessors:2079        DiagID = diag::warn_lock_some_predecessors;2080        break;2081      case LEK_LockedSomeLoopIterations:2082        DiagID = diag::warn_expecting_lock_held_on_loop;2083        break;2084      case LEK_LockedAtEndOfFunction:2085        DiagID = diag::warn_no_unlock;2086        break;2087      case LEK_NotLockedAtEndOfFunction:2088        DiagID = diag::warn_expecting_locked;2089        break;2090    }2091    if (LocEndOfScope.isInvalid())2092      LocEndOfScope = FunEndLocation;2093 2094    PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID)2095                                                   << Kind << LockName2096                                                   << ReentrancyMismatch);2097    Warnings.emplace_back(std::move(Warning),2098                          makeLockedHereNote(LocLocked, Kind));2099  }2100 2101  void handleExclusiveAndShared(StringRef Kind, Name LockName,2102                                SourceLocation Loc1,2103                                SourceLocation Loc2) override {2104    PartialDiagnosticAt Warning(Loc1,2105                                S.PDiag(diag::warn_lock_exclusive_and_shared)2106                                    << Kind << LockName);2107    PartialDiagnosticAt Note(Loc2, S.PDiag(diag::note_lock_exclusive_and_shared)2108                                       << Kind << LockName);2109    Warnings.emplace_back(std::move(Warning), getNotes(Note));2110  }2111 2112  void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK,2113                         AccessKind AK, SourceLocation Loc) override {2114    unsigned DiagID = 0;2115    switch (POK) {2116    case POK_VarAccess:2117    case POK_PassByRef:2118    case POK_ReturnByRef:2119    case POK_PassPointer:2120    case POK_ReturnPointer:2121      DiagID = diag::warn_variable_requires_any_lock;2122      break;2123    case POK_VarDereference:2124    case POK_PtPassByRef:2125    case POK_PtReturnByRef:2126    case POK_PtPassPointer:2127    case POK_PtReturnPointer:2128      DiagID = diag::warn_var_deref_requires_any_lock;2129      break;2130    case POK_FunctionCall:2131      llvm_unreachable("Only works for variables");2132      break;2133    }2134    PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)2135      << D << getLockKindFromAccessKind(AK));2136    Warnings.emplace_back(std::move(Warning), getNotes());2137  }2138 2139  void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,2140                          ProtectedOperationKind POK, Name LockName,2141                          LockKind LK, SourceLocation Loc,2142                          Name *PossibleMatch) override {2143    unsigned DiagID = 0;2144    if (PossibleMatch) {2145      switch (POK) {2146        case POK_VarAccess:2147          DiagID = diag::warn_variable_requires_lock_precise;2148          break;2149        case POK_VarDereference:2150          DiagID = diag::warn_var_deref_requires_lock_precise;2151          break;2152        case POK_FunctionCall:2153          DiagID = diag::warn_fun_requires_lock_precise;2154          break;2155        case POK_PassByRef:2156          DiagID = diag::warn_guarded_pass_by_reference;2157          break;2158        case POK_PtPassByRef:2159          DiagID = diag::warn_pt_guarded_pass_by_reference;2160          break;2161        case POK_ReturnByRef:2162          DiagID = diag::warn_guarded_return_by_reference;2163          break;2164        case POK_PtReturnByRef:2165          DiagID = diag::warn_pt_guarded_return_by_reference;2166          break;2167        case POK_PassPointer:2168          DiagID = diag::warn_guarded_pass_pointer;2169          break;2170        case POK_PtPassPointer:2171          DiagID = diag::warn_pt_guarded_pass_pointer;2172          break;2173        case POK_ReturnPointer:2174          DiagID = diag::warn_guarded_return_pointer;2175          break;2176        case POK_PtReturnPointer:2177          DiagID = diag::warn_pt_guarded_return_pointer;2178          break;2179      }2180      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind2181                                                       << D2182                                                       << LockName << LK);2183      PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match)2184                                        << *PossibleMatch);2185      if (Verbose && POK == POK_VarAccess) {2186        PartialDiagnosticAt VNote(D->getLocation(),2187                                  S.PDiag(diag::note_guarded_by_declared_here)2188                                      << D->getDeclName());2189        Warnings.emplace_back(std::move(Warning), getNotes(Note, VNote));2190      } else2191        Warnings.emplace_back(std::move(Warning), getNotes(Note));2192    } else {2193      switch (POK) {2194        case POK_VarAccess:2195          DiagID = diag::warn_variable_requires_lock;2196          break;2197        case POK_VarDereference:2198          DiagID = diag::warn_var_deref_requires_lock;2199          break;2200        case POK_FunctionCall:2201          DiagID = diag::warn_fun_requires_lock;2202          break;2203        case POK_PassByRef:2204          DiagID = diag::warn_guarded_pass_by_reference;2205          break;2206        case POK_PtPassByRef:2207          DiagID = diag::warn_pt_guarded_pass_by_reference;2208          break;2209        case POK_ReturnByRef:2210          DiagID = diag::warn_guarded_return_by_reference;2211          break;2212        case POK_PtReturnByRef:2213          DiagID = diag::warn_pt_guarded_return_by_reference;2214          break;2215        case POK_PassPointer:2216          DiagID = diag::warn_guarded_pass_pointer;2217          break;2218        case POK_PtPassPointer:2219          DiagID = diag::warn_pt_guarded_pass_pointer;2220          break;2221        case POK_ReturnPointer:2222          DiagID = diag::warn_guarded_return_pointer;2223          break;2224        case POK_PtReturnPointer:2225          DiagID = diag::warn_pt_guarded_return_pointer;2226          break;2227      }2228      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind2229                                                       << D2230                                                       << LockName << LK);2231      if (Verbose && POK == POK_VarAccess) {2232        PartialDiagnosticAt Note(D->getLocation(),2233                                 S.PDiag(diag::note_guarded_by_declared_here));2234        Warnings.emplace_back(std::move(Warning), getNotes(Note));2235      } else2236        Warnings.emplace_back(std::move(Warning), getNotes());2237    }2238  }2239 2240  void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,2241                             SourceLocation Loc) override {2242    PartialDiagnosticAt Warning(Loc,2243        S.PDiag(diag::warn_acquire_requires_negative_cap)2244        << Kind << LockName << Neg);2245    Warnings.emplace_back(std::move(Warning), getNotes());2246  }2247 2248  void handleNegativeNotHeld(const NamedDecl *D, Name LockName,2249                             SourceLocation Loc) override {2250    PartialDiagnosticAt Warning(2251        Loc, S.PDiag(diag::warn_fun_requires_negative_cap) << D << LockName);2252    Warnings.emplace_back(std::move(Warning), getNotes());2253  }2254 2255  void handleFunExcludesLock(StringRef Kind, Name FunName, Name LockName,2256                             SourceLocation Loc) override {2257    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_fun_excludes_mutex)2258                                         << Kind << FunName << LockName);2259    Warnings.emplace_back(std::move(Warning), getNotes());2260  }2261 2262  void handleLockAcquiredBefore(StringRef Kind, Name L1Name, Name L2Name,2263                                SourceLocation Loc) override {2264    PartialDiagnosticAt Warning(Loc,2265      S.PDiag(diag::warn_acquired_before) << Kind << L1Name << L2Name);2266    Warnings.emplace_back(std::move(Warning), getNotes());2267  }2268 2269  void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) override {2270    PartialDiagnosticAt Warning(Loc,2271      S.PDiag(diag::warn_acquired_before_after_cycle) << L1Name);2272    Warnings.emplace_back(std::move(Warning), getNotes());2273  }2274 2275  void enterFunction(const FunctionDecl* FD) override {2276    CurrentFunction = FD;2277  }2278 2279  void leaveFunction(const FunctionDecl* FD) override {2280    CurrentFunction = nullptr;2281  }2282};2283} // anonymous namespace2284} // namespace threadSafety2285} // namespace clang2286 2287//===----------------------------------------------------------------------===//2288// -Wconsumed2289//===----------------------------------------------------------------------===//2290 2291namespace clang {2292namespace consumed {2293namespace {2294class ConsumedWarningsHandler : public ConsumedWarningsHandlerBase {2295 2296  Sema &S;2297  DiagList Warnings;2298 2299public:2300 2301  ConsumedWarningsHandler(Sema &S) : S(S) {}2302 2303  void emitDiagnostics() override {2304    Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));2305    for (const auto &Diag : Warnings) {2306      S.Diag(Diag.first.first, Diag.first.second);2307      for (const auto &Note : Diag.second)2308        S.Diag(Note.first, Note.second);2309    }2310  }2311 2312  void warnLoopStateMismatch(SourceLocation Loc,2313                             StringRef VariableName) override {2314    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch) <<2315      VariableName);2316 2317    Warnings.emplace_back(std::move(Warning), OptionalNotes());2318  }2319 2320  void warnParamReturnTypestateMismatch(SourceLocation Loc,2321                                        StringRef VariableName,2322                                        StringRef ExpectedState,2323                                        StringRef ObservedState) override {2324 2325    PartialDiagnosticAt Warning(Loc, S.PDiag(2326      diag::warn_param_return_typestate_mismatch) << VariableName <<2327        ExpectedState << ObservedState);2328 2329    Warnings.emplace_back(std::move(Warning), OptionalNotes());2330  }2331 2332  void warnParamTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,2333                                  StringRef ObservedState) override {2334 2335    PartialDiagnosticAt Warning(Loc, S.PDiag(2336      diag::warn_param_typestate_mismatch) << ExpectedState << ObservedState);2337 2338    Warnings.emplace_back(std::move(Warning), OptionalNotes());2339  }2340 2341  void warnReturnTypestateForUnconsumableType(SourceLocation Loc,2342                                              StringRef TypeName) override {2343    PartialDiagnosticAt Warning(Loc, S.PDiag(2344      diag::warn_return_typestate_for_unconsumable_type) << TypeName);2345 2346    Warnings.emplace_back(std::move(Warning), OptionalNotes());2347  }2348 2349  void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,2350                                   StringRef ObservedState) override {2351 2352    PartialDiagnosticAt Warning(Loc, S.PDiag(2353      diag::warn_return_typestate_mismatch) << ExpectedState << ObservedState);2354 2355    Warnings.emplace_back(std::move(Warning), OptionalNotes());2356  }2357 2358  void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State,2359                                   SourceLocation Loc) override {2360 2361    PartialDiagnosticAt Warning(Loc, S.PDiag(2362      diag::warn_use_of_temp_in_invalid_state) << MethodName << State);2363 2364    Warnings.emplace_back(std::move(Warning), OptionalNotes());2365  }2366 2367  void warnUseInInvalidState(StringRef MethodName, StringRef VariableName,2368                             StringRef State, SourceLocation Loc) override {2369 2370    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state) <<2371                                MethodName << VariableName << State);2372 2373    Warnings.emplace_back(std::move(Warning), OptionalNotes());2374  }2375};2376} // anonymous namespace2377} // namespace consumed2378} // namespace clang2379 2380//===----------------------------------------------------------------------===//2381// Unsafe buffer usage analysis.2382//===----------------------------------------------------------------------===//2383 2384namespace {2385class UnsafeBufferUsageReporter : public UnsafeBufferUsageHandler {2386  Sema &S;2387  bool SuggestSuggestions;  // Recommend -fsafe-buffer-usage-suggestions?2388 2389  // Lists as a string the names of variables in `VarGroupForVD` except for `VD`2390  // itself:2391  std::string listVariableGroupAsString(2392      const VarDecl *VD, const ArrayRef<const VarDecl *> &VarGroupForVD) const {2393    if (VarGroupForVD.size() <= 1)2394      return "";2395 2396    std::vector<StringRef> VarNames;2397    auto PutInQuotes = [](StringRef S) -> std::string {2398      return "'" + S.str() + "'";2399    };2400 2401    for (auto *V : VarGroupForVD) {2402      if (V == VD)2403        continue;2404      VarNames.push_back(V->getName());2405    }2406    if (VarNames.size() == 1) {2407      return PutInQuotes(VarNames[0]);2408    }2409    if (VarNames.size() == 2) {2410      return PutInQuotes(VarNames[0]) + " and " + PutInQuotes(VarNames[1]);2411    }2412    assert(VarGroupForVD.size() > 3);2413    const unsigned N = VarNames.size() -2414                       2; // need to print the last two names as "..., X, and Y"2415    std::string AllVars = "";2416 2417    for (unsigned I = 0; I < N; ++I)2418      AllVars.append(PutInQuotes(VarNames[I]) + ", ");2419    AllVars.append(PutInQuotes(VarNames[N]) + ", and " +2420                   PutInQuotes(VarNames[N + 1]));2421    return AllVars;2422  }2423 2424public:2425  UnsafeBufferUsageReporter(Sema &S, bool SuggestSuggestions)2426    : S(S), SuggestSuggestions(SuggestSuggestions) {}2427 2428  void handleUnsafeOperation(const Stmt *Operation, bool IsRelatedToDecl,2429                             ASTContext &Ctx) override {2430    SourceLocation Loc;2431    SourceRange Range;2432    unsigned MsgParam = 0;2433    NamedDecl *D = nullptr;2434    if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Operation)) {2435      Loc = ASE->getBase()->getExprLoc();2436      Range = ASE->getBase()->getSourceRange();2437      MsgParam = 2;2438    } else if (const auto *BO = dyn_cast<BinaryOperator>(Operation)) {2439      BinaryOperator::Opcode Op = BO->getOpcode();2440      if (Op == BO_Add || Op == BO_AddAssign || Op == BO_Sub ||2441          Op == BO_SubAssign) {2442        if (BO->getRHS()->getType()->isIntegerType()) {2443          Loc = BO->getLHS()->getExprLoc();2444          Range = BO->getLHS()->getSourceRange();2445        } else {2446          Loc = BO->getRHS()->getExprLoc();2447          Range = BO->getRHS()->getSourceRange();2448        }2449        MsgParam = 1;2450      }2451    } else if (const auto *UO = dyn_cast<UnaryOperator>(Operation)) {2452      UnaryOperator::Opcode Op = UO->getOpcode();2453      if (Op == UO_PreInc || Op == UO_PreDec || Op == UO_PostInc ||2454          Op == UO_PostDec) {2455        Loc = UO->getSubExpr()->getExprLoc();2456        Range = UO->getSubExpr()->getSourceRange();2457        MsgParam = 1;2458      }2459    } else {2460      if (isa<CallExpr>(Operation) || isa<CXXConstructExpr>(Operation)) {2461        // note_unsafe_buffer_operation doesn't have this mode yet.2462        assert(!IsRelatedToDecl && "Not implemented yet!");2463        MsgParam = 3;2464      } else if (isa<MemberExpr>(Operation)) {2465        // note_unsafe_buffer_operation doesn't have this mode yet.2466        assert(!IsRelatedToDecl && "Not implemented yet!");2467        auto *ME = cast<MemberExpr>(Operation);2468        D = ME->getMemberDecl();2469        MsgParam = 5;2470      } else if (const auto *ECE = dyn_cast<ExplicitCastExpr>(Operation)) {2471        QualType destType = ECE->getType();2472        bool destTypeComplete = true;2473 2474        if (!isa<PointerType>(destType))2475          return;2476        destType = destType.getTypePtr()->getPointeeType();2477        if (const auto *D = destType->getAsTagDecl())2478          destTypeComplete = D->isCompleteDefinition();2479 2480        // If destination type is incomplete, it is unsafe to cast to anyway, no2481        // need to check its type:2482        if (destTypeComplete) {2483          const uint64_t dSize = Ctx.getTypeSize(destType);2484          QualType srcType = ECE->getSubExpr()->getType();2485 2486          assert(srcType->isPointerType());2487 2488          const uint64_t sSize =2489              Ctx.getTypeSize(srcType.getTypePtr()->getPointeeType());2490 2491          if (sSize >= dSize)2492            return;2493        }2494        if (const auto *CE = dyn_cast<CXXMemberCallExpr>(2495                ECE->getSubExpr()->IgnoreParens())) {2496          D = CE->getMethodDecl();2497        }2498 2499        if (!D)2500          return;2501 2502        MsgParam = 4;2503      }2504      Loc = Operation->getBeginLoc();2505      Range = Operation->getSourceRange();2506    }2507    if (IsRelatedToDecl) {2508      assert(!SuggestSuggestions &&2509             "Variables blamed for unsafe buffer usage without suggestions!");2510      S.Diag(Loc, diag::note_unsafe_buffer_operation) << MsgParam << Range;2511    } else {2512      if (D) {2513        S.Diag(Loc, diag::warn_unsafe_buffer_operation)2514            << MsgParam << D << Range;2515      } else {2516        S.Diag(Loc, diag::warn_unsafe_buffer_operation) << MsgParam << Range;2517      }2518      if (SuggestSuggestions) {2519        S.Diag(Loc, diag::note_safe_buffer_usage_suggestions_disabled);2520      }2521    }2522  }2523 2524  void handleUnsafeLibcCall(const CallExpr *Call, unsigned PrintfInfo,2525                            ASTContext &Ctx,2526                            const Expr *UnsafeArg = nullptr) override {2527    S.Diag(Call->getBeginLoc(), diag::warn_unsafe_buffer_libc_call)2528        << Call->getDirectCallee() // We've checked there is a direct callee2529        << Call->getSourceRange();2530    if (PrintfInfo > 0) {2531      SourceRange R =2532          UnsafeArg ? UnsafeArg->getSourceRange() : Call->getSourceRange();2533      S.Diag(R.getBegin(), diag::note_unsafe_buffer_printf_call)2534          << PrintfInfo << R;2535    }2536  }2537 2538  void handleUnsafeOperationInContainer(const Stmt *Operation,2539                                        bool IsRelatedToDecl,2540                                        ASTContext &Ctx) override {2541    SourceLocation Loc;2542    SourceRange Range;2543    unsigned MsgParam = 0;2544 2545    // This function only handles SpanTwoParamConstructorGadget so far, which2546    // always gives a CXXConstructExpr.2547    const auto *CtorExpr = cast<CXXConstructExpr>(Operation);2548    Loc = CtorExpr->getLocation();2549 2550    S.Diag(Loc, diag::warn_unsafe_buffer_usage_in_container);2551    if (IsRelatedToDecl) {2552      assert(!SuggestSuggestions &&2553             "Variables blamed for unsafe buffer usage without suggestions!");2554      S.Diag(Loc, diag::note_unsafe_buffer_operation) << MsgParam << Range;2555    }2556  }2557 2558  void handleUnsafeVariableGroup(const VarDecl *Variable,2559                                 const VariableGroupsManager &VarGrpMgr,2560                                 FixItList &&Fixes, const Decl *D,2561                                 const FixitStrategy &VarTargetTypes) override {2562    assert(!SuggestSuggestions &&2563           "Unsafe buffer usage fixits displayed without suggestions!");2564    S.Diag(Variable->getLocation(), diag::warn_unsafe_buffer_variable)2565        << Variable << (Variable->getType()->isPointerType() ? 0 : 1)2566        << Variable->getSourceRange();2567    if (!Fixes.empty()) {2568      assert(isa<NamedDecl>(D) &&2569             "Fix-its are generated only for `NamedDecl`s");2570      const NamedDecl *ND = cast<NamedDecl>(D);2571      bool BriefMsg = false;2572      // If the variable group involves parameters, the diagnostic message will2573      // NOT explain how the variables are grouped as the reason is non-trivial2574      // and irrelavant to users' experience:2575      const auto VarGroupForVD = VarGrpMgr.getGroupOfVar(Variable, &BriefMsg);2576      unsigned FixItStrategy = 0;2577      switch (VarTargetTypes.lookup(Variable)) {2578      case clang::FixitStrategy::Kind::Span:2579        FixItStrategy = 0;2580        break;2581      case clang::FixitStrategy::Kind::Array:2582        FixItStrategy = 1;2583        break;2584      default:2585        assert(false && "We support only std::span and std::array");2586      };2587 2588      const auto &FD =2589          S.Diag(Variable->getLocation(),2590                 BriefMsg ? diag::note_unsafe_buffer_variable_fixit_together2591                          : diag::note_unsafe_buffer_variable_fixit_group);2592 2593      FD << Variable << FixItStrategy;2594      FD << listVariableGroupAsString(Variable, VarGroupForVD)2595         << (VarGroupForVD.size() > 1) << ND;2596      for (const auto &F : Fixes) {2597        FD << F;2598      }2599    }2600 2601#ifndef NDEBUG2602    if (areDebugNotesRequested())2603      for (const DebugNote &Note: DebugNotesByVar[Variable])2604        S.Diag(Note.first, diag::note_safe_buffer_debug_mode) << Note.second;2605#endif2606  }2607 2608  void handleUnsafeUniquePtrArrayAccess(const DynTypedNode &Node,2609                                        bool IsRelatedToDecl,2610                                        ASTContext &Ctx) override {2611    SourceLocation Loc;2612 2613    Loc = Node.get<Stmt>()->getBeginLoc();2614    S.Diag(Loc, diag::warn_unsafe_buffer_usage_unique_ptr_array_access)2615        << Node.getSourceRange();2616  }2617 2618  bool isSafeBufferOptOut(const SourceLocation &Loc) const override {2619    return S.PP.isSafeBufferOptOut(S.getSourceManager(), Loc);2620  }2621 2622  bool ignoreUnsafeBufferInContainer(const SourceLocation &Loc) const override {2623    return S.Diags.isIgnored(diag::warn_unsafe_buffer_usage_in_container, Loc);2624  }2625 2626  bool ignoreUnsafeBufferInLibcCall(const SourceLocation &Loc) const override {2627    return S.Diags.isIgnored(diag::warn_unsafe_buffer_libc_call, Loc);2628  }2629 2630  // Returns the text representation of clang::unsafe_buffer_usage attribute.2631  // `WSSuffix` holds customized "white-space"s, e.g., newline or whilespace2632  // characters.2633  std::string2634  getUnsafeBufferUsageAttributeTextAt(SourceLocation Loc,2635                                      StringRef WSSuffix = "") const override {2636    Preprocessor &PP = S.getPreprocessor();2637    TokenValue ClangUnsafeBufferUsageTokens[] = {2638        tok::l_square,2639        tok::l_square,2640        PP.getIdentifierInfo("clang"),2641        tok::coloncolon,2642        PP.getIdentifierInfo("unsafe_buffer_usage"),2643        tok::r_square,2644        tok::r_square};2645 2646    StringRef MacroName;2647 2648    // The returned macro (it returns) is guaranteed not to be function-like:2649    MacroName = PP.getLastMacroWithSpelling(Loc, ClangUnsafeBufferUsageTokens);2650    if (MacroName.empty())2651      MacroName = "[[clang::unsafe_buffer_usage]]";2652    return MacroName.str() + WSSuffix.str();2653  }2654};2655} // namespace2656 2657//===----------------------------------------------------------------------===//2658// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based2659//  warnings on a function, method, or block.2660//===----------------------------------------------------------------------===//2661 2662sema::AnalysisBasedWarnings::Policy::Policy() {2663  enableCheckFallThrough = 1;2664  enableCheckUnreachable = 0;2665  enableThreadSafetyAnalysis = 0;2666  enableConsumedAnalysis = 0;2667}2668 2669/// InterProceduralData aims to be a storage of whatever data should be passed2670/// between analyses of different functions.2671///2672/// At the moment, its primary goal is to make the information gathered during2673/// the analysis of the blocks available during the analysis of the enclosing2674/// function.  This is important due to the fact that blocks are analyzed before2675/// the enclosed function is even parsed fully, so it is not viable to access2676/// anything in the outer scope while analyzing the block.  On the other hand,2677/// re-building CFG for blocks and re-analyzing them when we do have all the2678/// information (i.e. during the analysis of the enclosing function) seems to be2679/// ill-designed.2680class sema::AnalysisBasedWarnings::InterProceduralData {2681public:2682  // It is important to analyze blocks within functions because it's a very2683  // common pattern to capture completion handler parameters by blocks.2684  CalledOnceInterProceduralData CalledOnceData;2685};2686 2687template <typename... Ts>2688static bool areAnyEnabled(DiagnosticsEngine &D, SourceLocation Loc,2689                          Ts... Diags) {2690  return (!D.isIgnored(Diags, Loc) || ...);2691}2692 2693sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)2694    : S(s), IPData(std::make_unique<InterProceduralData>()),2695      NumFunctionsAnalyzed(0), NumFunctionsWithBadCFGs(0), NumCFGBlocks(0),2696      MaxCFGBlocksPerFunction(0), NumUninitAnalysisFunctions(0),2697      NumUninitAnalysisVariables(0), MaxUninitAnalysisVariablesPerFunction(0),2698      NumUninitAnalysisBlockVisits(0),2699      MaxUninitAnalysisBlockVisitsPerFunction(0) {2700}2701 2702// We need this here for unique_ptr with forward declared class.2703sema::AnalysisBasedWarnings::~AnalysisBasedWarnings() = default;2704 2705sema::AnalysisBasedWarnings::Policy2706sema::AnalysisBasedWarnings::getPolicyInEffectAt(SourceLocation Loc) {2707  using namespace diag;2708  DiagnosticsEngine &D = S.getDiagnostics();2709  Policy P;2710 2711  // Note: The enabled checks should be kept in sync with the switch in2712  // SemaPPCallbacks::PragmaDiagnostic().2713  P.enableCheckUnreachable =2714      PolicyOverrides.enableCheckUnreachable ||2715      areAnyEnabled(D, Loc, warn_unreachable, warn_unreachable_break,2716                    warn_unreachable_return, warn_unreachable_loop_increment);2717 2718  P.enableThreadSafetyAnalysis = PolicyOverrides.enableThreadSafetyAnalysis ||2719                                 areAnyEnabled(D, Loc, warn_double_lock);2720 2721  P.enableConsumedAnalysis = PolicyOverrides.enableConsumedAnalysis ||2722                             areAnyEnabled(D, Loc, warn_use_in_invalid_state);2723  return P;2724}2725 2726void sema::AnalysisBasedWarnings::clearOverrides() {2727  PolicyOverrides.enableCheckUnreachable = false;2728  PolicyOverrides.enableConsumedAnalysis = false;2729  PolicyOverrides.enableThreadSafetyAnalysis = false;2730}2731 2732static void flushDiagnostics(Sema &S, const sema::FunctionScopeInfo *fscope) {2733  for (const auto &D : fscope->PossiblyUnreachableDiags)2734    S.Diag(D.Loc, D.PD);2735}2736 2737template <typename Iterator>2738static void emitPossiblyUnreachableDiags(Sema &S, AnalysisDeclContext &AC,2739                                         std::pair<Iterator, Iterator> PUDs) {2740 2741  if (PUDs.first == PUDs.second)2742    return;2743 2744  for (auto I = PUDs.first; I != PUDs.second; ++I) {2745    for (const Stmt *S : I->Stmts)2746      AC.registerForcedBlockExpression(S);2747  }2748 2749  if (AC.getCFG()) {2750    CFGReverseBlockReachabilityAnalysis *Analysis =2751        AC.getCFGReachablityAnalysis();2752 2753    for (auto I = PUDs.first; I != PUDs.second; ++I) {2754      const auto &D = *I;2755      if (llvm::all_of(D.Stmts, [&](const Stmt *St) {2756            const CFGBlock *Block = AC.getBlockForRegisteredExpression(St);2757            // FIXME: We should be able to assert that block is non-null, but2758            // the CFG analysis can skip potentially-evaluated expressions in2759            // edge cases; see test/Sema/vla-2.c.2760            if (Block && Analysis)2761              if (!Analysis->isReachable(&AC.getCFG()->getEntry(), Block))2762                return false;2763            return true;2764          })) {2765        S.Diag(D.Loc, D.PD);2766      }2767    }2768  } else {2769    for (auto I = PUDs.first; I != PUDs.second; ++I)2770      S.Diag(I->Loc, I->PD);2771  }2772}2773 2774void sema::AnalysisBasedWarnings::registerVarDeclWarning(2775    VarDecl *VD, clang::sema::PossiblyUnreachableDiag PUD) {2776  VarDeclPossiblyUnreachableDiags.emplace(VD, PUD);2777}2778 2779void sema::AnalysisBasedWarnings::issueWarningsForRegisteredVarDecl(2780    VarDecl *VD) {2781  if (!llvm::is_contained(VarDeclPossiblyUnreachableDiags, VD))2782    return;2783 2784  AnalysisDeclContext AC(/*Mgr=*/nullptr, VD);2785 2786  AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true;2787  AC.getCFGBuildOptions().AddEHEdges = false;2788  AC.getCFGBuildOptions().AddInitializers = true;2789  AC.getCFGBuildOptions().AddImplicitDtors = true;2790  AC.getCFGBuildOptions().AddTemporaryDtors = true;2791  AC.getCFGBuildOptions().AddCXXNewAllocator = false;2792  AC.getCFGBuildOptions().AddCXXDefaultInitExprInCtors = true;2793 2794  auto Range = VarDeclPossiblyUnreachableDiags.equal_range(VD);2795  auto SecondRange =2796      llvm::make_second_range(llvm::make_range(Range.first, Range.second));2797  emitPossiblyUnreachableDiags(2798      S, AC, std::make_pair(SecondRange.begin(), SecondRange.end()));2799}2800 2801// An AST Visitor that calls a callback function on each callable DEFINITION2802// that is NOT in a dependent context:2803class CallableVisitor : public DynamicRecursiveASTVisitor {2804private:2805  llvm::function_ref<void(const Decl *)> Callback;2806  const Module *const TUModule;2807 2808public:2809  CallableVisitor(llvm::function_ref<void(const Decl *)> Callback,2810                  const Module *const TUModule)2811      : Callback(Callback), TUModule(TUModule) {2812    ShouldVisitTemplateInstantiations = true;2813    ShouldVisitImplicitCode = false;2814  }2815 2816  bool TraverseDecl(Decl *Node) override {2817    // For performance reasons, only validate the current translation unit's2818    // module, and not modules it depends on.2819    // See https://issues.chromium.org/issues/351909443 for details.2820    if (Node && Node->getOwningModule() == TUModule)2821      return DynamicRecursiveASTVisitor::TraverseDecl(Node);2822    return true;2823  }2824 2825  bool VisitFunctionDecl(FunctionDecl *Node) override {2826    if (cast<DeclContext>(Node)->isDependentContext())2827      return true; // Not to analyze dependent decl2828    // `FunctionDecl->hasBody()` returns true if the function has a body2829    // somewhere defined.  But we want to know if this `Node` has a body2830    // child.  So we use `doesThisDeclarationHaveABody`:2831    if (Node->doesThisDeclarationHaveABody())2832      Callback(Node);2833    return true;2834  }2835 2836  bool VisitBlockDecl(BlockDecl *Node) override {2837    if (cast<DeclContext>(Node)->isDependentContext())2838      return true; // Not to analyze dependent decl2839    Callback(Node);2840    return true;2841  }2842 2843  bool VisitObjCMethodDecl(ObjCMethodDecl *Node) override {2844    if (cast<DeclContext>(Node)->isDependentContext())2845      return true; // Not to analyze dependent decl2846    if (Node->hasBody())2847      Callback(Node);2848    return true;2849  }2850 2851  bool VisitLambdaExpr(LambdaExpr *Node) override {2852    return VisitFunctionDecl(Node->getCallOperator());2853  }2854};2855 2856namespace clang::lifetimes {2857namespace {2858class LifetimeSafetyReporterImpl : public LifetimeSafetyReporter {2859 2860public:2861  LifetimeSafetyReporterImpl(Sema &S) : S(S) {}2862 2863  void reportUseAfterFree(const Expr *IssueExpr, const Expr *UseExpr,2864                          SourceLocation FreeLoc, Confidence C) override {2865    S.Diag(IssueExpr->getExprLoc(),2866           C == Confidence::Definite2867               ? diag::warn_lifetime_safety_loan_expires_permissive2868               : diag::warn_lifetime_safety_loan_expires_strict)2869        << IssueExpr->getEndLoc();2870    S.Diag(FreeLoc, diag::note_lifetime_safety_destroyed_here);2871    S.Diag(UseExpr->getExprLoc(), diag::note_lifetime_safety_used_here)2872        << UseExpr->getEndLoc();2873  }2874 2875  void reportUseAfterReturn(const Expr *IssueExpr, const Expr *EscapeExpr,2876                            SourceLocation ExpiryLoc, Confidence C) override {2877    S.Diag(IssueExpr->getExprLoc(),2878           C == Confidence::Definite2879               ? diag::warn_lifetime_safety_return_stack_addr_permissive2880               : diag::warn_lifetime_safety_return_stack_addr_strict)2881        << IssueExpr->getEndLoc();2882 2883    S.Diag(EscapeExpr->getExprLoc(), diag::note_lifetime_safety_returned_here)2884        << EscapeExpr->getEndLoc();2885  }2886 2887private:2888  Sema &S;2889};2890} // namespace2891} // namespace clang::lifetimes2892 2893void clang::sema::AnalysisBasedWarnings::IssueWarnings(2894     TranslationUnitDecl *TU) {2895  if (!TU)2896    return; // This is unexpected, give up quietly.2897 2898  DiagnosticsEngine &Diags = S.getDiagnostics();2899 2900  if (S.hasUncompilableErrorOccurred() || Diags.getIgnoreAllWarnings())2901    // exit if having uncompilable errors or ignoring all warnings:2902    return;2903 2904  DiagnosticOptions &DiagOpts = Diags.getDiagnosticOptions();2905 2906  // UnsafeBufferUsage analysis settings.2907  bool UnsafeBufferUsageCanEmitSuggestions = S.getLangOpts().CPlusPlus20;2908  bool UnsafeBufferUsageShouldEmitSuggestions =  // Should != Can.2909      UnsafeBufferUsageCanEmitSuggestions &&2910      DiagOpts.ShowSafeBufferUsageSuggestions;2911  bool UnsafeBufferUsageShouldSuggestSuggestions =2912      UnsafeBufferUsageCanEmitSuggestions &&2913      !DiagOpts.ShowSafeBufferUsageSuggestions;2914  UnsafeBufferUsageReporter R(S, UnsafeBufferUsageShouldSuggestSuggestions);2915 2916  // The Callback function that performs analyses:2917  auto CallAnalyzers = [&](const Decl *Node) -> void {2918    if (Node->hasAttr<UnsafeBufferUsageAttr>())2919      return;2920 2921    // Perform unsafe buffer usage analysis:2922    if (!Diags.isIgnored(diag::warn_unsafe_buffer_operation,2923                         Node->getBeginLoc()) ||2924        !Diags.isIgnored(diag::warn_unsafe_buffer_variable,2925                         Node->getBeginLoc()) ||2926        !Diags.isIgnored(diag::warn_unsafe_buffer_usage_in_container,2927                         Node->getBeginLoc()) ||2928        !Diags.isIgnored(diag::warn_unsafe_buffer_libc_call,2929                         Node->getBeginLoc())) {2930      clang::checkUnsafeBufferUsage(Node, R,2931                                    UnsafeBufferUsageShouldEmitSuggestions);2932    }2933 2934    // More analysis ...2935  };2936  // Emit per-function analysis-based warnings that require the whole-TU2937  // reasoning. Check if any of them is enabled at all before scanning the AST:2938  if (!Diags.isIgnored(diag::warn_unsafe_buffer_operation, SourceLocation()) ||2939      !Diags.isIgnored(diag::warn_unsafe_buffer_variable, SourceLocation()) ||2940      !Diags.isIgnored(diag::warn_unsafe_buffer_usage_in_container,2941                       SourceLocation()) ||2942      (!Diags.isIgnored(diag::warn_unsafe_buffer_libc_call, SourceLocation()) &&2943       S.getLangOpts().CPlusPlus /* only warn about libc calls in C++ */)) {2944    CallableVisitor(CallAnalyzers, TU->getOwningModule())2945        .TraverseTranslationUnitDecl(TU);2946  }2947}2948 2949void clang::sema::AnalysisBasedWarnings::IssueWarnings(2950    sema::AnalysisBasedWarnings::Policy P, sema::FunctionScopeInfo *fscope,2951    const Decl *D, QualType BlockType) {2952 2953  // We avoid doing analysis-based warnings when there are errors for2954  // two reasons:2955  // (1) The CFGs often can't be constructed (if the body is invalid), so2956  //     don't bother trying.2957  // (2) The code already has problems; running the analysis just takes more2958  //     time.2959  DiagnosticsEngine &Diags = S.getDiagnostics();2960 2961  // Do not do any analysis if we are going to just ignore them.2962  if (Diags.getIgnoreAllWarnings() ||2963      (Diags.getSuppressSystemWarnings() &&2964       S.SourceMgr.isInSystemHeader(D->getLocation())))2965    return;2966 2967  // For code in dependent contexts, we'll do this at instantiation time.2968  if (cast<DeclContext>(D)->isDependentContext())2969    return;2970 2971  if (S.hasUncompilableErrorOccurred()) {2972    // Flush out any possibly unreachable diagnostics.2973    flushDiagnostics(S, fscope);2974    return;2975  }2976 2977  const Stmt *Body = D->getBody();2978  assert(Body);2979 2980  // Construct the analysis context with the specified CFG build options.2981  AnalysisDeclContext AC(/* AnalysisDeclContextManager */ nullptr, D);2982 2983  // Don't generate EH edges for CallExprs as we'd like to avoid the n^22984  // explosion for destructors that can result and the compile time hit.2985  AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true;2986  AC.getCFGBuildOptions().AddEHEdges = false;2987  AC.getCFGBuildOptions().AddInitializers = true;2988  AC.getCFGBuildOptions().AddImplicitDtors = true;2989  AC.getCFGBuildOptions().AddTemporaryDtors = true;2990  AC.getCFGBuildOptions().AddCXXNewAllocator = false;2991  AC.getCFGBuildOptions().AddCXXDefaultInitExprInCtors = true;2992 2993  bool EnableLifetimeSafetyAnalysis = S.getLangOpts().EnableLifetimeSafety;2994 2995  if (EnableLifetimeSafetyAnalysis)2996    AC.getCFGBuildOptions().AddLifetime = true;2997 2998  // Force that certain expressions appear as CFGElements in the CFG.  This2999  // is used to speed up various analyses.3000  // FIXME: This isn't the right factoring.  This is here for initial3001  // prototyping, but we need a way for analyses to say what expressions they3002  // expect to always be CFGElements and then fill in the BuildOptions3003  // appropriately.  This is essentially a layering violation.3004  if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis ||3005      P.enableConsumedAnalysis || EnableLifetimeSafetyAnalysis) {3006    // Unreachable code analysis and thread safety require a linearized CFG.3007    AC.getCFGBuildOptions().setAllAlwaysAdd();3008  } else {3009    AC.getCFGBuildOptions()3010      .setAlwaysAdd(Stmt::BinaryOperatorClass)3011      .setAlwaysAdd(Stmt::CompoundAssignOperatorClass)3012      .setAlwaysAdd(Stmt::BlockExprClass)3013      .setAlwaysAdd(Stmt::CStyleCastExprClass)3014      .setAlwaysAdd(Stmt::DeclRefExprClass)3015      .setAlwaysAdd(Stmt::ImplicitCastExprClass)3016      .setAlwaysAdd(Stmt::UnaryOperatorClass);3017  }3018 3019  // Install the logical handler.3020  std::optional<LogicalErrorHandler> LEH;3021  if (LogicalErrorHandler::hasActiveDiagnostics(Diags, D->getBeginLoc())) {3022    LEH.emplace(S);3023    AC.getCFGBuildOptions().Observer = &*LEH;3024  }3025 3026  // Emit delayed diagnostics.3027  auto &PUDs = fscope->PossiblyUnreachableDiags;3028  emitPossiblyUnreachableDiags(S, AC, std::make_pair(PUDs.begin(), PUDs.end()));3029 3030  // Warning: check missing 'return'3031  if (P.enableCheckFallThrough) {3032    const CheckFallThroughDiagnostics &CD =3033        (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()3034         : (isa<CXXMethodDecl>(D) &&3035            cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call &&3036            cast<CXXMethodDecl>(D)->getParent()->isLambda())3037             ? CheckFallThroughDiagnostics::MakeForLambda()3038             : (fscope->isCoroutine()3039                    ? CheckFallThroughDiagnostics::MakeForCoroutine(D)3040                    : CheckFallThroughDiagnostics::MakeForFunction(S, D)));3041    CheckFallThroughForBody(S, D, Body, BlockType, CD, AC);3042  }3043 3044  // Warning: check for unreachable code3045  if (P.enableCheckUnreachable) {3046    // Only check for unreachable code on non-template instantiations.3047    // Different template instantiations can effectively change the control-flow3048    // and it is very difficult to prove that a snippet of code in a template3049    // is unreachable for all instantiations.3050    bool isTemplateInstantiation = false;3051    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D))3052      isTemplateInstantiation = Function->isTemplateInstantiation();3053    if (!isTemplateInstantiation)3054      CheckUnreachable(S, AC);3055  }3056 3057  // Check for thread safety violations3058  if (P.enableThreadSafetyAnalysis) {3059    SourceLocation FL = AC.getDecl()->getLocation();3060    SourceLocation FEL = AC.getDecl()->getEndLoc();3061    threadSafety::ThreadSafetyReporter Reporter(S, FL, FEL);3062    if (!Diags.isIgnored(diag::warn_thread_safety_beta, D->getBeginLoc()))3063      Reporter.setIssueBetaWarnings(true);3064    if (!Diags.isIgnored(diag::warn_thread_safety_verbose, D->getBeginLoc()))3065      Reporter.setVerbose(true);3066 3067    threadSafety::runThreadSafetyAnalysis(AC, Reporter,3068                                          &S.ThreadSafetyDeclCache);3069    Reporter.emitDiagnostics();3070  }3071 3072  // Check for violations of consumed properties.3073  if (P.enableConsumedAnalysis) {3074    consumed::ConsumedWarningsHandler WarningHandler(S);3075    consumed::ConsumedAnalyzer Analyzer(WarningHandler);3076    Analyzer.run(AC);3077  }3078 3079  if (!Diags.isIgnored(diag::warn_uninit_var, D->getBeginLoc()) ||3080      !Diags.isIgnored(diag::warn_sometimes_uninit_var, D->getBeginLoc()) ||3081      !Diags.isIgnored(diag::warn_maybe_uninit_var, D->getBeginLoc()) ||3082      !Diags.isIgnored(diag::warn_uninit_const_reference, D->getBeginLoc()) ||3083      !Diags.isIgnored(diag::warn_uninit_const_pointer, D->getBeginLoc())) {3084    if (CFG *cfg = AC.getCFG()) {3085      UninitValsDiagReporter reporter(S);3086      UninitVariablesAnalysisStats stats;3087      std::memset(&stats, 0, sizeof(UninitVariablesAnalysisStats));3088      runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC,3089                                        reporter, stats);3090 3091      if (S.CollectStats && stats.NumVariablesAnalyzed > 0) {3092        ++NumUninitAnalysisFunctions;3093        NumUninitAnalysisVariables += stats.NumVariablesAnalyzed;3094        NumUninitAnalysisBlockVisits += stats.NumBlockVisits;3095        MaxUninitAnalysisVariablesPerFunction =3096            std::max(MaxUninitAnalysisVariablesPerFunction,3097                     stats.NumVariablesAnalyzed);3098        MaxUninitAnalysisBlockVisitsPerFunction =3099            std::max(MaxUninitAnalysisBlockVisitsPerFunction,3100                     stats.NumBlockVisits);3101      }3102    }3103  }3104 3105  // TODO: Enable lifetime safety analysis for other languages once it is3106  // stable.3107  if (EnableLifetimeSafetyAnalysis && S.getLangOpts().CPlusPlus) {3108    if (AC.getCFG()) {3109      lifetimes::LifetimeSafetyReporterImpl LifetimeSafetyReporter(S);3110      lifetimes::runLifetimeSafetyAnalysis(AC, &LifetimeSafetyReporter);3111    }3112  }3113  // Check for violations of "called once" parameter properties.3114  if (S.getLangOpts().ObjC && !S.getLangOpts().CPlusPlus &&3115      shouldAnalyzeCalledOnceParameters(Diags, D->getBeginLoc())) {3116    if (AC.getCFG()) {3117      CalledOnceCheckReporter Reporter(S, IPData->CalledOnceData);3118      checkCalledOnceParameters(3119          AC, Reporter,3120          shouldAnalyzeCalledOnceConventions(Diags, D->getBeginLoc()));3121    }3122  }3123 3124  bool FallThroughDiagFull =3125      !Diags.isIgnored(diag::warn_unannotated_fallthrough, D->getBeginLoc());3126  bool FallThroughDiagPerFunction = !Diags.isIgnored(3127      diag::warn_unannotated_fallthrough_per_function, D->getBeginLoc());3128  if (FallThroughDiagFull || FallThroughDiagPerFunction ||3129      fscope->HasFallthroughStmt) {3130    DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull);3131  }3132 3133  if (S.getLangOpts().ObjCWeak &&3134      !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, D->getBeginLoc()))3135    diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap());3136 3137 3138  // Check for infinite self-recursion in functions3139  if (!Diags.isIgnored(diag::warn_infinite_recursive_function,3140                       D->getBeginLoc())) {3141    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {3142      checkRecursiveFunction(S, FD, Body, AC);3143    }3144  }3145 3146  // Check for throw out of non-throwing function.3147  if (!Diags.isIgnored(diag::warn_throw_in_noexcept_func, D->getBeginLoc()))3148    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))3149      if (S.getLangOpts().CPlusPlus && !fscope->isCoroutine() && isNoexcept(FD))3150        checkThrowInNonThrowingFunc(S, FD, AC);3151 3152  // If none of the previous checks caused a CFG build, trigger one here3153  // for the logical error handler.3154  if (LogicalErrorHandler::hasActiveDiagnostics(Diags, D->getBeginLoc())) {3155    AC.getCFG();3156  }3157 3158  // Clear any of our policy overrides.3159  clearOverrides();3160 3161  // Collect statistics about the CFG if it was built.3162  if (S.CollectStats && AC.isCFGBuilt()) {3163    ++NumFunctionsAnalyzed;3164    if (CFG *cfg = AC.getCFG()) {3165      // If we successfully built a CFG for this context, record some more3166      // detail information about it.3167      NumCFGBlocks += cfg->getNumBlockIDs();3168      MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction,3169                                         cfg->getNumBlockIDs());3170    } else {3171      ++NumFunctionsWithBadCFGs;3172    }3173  }3174}3175 3176void clang::sema::AnalysisBasedWarnings::PrintStats() const {3177  llvm::errs() << "\n*** Analysis Based Warnings Stats:\n";3178 3179  unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs;3180  unsigned AvgCFGBlocksPerFunction =3181      !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt;3182  llvm::errs() << NumFunctionsAnalyzed << " functions analyzed ("3183               << NumFunctionsWithBadCFGs << " w/o CFGs).\n"3184               << "  " << NumCFGBlocks << " CFG blocks built.\n"3185               << "  " << AvgCFGBlocksPerFunction3186               << " average CFG blocks per function.\n"3187               << "  " << MaxCFGBlocksPerFunction3188               << " max CFG blocks per function.\n";3189 3190  unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 03191      : NumUninitAnalysisVariables/NumUninitAnalysisFunctions;3192  unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 03193      : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions;3194  llvm::errs() << NumUninitAnalysisFunctions3195               << " functions analyzed for uninitialiazed variables\n"3196               << "  " << NumUninitAnalysisVariables << " variables analyzed.\n"3197               << "  " << AvgUninitVariablesPerFunction3198               << " average variables per function.\n"3199               << "  " << MaxUninitAnalysisVariablesPerFunction3200               << " max variables per function.\n"3201               << "  " << NumUninitAnalysisBlockVisits << " block visits.\n"3202               << "  " << AvgUninitBlockVisitsPerFunction3203               << " average block visits per function.\n"3204               << "  " << MaxUninitAnalysisBlockVisitsPerFunction3205               << " max block visits per function.\n";3206}3207