1dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis -*- C++ -*-=//
2dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//
3dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//                     The LLVM Compiler Infrastructure
4dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//
5dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// This file is distributed under the University of Illinois Open Source
6dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// License. See LICENSE.TXT for details.
7dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//
8dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
9dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//
10dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// This file defines analysis_warnings::[Policy,Executor].
11dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Together they are used by Sema to issue warnings based on inexpensive
12dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// static analysis algorithms in libAnalysis.
13dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//
14dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
15dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
16e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "clang/Sema/AnalysisBasedWarnings.h"
17384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h"
1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/DeclObjC.h"
196f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek#include "clang/AST/EvaluatedExprVisitor.h"
2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/ExprCXX.h"
2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/ExprObjC.h"
22b5cd1220dd650a358622241237aa595c5d675506Jordan Rose#include "clang/AST/ParentMap.h"
23e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith#include "clang/AST/RecursiveASTVisitor.h"
2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/StmtCXX.h"
2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/StmtObjC.h"
2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/StmtVisitor.h"
27351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
28df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins#include "clang/Analysis/Analyses/Consumed.h"
2955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Analysis/Analyses/ReachableCode.h"
30402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski#include "clang/Analysis/Analyses/ThreadSafety.h"
316f34213f8d6ae8c77685b53664527e39bfaaca3bTed Kremenek#include "clang/Analysis/Analyses/UninitializedValues.h"
3255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Analysis/AnalysisContext.h"
3355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Analysis/CFG.h"
3455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Analysis/CFGStmtMap.h"
3555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/SourceLocation.h"
3655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/SourceManager.h"
3755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Lexer.h"
3855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Preprocessor.h"
3955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/ScopeInfo.h"
4055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/SemaInternal.h"
4166da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko#include "llvm/ADT/ArrayRef.h"
42dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/ADT/BitVector.h"
433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/FoldingSet.h"
443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/ImmutableMap.h"
453285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella#include "llvm/ADT/MapVector.h"
463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/PostOrderIterator.h"
471952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko#include "llvm/ADT/SmallString.h"
483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/SmallVector.h"
4975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski#include "llvm/ADT/StringRef.h"
50dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/Support/Casting.h"
513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include <algorithm>
5255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include <deque>
53e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith#include <iterator>
543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include <vector>
55dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
56dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekusing namespace clang;
57dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
58dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
59dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Unreachable code analysis.
60dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
61dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
62dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremeneknamespace {
63dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  class UnreachableCodeHandler : public reachable_code::Callback {
64dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    Sema &S;
65dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  public:
66dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    UnreachableCodeHandler(Sema &s) : S(s) {}
67dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void HandleUnreachable(reachable_code::UnreachableKind UK,
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                           SourceLocation L,
70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                           SourceRange SilenceableCondVal,
71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                           SourceRange R1,
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                           SourceRange R2) override {
73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      unsigned diag = diag::warn_unreachable;
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      switch (UK) {
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        case reachable_code::UK_Break:
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          diag = diag::warn_unreachable_break;
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          break;
78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        case reachable_code::UK_Return:
79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          diag = diag::warn_unreachable_return;
80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          break;
81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        case reachable_code::UK_Loop_Increment:
82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          diag = diag::warn_unreachable_loop_increment;
83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          break;
84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        case reachable_code::UK_Other:
85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          break;
86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      S.Diag(L, diag) << R1 << R2;
89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      SourceLocation Open = SilenceableCondVal.getBegin();
91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (Open.isValid()) {
926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        SourceLocation Close = SilenceableCondVal.getEnd();
936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        Close = S.getLocForEndOfToken(Close);
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (Close.isValid()) {
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          S.Diag(Open, diag::note_unreachable_silence)
96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            << FixItHint::CreateInsertion(Open, "/* DISABLES CODE */ (")
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            << FixItHint::CreateInsertion(Close, ")");
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        }
99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
100dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
101dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  };
102dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
103dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
104dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckUnreachable - Check for unreachable code.
1051d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekstatic void CheckUnreachable(Sema &S, AnalysisDeclContext &AC) {
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // As a heuristic prune all diagnostics not in the main file.  Currently
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // the majority of warnings in headers are false positives.  These
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // are largely caused by configuration state, e.g. preprocessor
109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // defined code, etc.
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  //
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Note that this is also a performance optimization.  Analyzing
112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // headers many times can be expensive.
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!S.getSourceManager().isInMainFile(AC.getDecl()->getLocStart()))
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
116dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  UnreachableCodeHandler UC(S);
117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  reachable_code::FindUnreachableCode(AC, S.getPreprocessor(), UC);
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1200e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesnamespace {
1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \brief Warn on logical operator errors in CFGBuilder
1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass LogicalErrorHandler : public CFGCallback {
1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Sema &S;
1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic:
1266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  LogicalErrorHandler(Sema &S) : CFGCallback(), S(S) {}
1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  static bool HasMacroID(const Expr *E) {
1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (E->getExprLoc().isMacroID())
1306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return true;
1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Recurse to children.
1336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (ConstStmtRange SubStmts = E->children(); SubStmts; ++SubStmts)
1346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (*SubStmts)
1356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        if (const Expr *SubExpr = dyn_cast<Expr>(*SubStmts))
1366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          if (HasMacroID(SubExpr))
1376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines            return true;
1386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return false;
1406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
14233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) override {
1436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (HasMacroID(B))
1446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return;
1456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    SourceRange DiagRange = B->getSourceRange();
1476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    S.Diag(B->getExprLoc(), diag::warn_tautological_overlap_comparison)
1486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        << DiagRange << isAlwaysTrue;
1496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
15133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  void compareBitwiseEquality(const BinaryOperator *B,
15233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar                              bool isAlwaysTrue) override {
1536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (HasMacroID(B))
1546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return;
1556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    SourceRange DiagRange = B->getSourceRange();
1576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    S.Diag(B->getExprLoc(), diag::warn_comparison_bitwise_always)
1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        << DiagRange << isAlwaysTrue;
1596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
1610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} // namespace
1626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===//
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Check for infinite self-recursion in functions
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===//
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// All blocks are in one of three states.  States are ordered so that blocks
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// can only move to higher states.
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesenum RecursiveState {
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  FoundNoPath,
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  FoundPath,
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  FoundPathWithNoRecursiveCall
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void checkForFunctionCall(Sema &S, const FunctionDecl *FD,
176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 CFGBlock &Block, unsigned ExitID,
177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 llvm::SmallVectorImpl<RecursiveState> &States,
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 RecursiveState State) {
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned ID = Block.getBlockID();
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // A block's state can only move to a higher state.
182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (States[ID] >= State)
183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  States[ID] = State;
186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Found a path to the exit node without a recursive call.
188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (ID == ExitID && State == FoundPathWithNoRecursiveCall)
189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (State == FoundPathWithNoRecursiveCall) {
192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // If the current state is FoundPathWithNoRecursiveCall, the successors
193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // will be either FoundPathWithNoRecursiveCall or FoundPath.  To determine
194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // which, process all the Stmt's in this block to find any recursive calls.
1956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &B : Block) {
1966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (B.getKind() != CFGElement::Statement)
197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        continue;
198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      const CallExpr *CE = dyn_cast<CallExpr>(B.getAs<CFGStmt>()->getStmt());
200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (CE && CE->getCalleeDecl() &&
201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          CE->getCalleeDecl()->getCanonicalDecl() == FD) {
202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        // Skip function calls which are qualified with a templated class.
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                CE->getCallee()->IgnoreParenImpCasts())) {
206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (NestedNameSpecifier *NNS = DRE->getQualifier()) {
207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            if (NNS->getKind() == NestedNameSpecifier::TypeSpec &&
208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                isa<TemplateSpecializationType>(NNS->getAsType())) {
209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines               continue;
210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            }
211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          }
212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        }
213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE)) {
215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (isa<CXXThisExpr>(MCE->getImplicitObjectArgument()) ||
216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              !MCE->getMethodDecl()->isVirtual()) {
217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            State = FoundPath;
218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            break;
219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          }
220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        } else {
221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          State = FoundPath;
222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          break;
223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        }
224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
225651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (CFGBlock::succ_iterator I = Block.succ_begin(), E = Block.succ_end();
229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       I != E; ++I)
230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*I)
231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      checkForFunctionCall(S, FD, **I, ExitID, States, State);
232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void checkRecursiveFunction(Sema &S, const FunctionDecl *FD,
235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   const Stmt *Body,
236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   AnalysisDeclContext &AC) {
237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  FD = FD->getCanonicalDecl();
238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Only run on non-templated functions and non-templated members of
240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // templated classes.
241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate &&
242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      FD->getTemplatedKind() != FunctionDecl::TK_MemberSpecialization)
243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CFG *cfg = AC.getCFG();
2466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!cfg) return;
247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // If the exit block is unreachable, skip processing the function.
249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (cfg->getExit().pred_empty())
250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Mark all nodes as FoundNoPath, then begin processing the entry block.
253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::SmallVector<RecursiveState, 16> states(cfg->getNumBlockIDs(),
254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                               FoundNoPath);
255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  checkForFunctionCall(S, FD, cfg->getEntry(), cfg->getExit().getBlockID(),
256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                       states, FoundPathWithNoRecursiveCall);
257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Check that the exit block is reachable.  This prevents triggering the
259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // warning on functions that do not terminate.
260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (states[cfg->getExit().getBlockID()] == FoundPath)
261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    S.Diag(Body->getLocStart(), diag::warn_infinite_recursive_function);
262dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
263dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
264dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
265dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Check for missing return value.
266dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
267dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
26816565aa95b086fb239baf82335dccc1b1ec93942John McCallenum ControlFlowKind {
26916565aa95b086fb239baf82335dccc1b1ec93942John McCall  UnknownFallThrough,
27016565aa95b086fb239baf82335dccc1b1ec93942John McCall  NeverFallThrough,
27116565aa95b086fb239baf82335dccc1b1ec93942John McCall  MaybeFallThrough,
27216565aa95b086fb239baf82335dccc1b1ec93942John McCall  AlwaysFallThrough,
27316565aa95b086fb239baf82335dccc1b1ec93942John McCall  NeverFallThroughOrReturn
27416565aa95b086fb239baf82335dccc1b1ec93942John McCall};
275dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
276dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThrough - Check that we don't fall off the end of a
277dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// Statement that should return a value.
278dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek///
279f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// \returns AlwaysFallThrough iff we always fall off the end of the statement,
280f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// MaybeFallThrough iff we might or might not fall off the end,
281f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// NeverFallThroughOrReturn iff we never fall off the end of the statement or
282f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// return.  We assume NeverFallThrough iff we never fall off the end of the
283dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// statement but we may return.  We assume that functions not marked noreturn
284dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// will return.
2851d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekstatic ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) {
286dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  CFG *cfg = AC.getCFG();
2876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!cfg) return UnknownFallThrough;
288dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
289dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // The CFG leaves in dead things, and we don't want the dead code paths to
290dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // confuse us, so we mark all live things first.
291dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  llvm::BitVector live(cfg->getNumBlockIDs());
2920f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek  unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(),
293dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                                          live);
294dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
295dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool AddEHEdges = AC.getAddEHEdges();
296dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (!AddEHEdges && count != cfg->getNumBlockIDs())
297dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // When there are things remaining dead, and we didn't add EH edges
298dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // from CallExprs to the catch clauses, we have to go back and
299dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // mark them as live.
3006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto *B : *cfg) {
3016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (!live[B->getBlockID()]) {
3026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        if (B->pred_begin() == B->pred_end()) {
3036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          if (B->getTerminator() && isa<CXXTryStmt>(B->getTerminator()))
304dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek            // When not adding EH edges from calls, catch clauses
305dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek            // can otherwise seem dead.  Avoid noting them as dead.
3066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines            count += reachable_code::ScanReachableFromBlock(B, live);
307dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          continue;
308dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        }
309dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
310dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
311dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
312dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Now we know what is live, we check the live precessors of the exit block
313dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // and look for fall through paths, being careful to ignore normal returns,
314dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // and exceptional paths.
315dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasLiveReturn = false;
316dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasFakeEdge = false;
317dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasPlainEdge = false;
318dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasAbnormalEdge = false;
31990b828aa279542559f655d1af666580288cb1841Ted Kremenek
32090b828aa279542559f655d1af666580288cb1841Ted Kremenek  // Ignore default cases that aren't likely to be reachable because all
32190b828aa279542559f655d1af666580288cb1841Ted Kremenek  // enums in a switch(X) have explicit case statements.
32290b828aa279542559f655d1af666580288cb1841Ted Kremenek  CFGBlock::FilterOptions FO;
32390b828aa279542559f655d1af666580288cb1841Ted Kremenek  FO.IgnoreDefaultsWithCoveredEnums = 1;
32490b828aa279542559f655d1af666580288cb1841Ted Kremenek
32590b828aa279542559f655d1af666580288cb1841Ted Kremenek  for (CFGBlock::filtered_pred_iterator
32690b828aa279542559f655d1af666580288cb1841Ted Kremenek	 I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) {
32790b828aa279542559f655d1af666580288cb1841Ted Kremenek    const CFGBlock& B = **I;
328dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (!live[B.getBlockID()])
329dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
3305811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek
331e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    // Skip blocks which contain an element marked as no-return. They don't
332e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    // represent actually viable edges into the exit block, so mark them as
333e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    // abnormal.
334e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    if (B.hasNoReturnElement()) {
335e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth      HasAbnormalEdge = true;
336e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth      continue;
337e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    }
338e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth
3395811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // Destructors can appear after the 'return' in the CFG.  This is
3405811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // normal.  We need to look pass the destructors for the return
3415811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // statement (if it exists).
3425811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend();
343e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth
344e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    for ( ; ri != re ; ++ri)
345fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie      if (ri->getAs<CFGStmt>())
3465811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek        break;
347e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth
3485811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // No more CFGElements in the block?
3495811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    if (ri == re) {
350dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) {
351dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasAbnormalEdge = true;
352dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        continue;
353dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
354dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      // A labeled empty statement, or the entry block...
355dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasPlainEdge = true;
356dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
357dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
358f39e6a388aaa2f155b46c61e655784b2473218ebTed Kremenek
359fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie    CFGStmt CS = ri->castAs<CFGStmt>();
360f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek    const Stmt *S = CS.getStmt();
361dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<ReturnStmt>(S)) {
362dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasLiveReturn = true;
363dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
364dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
365dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<ObjCAtThrowStmt>(S)) {
366dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasFakeEdge = true;
367dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
368dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
369dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<CXXThrowExpr>(S)) {
370dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasFakeEdge = true;
371dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
372dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
3738cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier    if (isa<MSAsmStmt>(S)) {
3748cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      // TODO: Verify this is correct.
3758cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      HasFakeEdge = true;
3768cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      HasLiveReturn = true;
3778cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      continue;
3788cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier    }
379dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<CXXTryStmt>(S)) {
380dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasAbnormalEdge = true;
381dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
382dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
383e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit())
384e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth        == B.succ_end()) {
385e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth      HasAbnormalEdge = true;
386e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth      continue;
387dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
388e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth
389e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    HasPlainEdge = true;
390dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
391dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (!HasPlainEdge) {
392dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (HasLiveReturn)
393dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      return NeverFallThrough;
394dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return NeverFallThroughOrReturn;
395dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
396dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn)
397dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return MaybeFallThrough;
398dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // This says AlwaysFallThrough for calls to functions that are not marked
399dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // noreturn, that don't return.  If people would like this warning to be more
400dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // accurate, such functions should be marked as noreturn.
401dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  return AlwaysFallThrough;
402dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
403dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
4043c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohmannamespace {
4053c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman
406dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstruct CheckFallThroughDiagnostics {
407dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_MaybeFallThrough_HasNoReturn;
408dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_MaybeFallThrough_ReturnsNonVoid;
409dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_AlwaysFallThrough_HasNoReturn;
410dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
411dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_NeverFallThroughOrReturn;
412793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor  enum { Function, Block, Lambda } funMode;
4130827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis  SourceLocation FuncLoc;
414d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
415ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor  static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
416dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CheckFallThroughDiagnostics D;
4170827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    D.FuncLoc = Func->getLocation();
418dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_HasNoReturn =
419dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_noreturn_function;
420dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_ReturnsNonVoid =
421dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_maybe_falloff_nonvoid_function;
422dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_HasNoReturn =
423dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_noreturn_function;
424dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_ReturnsNonVoid =
425dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_nonvoid_function;
426ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor
427ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    // Don't suggest that virtual functions be marked "noreturn", since they
428ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    // might be overridden by non-noreturn functions.
429ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    bool isVirtualMethod = false;
430ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func))
431ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor      isVirtualMethod = Method->isVirtual();
432ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor
433fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor    // Don't suggest that template instantiations be marked "noreturn"
434fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor    bool isTemplateInstantiation = false;
43575df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func))
43675df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek      isTemplateInstantiation = Function->isTemplateInstantiation();
437fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor
438fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor    if (!isVirtualMethod && !isTemplateInstantiation)
439ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor      D.diag_NeverFallThroughOrReturn =
440ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor        diag::warn_suggest_noreturn_function;
441ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    else
442ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor      D.diag_NeverFallThroughOrReturn = 0;
443ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor
444793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.funMode = Function;
445dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return D;
446dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
447d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
448dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  static CheckFallThroughDiagnostics MakeForBlock() {
449dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CheckFallThroughDiagnostics D;
450dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_HasNoReturn =
451dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_noreturn_block_has_return_expr;
452dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_ReturnsNonVoid =
453dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_maybe_falloff_nonvoid_block;
454dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_HasNoReturn =
455dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_noreturn_block_has_return_expr;
456dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_ReturnsNonVoid =
457dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_falloff_nonvoid_block;
4586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    D.diag_NeverFallThroughOrReturn = 0;
459793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.funMode = Block;
460793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    return D;
461793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor  }
462793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor
463793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor  static CheckFallThroughDiagnostics MakeForLambda() {
464793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    CheckFallThroughDiagnostics D;
465793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.diag_MaybeFallThrough_HasNoReturn =
466793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor      diag::err_noreturn_lambda_has_return_expr;
467793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.diag_MaybeFallThrough_ReturnsNonVoid =
468793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor      diag::warn_maybe_falloff_nonvoid_lambda;
469793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.diag_AlwaysFallThrough_HasNoReturn =
470793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor      diag::err_noreturn_lambda_has_return_expr;
471793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.diag_AlwaysFallThrough_ReturnsNonVoid =
472793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor      diag::warn_falloff_nonvoid_lambda;
473793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.diag_NeverFallThroughOrReturn = 0;
474793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.funMode = Lambda;
475dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return D;
476dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
477d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
478d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid,
479dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                        bool HasNoReturn) const {
480793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    if (funMode == Function) {
4810827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      return (ReturnsVoid ||
482c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines              D.isIgnored(diag::warn_maybe_falloff_nonvoid_function,
483c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                          FuncLoc)) &&
484c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines             (!HasNoReturn ||
485c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines              D.isIgnored(diag::warn_noreturn_function_has_return_expr,
486c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                          FuncLoc)) &&
487c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines             (!ReturnsVoid ||
488c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines              D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc));
489dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
490d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
491793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    // For blocks / lambdas.
4926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return ReturnsVoid && !HasNoReturn;
493dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
494dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek};
495dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
4963c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman}
4973c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman
498dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
499dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// function that should return a value.  Check that we don't fall off the end
500dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// of a noreturn function.  We assume that functions and blocks not marked
501dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// noreturn will return.
502dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
5033ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek                                    const BlockExpr *blkExpr,
504dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                    const CheckFallThroughDiagnostics& CD,
5051d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek                                    AnalysisDeclContext &AC) {
506dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
507dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool ReturnsVoid = false;
508dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasNoReturn = false;
509dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
510dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
511651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ReturnsVoid = FD->getReturnType()->isVoidType();
512cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith    HasNoReturn = FD->isNoReturn();
513dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
514dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ReturnsVoid = MD->getReturnType()->isVoidType();
516dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    HasNoReturn = MD->hasAttr<NoReturnAttr>();
517dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
518dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  else if (isa<BlockDecl>(D)) {
5193ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek    QualType BlockTy = blkExpr->getType();
520d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek    if (const FunctionType *FT =
521dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          BlockTy->getPointeeType()->getAs<FunctionType>()) {
522651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (FT->getReturnType()->isVoidType())
523dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        ReturnsVoid = true;
524dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (FT->getNoReturnAttr())
525dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasNoReturn = true;
526dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
527dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
528dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
529d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &Diags = S.getDiagnostics();
530dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
531dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Short circuit for compilation speed.
532dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
533dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      return;
534d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
535176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  SourceLocation LBrace = Body->getLocStart(), RBrace = Body->getLocEnd();
536176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Either in a function body compound statement, or a function-try-block.
537176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  switch (CheckFallThrough(AC)) {
538176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    case UnknownFallThrough:
539176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      break;
54016565aa95b086fb239baf82335dccc1b1ec93942John McCall
541176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    case MaybeFallThrough:
542176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      if (HasNoReturn)
543176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        S.Diag(RBrace, CD.diag_MaybeFallThrough_HasNoReturn);
544176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      else if (!ReturnsVoid)
545176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        S.Diag(RBrace, CD.diag_MaybeFallThrough_ReturnsNonVoid);
546176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      break;
547176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    case AlwaysFallThrough:
548176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      if (HasNoReturn)
549176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        S.Diag(RBrace, CD.diag_AlwaysFallThrough_HasNoReturn);
550176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      else if (!ReturnsVoid)
551176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        S.Diag(RBrace, CD.diag_AlwaysFallThrough_ReturnsNonVoid);
552176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      break;
553176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    case NeverFallThroughOrReturn:
554176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
555176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
556176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 0 << FD;
557176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
558176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 1 << MD;
559176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        } else {
560176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn);
561b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth        }
562176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      }
563176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      break;
564176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    case NeverFallThrough:
565176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      break;
566dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
567dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
568dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
569dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
570610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// -Wuninitialized
571610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===//
572610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek
5736f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremeneknamespace {
5749f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// ContainsReference - A visitor class to search for references to
5759f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// a particular declaration (the needle) within any evaluated component of an
5769f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// expression (recursively).
5776f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenekclass ContainsReference : public EvaluatedExprVisitor<ContainsReference> {
5789f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  bool FoundReference;
5799f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  const DeclRefExpr *Needle;
5809f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
5816f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenekpublic:
5829f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  ContainsReference(ASTContext &Context, const DeclRefExpr *Needle)
5839f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    : EvaluatedExprVisitor<ContainsReference>(Context),
5849f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth      FoundReference(false), Needle(Needle) {}
5859f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
5869f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  void VisitExpr(Expr *E) {
5876f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek    // Stop evaluating if we already have a reference.
5889f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    if (FoundReference)
5896f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek      return;
5909f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
5919f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    EvaluatedExprVisitor<ContainsReference>::VisitExpr(E);
5926f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek  }
5939f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
5949f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  void VisitDeclRefExpr(DeclRefExpr *E) {
5959f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    if (E == Needle)
5969f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth      FoundReference = true;
5979f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    else
5989f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth      EvaluatedExprVisitor<ContainsReference>::VisitDeclRefExpr(E);
5996f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek  }
6009f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
6019f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  bool doesContainReference() const { return FoundReference; }
6026f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek};
6036f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek}
6046f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek
6054f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikiestatic bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
606a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian  QualType VariableTy = VD->getType().getCanonicalType();
607a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian  if (VariableTy->isBlockPointerType() &&
608a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian      !VD->hasAttr<BlocksAttr>()) {
609c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization)
610c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines        << VD->getDeclName()
611c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines        << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
612a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian    return true;
613a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian  }
6148adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith
6154f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie  // Don't issue a fixit if there is already an initializer.
6164f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie  if (VD->getInit())
6174f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie    return false;
6187b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu
6197b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu  // Don't suggest a fixit inside macros.
6207b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu  if (VD->getLocEnd().isMacroID())
6217b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu    return false;
6227b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu
6236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  SourceLocation Loc = S.getLocForEndOfToken(VD->getLocEnd());
6248adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith
6258adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith  // Suggest possible initialization (if any).
6268adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith  std::string Init = S.getFixItZeroInitializerForType(VariableTy, Loc);
6278adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith  if (Init.empty())
6288adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith    return false;
6298adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith
6307984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith  S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
6317984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith    << FixItHint::CreateInsertion(Loc, Init);
6327984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith  return true;
6334f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie}
6344f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie
635bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// Create a fixit to remove an if-like statement, on the assumption that its
636bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// condition is CondVal.
637bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smithstatic void CreateIfFixit(Sema &S, const Stmt *If, const Stmt *Then,
638bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                          const Stmt *Else, bool CondVal,
639bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                          FixItHint &Fixit1, FixItHint &Fixit2) {
640bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  if (CondVal) {
641bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    // If condition is always true, remove all but the 'then'.
642bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    Fixit1 = FixItHint::CreateRemoval(
643bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        CharSourceRange::getCharRange(If->getLocStart(),
644bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                                      Then->getLocStart()));
645bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    if (Else) {
646bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      SourceLocation ElseKwLoc = Lexer::getLocForEndOfToken(
647bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith          Then->getLocEnd(), 0, S.getSourceManager(), S.getLangOpts());
648bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Fixit2 = FixItHint::CreateRemoval(
649bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith          SourceRange(ElseKwLoc, Else->getLocEnd()));
650bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    }
651bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  } else {
652bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    // If condition is always false, remove all but the 'else'.
653bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    if (Else)
654bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Fixit1 = FixItHint::CreateRemoval(
655bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith          CharSourceRange::getCharRange(If->getLocStart(),
656bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                                        Else->getLocStart()));
657bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    else
658bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Fixit1 = FixItHint::CreateRemoval(If->getSourceRange());
659bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  }
660bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith}
661bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
662bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// DiagUninitUse -- Helper function to produce a diagnostic for an
663bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// uninitialized use of a variable.
664bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smithstatic void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,
665bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                          bool IsCapturedByBlock) {
666bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  bool Diagnosed = false;
667bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
6688a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  switch (Use.getKind()) {
6698a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  case UninitUse::Always:
6708a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    S.Diag(Use.getUser()->getLocStart(), diag::warn_uninit_var)
6718a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        << VD->getDeclName() << IsCapturedByBlock
6728a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        << Use.getUser()->getSourceRange();
6738a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    return;
6748a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith
6758a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  case UninitUse::AfterDecl:
6768a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  case UninitUse::AfterCall:
6778a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    S.Diag(VD->getLocation(), diag::warn_sometimes_uninit_var)
6788a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      << VD->getDeclName() << IsCapturedByBlock
6798a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      << (Use.getKind() == UninitUse::AfterDecl ? 4 : 5)
6808a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      << const_cast<DeclContext*>(VD->getLexicalDeclContext())
6818a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      << VD->getSourceRange();
6828a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    S.Diag(Use.getUser()->getLocStart(), diag::note_uninit_var_use)
6838a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      << IsCapturedByBlock << Use.getUser()->getSourceRange();
6848a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    return;
6858a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith
6868a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  case UninitUse::Maybe:
6878a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  case UninitUse::Sometimes:
6888a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    // Carry on to report sometimes-uninitialized branches, if possible,
6898a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    // or a 'may be used uninitialized' diagnostic otherwise.
6908a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    break;
6918a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  }
6928a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith
693bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  // Diagnose each branch which leads to a sometimes-uninitialized use.
6942815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith  for (UninitUse::branch_iterator I = Use.branch_begin(), E = Use.branch_end();
6952815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith       I != E; ++I) {
696bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    assert(Use.getKind() == UninitUse::Sometimes);
697bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
698bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    const Expr *User = Use.getUser();
6992815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    const Stmt *Term = I->Terminator;
700bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
701bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    // Information used when building the diagnostic.
7022815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    unsigned DiagKind;
7030bea86307eb8c16339315a1e261fc490eb505c5bDavid Blaikie    StringRef Str;
704bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    SourceRange Range;
705bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
706fc09336a5965040736f9bc63a70416003972364eStefanus Du Toit    // FixIts to suppress the diagnostic by removing the dead condition.
707bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    // For all binary terminators, branch 0 is taken if the condition is true,
708bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    // and branch 1 is taken if the condition is false.
709bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    int RemoveDiagKind = -1;
710bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    const char *FixitStr =
711bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        S.getLangOpts().CPlusPlus ? (I->Output ? "true" : "false")
712bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                                  : (I->Output ? "1" : "0");
713bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    FixItHint Fixit1, Fixit2;
714bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
7158a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    switch (Term ? Term->getStmtClass() : Stmt::DeclStmtClass) {
7162815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    default:
717bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      // Don't know how to report this. Just fall back to 'may be used
7188a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      // uninitialized'. FIXME: Can this happen?
7192815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      continue;
7202815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
7212815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    // "condition is true / condition is false".
722bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    case Stmt::IfStmtClass: {
723bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      const IfStmt *IS = cast<IfStmt>(Term);
7242815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 0;
7252815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "if";
726bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Range = IS->getCond()->getSourceRange();
727bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 0;
728bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      CreateIfFixit(S, IS, IS->getThen(), IS->getElse(),
729bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                    I->Output, Fixit1, Fixit2);
7302815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
731bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    }
732bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    case Stmt::ConditionalOperatorClass: {
733bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      const ConditionalOperator *CO = cast<ConditionalOperator>(Term);
7342815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 0;
7352815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "?:";
736bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Range = CO->getCond()->getSourceRange();
737bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 0;
738bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(),
739bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                    I->Output, Fixit1, Fixit2);
7402815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
741bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    }
7422815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::BinaryOperatorClass: {
7432815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      const BinaryOperator *BO = cast<BinaryOperator>(Term);
7442815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      if (!BO->isLogicalOp())
7452815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith        continue;
7462815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 0;
7472815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = BO->getOpcodeStr();
7482815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = BO->getLHS()->getSourceRange();
749bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 0;
750bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      if ((BO->getOpcode() == BO_LAnd && I->Output) ||
751bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith          (BO->getOpcode() == BO_LOr && !I->Output))
752bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        // true && y -> y, false || y -> y.
753bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        Fixit1 = FixItHint::CreateRemoval(SourceRange(BO->getLocStart(),
754bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                                                      BO->getOperatorLoc()));
755bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      else
756bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        // false && y -> false, true || y -> true.
757bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        Fixit1 = FixItHint::CreateReplacement(BO->getSourceRange(), FixitStr);
7582815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
7592815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    }
7602815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
7612815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    // "loop is entered / loop is exited".
7622815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::WhileStmtClass:
7632815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 1;
7642815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "while";
7652815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = cast<WhileStmt>(Term)->getCond()->getSourceRange();
766bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 1;
767bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
7682815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
7692815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::ForStmtClass:
7702815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 1;
7712815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "for";
7722815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = cast<ForStmt>(Term)->getCond()->getSourceRange();
773bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 1;
774bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      if (I->Output)
775bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        Fixit1 = FixItHint::CreateRemoval(Range);
776bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      else
777bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
7782815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
7798a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    case Stmt::CXXForRangeStmtClass:
7808a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      if (I->Output == 1) {
7818a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        // The use occurs if a range-based for loop's body never executes.
7828a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        // That may be impossible, and there's no syntactic fix for this,
7838a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        // so treat it as a 'may be uninitialized' case.
7848a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        continue;
7858a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      }
7868a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      DiagKind = 1;
7878a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      Str = "for";
7888a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      Range = cast<CXXForRangeStmt>(Term)->getRangeInit()->getSourceRange();
7898a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      break;
7902815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
7912815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    // "condition is true / loop is exited".
7922815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::DoStmtClass:
7932815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 2;
7942815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "do";
7952815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = cast<DoStmt>(Term)->getCond()->getSourceRange();
796bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 1;
797bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
7982815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
7992815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
8002815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    // "switch case is taken".
8012815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::CaseStmtClass:
8022815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 3;
8032815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "case";
8042815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = cast<CaseStmt>(Term)->getLHS()->getSourceRange();
8052815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
8062815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::DefaultStmtClass:
8072815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 3;
8082815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "default";
8092815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = cast<DefaultStmt>(Term)->getDefaultLoc();
8102815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
8112815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    }
8122815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
813bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    S.Diag(Range.getBegin(), diag::warn_sometimes_uninit_var)
814bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      << VD->getDeclName() << IsCapturedByBlock << DiagKind
815bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      << Str << I->Output << Range;
816bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    S.Diag(User->getLocStart(), diag::note_uninit_var_use)
817bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      << IsCapturedByBlock << User->getSourceRange();
818bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    if (RemoveDiagKind != -1)
819bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      S.Diag(Fixit1.RemoveRange.getBegin(), diag::note_uninit_fixit_remove_cond)
820bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2;
821bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
822bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    Diagnosed = true;
8232815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith  }
824bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
825bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  if (!Diagnosed)
8268a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    S.Diag(Use.getUser()->getLocStart(), diag::warn_maybe_uninit_var)
827bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        << VD->getDeclName() << IsCapturedByBlock
828bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        << Use.getUser()->getSourceRange();
8292815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith}
8302815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
831262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an
832262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// uninitialized variable. This manages the different forms of diagnostic
833262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// emitted for particular types of uses. Returns true if the use was diagnosed
8342815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith/// as a warning. If a particular use is one we omit warnings for, returns
835262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// false.
836262d50e1dcf529317da193ad585c11c16281a7acChandler Carruthstatic bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
8372815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith                                     const UninitUse &Use,
8389e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek                                     bool alwaysReportSelfInit = false) {
8394c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
8402815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Use.getUser())) {
841f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // Inspect the initializer of the variable declaration which is
842f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // being referenced prior to its initialization. We emit
843f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // specialized diagnostics for self-initialization, and we
844f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // specifically avoid warning about self references which take the
845f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // form of:
846f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    //
847f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    //   int x = x;
848f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    //
849f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // This is used to indicate to GCC that 'x' is intentionally left
850f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // uninitialized. Proven code paths which access 'x' in
851f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // an uninitialized state after this will still warn.
852f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    if (const Expr *Initializer = VD->getInit()) {
853f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu      if (!alwaysReportSelfInit && DRE == Initializer->IgnoreParenImpCasts())
854f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu        return false;
855f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu
856f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu      ContainsReference CR(S.Context, DRE);
857f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu      CR.Visit(const_cast<Expr*>(Initializer));
858f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu      if (CR.doesContainReference()) {
8594c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth        S.Diag(DRE->getLocStart(),
8604c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth               diag::warn_uninit_self_reference_in_init)
861f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu          << VD->getDeclName() << VD->getLocation() << DRE->getSourceRange();
862f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu        return true;
8634c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      }
8644c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    }
865f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu
866bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    DiagUninitUse(S, VD, Use, false);
8674c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  } else {
8682815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    const BlockExpr *BE = cast<BlockExpr>(Use.getUser());
869bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    if (VD->getType()->isBlockPointerType() && !VD->hasAttr<BlocksAttr>())
870bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      S.Diag(BE->getLocStart(),
871bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith             diag::warn_uninit_byref_blockvar_captured_by_block)
872a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian        << VD->getDeclName();
873bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    else
874bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      DiagUninitUse(S, VD, Use, true);
8754c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  }
8764c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
8774c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  // Report where the variable was declared when the use wasn't within
8784f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie  // the initializer of that declaration & we didn't already suggest
8794f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie  // an initialization fixit.
880f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu  if (!SuggestInitializationFixit(S, VD))
8814c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    S.Diag(VD->getLocStart(), diag::note_uninit_var_def)
8824c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      << VD->getDeclName();
8834c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
884262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth  return true;
88564fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth}
88664fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth
887e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smithnamespace {
888e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> {
889e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  public:
890e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    FallthroughMapper(Sema &S)
891e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      : FoundSwitchStatements(false),
892e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        S(S) {
893e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
894e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
895e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool foundSwitchStatements() const { return FoundSwitchStatements; }
896e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
897e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    void markFallthroughVisited(const AttributedStmt *Stmt) {
898e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      bool Found = FallthroughStmts.erase(Stmt);
899e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      assert(Found);
9003bb2994a7de3679fb825f3a36f3dc11ea1daf6a6Kaelyn Uhrain      (void)Found;
901e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
902e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
903e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts;
904e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
905e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    const AttrStmts &getFallthroughStmts() const {
906e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      return FallthroughStmts;
907e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
908e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
9094874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko    void fillReachableBlocks(CFG *Cfg) {
9104874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      assert(ReachableBlocks.empty() && "ReachableBlocks already filled");
9114874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      std::deque<const CFGBlock *> BlockQueue;
9124874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko
9134874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      ReachableBlocks.insert(&Cfg->getEntry());
9144874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      BlockQueue.push_back(&Cfg->getEntry());
915878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko      // Mark all case blocks reachable to avoid problems with switching on
916878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko      // constants, covered enums, etc.
917878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko      // These blocks can contain fall-through annotations, and we don't want to
918878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko      // issue a warn_fallthrough_attr_unreachable for them.
9196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      for (const auto *B : *Cfg) {
920878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko        const Stmt *L = B->getLabel();
921176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        if (L && isa<SwitchCase>(L) && ReachableBlocks.insert(B).second)
922878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko          BlockQueue.push_back(B);
923878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko      }
924878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko
9254874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      while (!BlockQueue.empty()) {
9264874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko        const CFGBlock *P = BlockQueue.front();
9274874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko        BlockQueue.pop_front();
9284874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko        for (CFGBlock::const_succ_iterator I = P->succ_begin(),
9294874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko                                           E = P->succ_end();
9304874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko             I != E; ++I) {
931176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          if (*I && ReachableBlocks.insert(*I).second)
9324874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko            BlockQueue.push_back(*I);
9334874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko        }
9344874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      }
9354874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko    }
9364874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko
937e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) {
9384874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
9394874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko
940e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      int UnannotatedCnt = 0;
941e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      AnnotatedCnt = 0;
942e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
9436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      std::deque<const CFGBlock*> BlockQueue(B.pred_begin(), B.pred_end());
944e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      while (!BlockQueue.empty()) {
945e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        const CFGBlock *P = BlockQueue.front();
946e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        BlockQueue.pop_front();
947651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (!P) continue;
948e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
949e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        const Stmt *Term = P->getTerminator();
950e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (Term && isa<SwitchStmt>(Term))
951e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          continue; // Switch statement, good.
952e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
953e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel());
954e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end())
955e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          continue; // Previous case label has no statements, good.
956e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
957c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko        const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel());
958c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko        if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end())
959c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko          continue; // Case label is preceded with a normal label, good.
960c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko
9614874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko        if (!ReachableBlocks.count(P)) {
962878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko          for (CFGBlock::const_reverse_iterator ElemIt = P->rbegin(),
963878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko                                                ElemEnd = P->rend();
964878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko               ElemIt != ElemEnd; ++ElemIt) {
965b07805485c603be3d8011f72611465324c9e664bDavid Blaikie            if (Optional<CFGStmt> CS = ElemIt->getAs<CFGStmt>()) {
966b07805485c603be3d8011f72611465324c9e664bDavid Blaikie              if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) {
967e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                S.Diag(AS->getLocStart(),
968e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                       diag::warn_fallthrough_attr_unreachable);
969e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                markFallthroughVisited(AS);
970e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                ++AnnotatedCnt;
971878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko                break;
972e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith              }
973e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith              // Don't care about other unreachable statements.
974e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith            }
975e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          }
976e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // If there are no unreachable statements, this may be a special
977e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // case in CFG:
978e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // case X: {
979e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          //    A a;  // A has a destructor.
980e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          //    break;
981e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // }
982e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // // <<<< This place is represented by a 'hanging' CFG block.
983e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // case Y:
984e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          continue;
985e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        }
986e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
987e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        const Stmt *LastStmt = getLastStmt(*P);
988e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
989e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          markFallthroughVisited(AS);
990e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          ++AnnotatedCnt;
991e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          continue; // Fallthrough annotation, good.
992e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        }
993e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
994e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (!LastStmt) { // This block contains no executable statements.
995e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // Traverse its predecessors.
996e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          std::copy(P->pred_begin(), P->pred_end(),
997e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                    std::back_inserter(BlockQueue));
998e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          continue;
999e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        }
1000e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1001e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        ++UnannotatedCnt;
1002e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      }
1003e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      return !!UnannotatedCnt;
1004e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1005e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1006e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    // RecursiveASTVisitor setup.
1007e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool shouldWalkTypesOfTypeLocs() const { return false; }
1008e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1009e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool VisitAttributedStmt(AttributedStmt *S) {
1010e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      if (asFallThroughAttr(S))
1011e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        FallthroughStmts.insert(S);
1012e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      return true;
1013e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1014e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1015e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool VisitSwitchStmt(SwitchStmt *S) {
1016e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      FoundSwitchStatements = true;
1017e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      return true;
1018e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1019e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1020b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko    // We don't want to traverse local type declarations. We analyze their
1021b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko    // methods separately.
1022b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko    bool TraverseDecl(Decl *D) { return true; }
1023b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko
1024c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    // We analyze lambda bodies separately. Skip them here.
1025c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
1026c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
1027e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  private:
1028e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1029e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
1030e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {
1031e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
1032e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          return AS;
1033e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      }
10346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return nullptr;
1035e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1036e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1037e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    static const Stmt *getLastStmt(const CFGBlock &B) {
1038e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      if (const Stmt *Term = B.getTerminator())
1039e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        return Term;
1040e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      for (CFGBlock::const_reverse_iterator ElemIt = B.rbegin(),
1041e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                                            ElemEnd = B.rend();
1042e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                                            ElemIt != ElemEnd; ++ElemIt) {
1043b07805485c603be3d8011f72611465324c9e664bDavid Blaikie        if (Optional<CFGStmt> CS = ElemIt->getAs<CFGStmt>())
1044b07805485c603be3d8011f72611465324c9e664bDavid Blaikie          return CS->getStmt();
1045e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      }
1046e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      // Workaround to detect a statement thrown out by CFGBuilder:
1047e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      //   case X: {} case Y:
1048e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      //   case X: ; case Y:
1049e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))
1050e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (!isa<SwitchCase>(SW->getSubStmt()))
1051e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          return SW->getSubStmt();
1052e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
10536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return nullptr;
1054e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1055e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1056e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool FoundSwitchStatements;
1057e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    AttrStmts FallthroughStmts;
1058e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    Sema &S;
10594874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko    llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
1060e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  };
1061e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith}
1062e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
10631973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienkostatic void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC,
1064c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt                                            bool PerFunction) {
10653078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // Only perform this analysis when using C++11.  There is no good workflow
10663078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // for this warning when not using C++11.  There is no good way to silence
10673078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // the warning (no attribute is available) unless we are using C++11's support
10683078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // for generalized attributes.  Once could use pragmas to silence the warning,
10693078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // but as a general solution that is gross and not in the spirit of this
10703078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // warning.
10713078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  //
10723078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // NOTE: This an intermediate solution.  There are on-going discussions on
10733078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // how to properly support this warning outside of C++11 with an annotation.
107480ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith  if (!AC.getASTContext().getLangOpts().CPlusPlus11)
10753078353fb56772193b9304510048ac075a2c95b5Ted Kremenek    return;
10763078353fb56772193b9304510048ac075a2c95b5Ted Kremenek
1077e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  FallthroughMapper FM(S);
1078e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  FM.TraverseStmt(AC.getBody());
1079e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1080e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  if (!FM.foundSwitchStatements())
1081e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    return;
1082e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1083c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt  if (PerFunction && FM.getFallthroughStmts().empty())
10841973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko    return;
10851973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko
1086e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  CFG *Cfg = AC.getCFG();
1087e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1088e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  if (!Cfg)
1089e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    return;
1090e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
10914874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko  FM.fillReachableBlocks(Cfg);
1092e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1093e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  for (CFG::reverse_iterator I = Cfg->rbegin(), E = Cfg->rend(); I != E; ++I) {
1094e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko    const CFGBlock *B = *I;
1095e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko    const Stmt *Label = B->getLabel();
1096e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1097e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    if (!Label || !isa<SwitchCase>(Label))
1098e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      continue;
1099e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
11004874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko    int AnnotatedCnt;
11014874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko
1102e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko    if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt))
1103e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      continue;
1104e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
11051973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko    S.Diag(Label->getLocStart(),
1106c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt        PerFunction ? diag::warn_unannotated_fallthrough_per_function
1107c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt                    : diag::warn_unannotated_fallthrough);
1108e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1109e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    if (!AnnotatedCnt) {
1110e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      SourceLocation L = Label->getLocStart();
1111e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      if (L.isMacroID())
1112e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        continue;
111380ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith      if (S.getLangOpts().CPlusPlus11) {
1114e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko        const Stmt *Term = B->getTerminator();
1115e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko        // Skip empty cases.
1116e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko        while (B->empty() && !Term && B->succ_size() == 1) {
1117e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko          B = *B->succ_begin();
1118e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko          Term = B->getTerminator();
1119e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko        }
1120e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko        if (!(B->empty() && Term && isa<BreakStmt>(Term))) {
112166da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko          Preprocessor &PP = S.getPreprocessor();
112266da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko          TokenValue Tokens[] = {
112366da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko            tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"),
112466da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko            tok::coloncolon, PP.getIdentifierInfo("fallthrough"),
112566da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko            tok::r_square, tok::r_square
112666da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko          };
11271952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko          StringRef AnnotationSpelling = "[[clang::fallthrough]]";
11281952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko          StringRef MacroName = PP.getLastMacroWithSpelling(L, Tokens);
11291952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko          if (!MacroName.empty())
11301952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko            AnnotationSpelling = MacroName;
11311952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko          SmallString<64> TextToInsert(AnnotationSpelling);
11321952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko          TextToInsert += "; ";
1133a189d8976f1193b788508a1a29b2e9d0aca06acaAlexander Kornienko          S.Diag(L, diag::note_insert_fallthrough_fixit) <<
113466da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko              AnnotationSpelling <<
11351952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko              FixItHint::CreateInsertion(L, TextToInsert);
1136a189d8976f1193b788508a1a29b2e9d0aca06acaAlexander Kornienko        }
1137e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      }
1138e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      S.Diag(L, diag::note_insert_break_fixit) <<
1139e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        FixItHint::CreateInsertion(L, "break; ");
1140e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1141e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  }
1142e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
11436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  for (const auto *F : FM.getFallthroughStmts())
11446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    S.Diag(F->getLocStart(), diag::warn_fallthrough_attr_invalid_placement);
1145e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith}
1146e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1147c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rosestatic bool isInLoop(const ASTContext &Ctx, const ParentMap &PM,
1148c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose                     const Stmt *S) {
1149b5cd1220dd650a358622241237aa595c5d675506Jordan Rose  assert(S);
1150b5cd1220dd650a358622241237aa595c5d675506Jordan Rose
1151b5cd1220dd650a358622241237aa595c5d675506Jordan Rose  do {
1152b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    switch (S->getStmtClass()) {
1153b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    case Stmt::ForStmtClass:
1154b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    case Stmt::WhileStmtClass:
1155b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    case Stmt::CXXForRangeStmtClass:
1156b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    case Stmt::ObjCForCollectionStmtClass:
1157b5cd1220dd650a358622241237aa595c5d675506Jordan Rose      return true;
1158c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    case Stmt::DoStmtClass: {
1159c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      const Expr *Cond = cast<DoStmt>(S)->getCond();
1160c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      llvm::APSInt Val;
1161c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      if (!Cond->EvaluateAsInt(Val, Ctx))
1162c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        return true;
1163c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      return Val.getBoolValue();
1164c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    }
1165b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    default:
1166b5cd1220dd650a358622241237aa595c5d675506Jordan Rose      break;
1167b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    }
1168b5cd1220dd650a358622241237aa595c5d675506Jordan Rose  } while ((S = PM.getParent(S)));
1169b5cd1220dd650a358622241237aa595c5d675506Jordan Rose
1170b5cd1220dd650a358622241237aa595c5d675506Jordan Rose  return false;
1171b5cd1220dd650a358622241237aa595c5d675506Jordan Rose}
1172b5cd1220dd650a358622241237aa595c5d675506Jordan Rose
117358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
117458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosestatic void diagnoseRepeatedUseOfWeak(Sema &S,
117558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose                                      const sema::FunctionScopeInfo *CurFn,
1176b5cd1220dd650a358622241237aa595c5d675506Jordan Rose                                      const Decl *D,
1177b5cd1220dd650a358622241237aa595c5d675506Jordan Rose                                      const ParentMap &PM) {
117858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy;
117958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap;
118058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector;
1181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef std::pair<const Stmt *, WeakObjectUseMap::const_iterator>
1182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StmtUsesPair;
118358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
1184c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose  ASTContext &Ctx = S.getASTContext();
1185c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose
118658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  const WeakObjectUseMap &WeakMap = CurFn->getWeakObjectUses();
118758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
118858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // Extract all weak objects that are referenced more than once.
118958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  SmallVector<StmtUsesPair, 8> UsesByStmt;
119058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  for (WeakObjectUseMap::const_iterator I = WeakMap.begin(), E = WeakMap.end();
119158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose       I != E; ++I) {
119258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    const WeakUseVector &Uses = I->second;
119358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
119458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    // Find the first read of the weak object.
119558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end();
119658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    for ( ; UI != UE; ++UI) {
119758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      if (UI->isUnsafe())
119858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose        break;
119958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
120058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
120158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    // If there were only writes to this object, don't warn.
120258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    if (UI == UE)
120358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      continue;
120458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
1205b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    // If there was only one read, followed by any number of writes, and the
1206c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    // read is not within a loop, don't warn. Additionally, don't warn in a
1207c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    // loop if the base object is a local variable -- local variables are often
1208c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    // changed in loops.
1209b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    if (UI == Uses.begin()) {
1210b5cd1220dd650a358622241237aa595c5d675506Jordan Rose      WeakUseVector::const_iterator UI2 = UI;
1211b5cd1220dd650a358622241237aa595c5d675506Jordan Rose      for (++UI2; UI2 != UE; ++UI2)
1212b5cd1220dd650a358622241237aa595c5d675506Jordan Rose        if (UI2->isUnsafe())
1213b5cd1220dd650a358622241237aa595c5d675506Jordan Rose          break;
1214b5cd1220dd650a358622241237aa595c5d675506Jordan Rose
1215c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      if (UI2 == UE) {
1216c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        if (!isInLoop(Ctx, PM, UI->getUseExpr()))
1217b5cd1220dd650a358622241237aa595c5d675506Jordan Rose          continue;
1218c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose
1219c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        const WeakObjectProfileTy &Profile = I->first;
1220c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        if (!Profile.isExactProfile())
1221c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose          continue;
1222c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose
1223c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        const NamedDecl *Base = Profile.getBase();
1224c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        if (!Base)
1225c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose          Base = Profile.getProperty();
1226c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        assert(Base && "A profile always has a base or property.");
1227c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose
1228c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        if (const VarDecl *BaseVar = dyn_cast<VarDecl>(Base))
1229c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose          if (BaseVar->hasLocalStorage() && !isa<ParmVarDecl>(Base))
1230c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose            continue;
1231c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      }
1232b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    }
1233b5cd1220dd650a358622241237aa595c5d675506Jordan Rose
123458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    UsesByStmt.push_back(StmtUsesPair(UI->getUseExpr(), I));
123558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  }
123658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
123758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  if (UsesByStmt.empty())
123858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    return;
123958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
124058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // Sort by first use so that we emit the warnings in a deterministic order.
1241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceManager &SM = S.getSourceManager();
124258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  std::sort(UsesByStmt.begin(), UsesByStmt.end(),
1243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            [&SM](const StmtUsesPair &LHS, const StmtUsesPair &RHS) {
1244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return SM.isBeforeInTranslationUnit(LHS.first->getLocStart(),
1245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        RHS.first->getLocStart());
1246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  });
124758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
124858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // Classify the current code body for better warning text.
124958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // This enum should stay in sync with the cases in
125058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.
125158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // FIXME: Should we use a common classification enum and the same set of
125258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // possibilities all throughout Sema?
125358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  enum {
125458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    Function,
125558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    Method,
125658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    Block,
125758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    Lambda
125858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  } FunctionKind;
125958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
126058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  if (isa<sema::BlockScopeInfo>(CurFn))
126158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    FunctionKind = Block;
126258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  else if (isa<sema::LambdaScopeInfo>(CurFn))
126358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    FunctionKind = Lambda;
126458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  else if (isa<ObjCMethodDecl>(D))
126558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    FunctionKind = Method;
126658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  else
126758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    FunctionKind = Function;
126858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
126958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // Iterate through the sorted problems and emit warnings for each.
12706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  for (const auto &P : UsesByStmt) {
12716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const Stmt *FirstRead = P.first;
12726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const WeakObjectProfileTy &Key = P.second->first;
12736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const WeakUseVector &Uses = P.second->second;
127458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
12757a2704800943fbb69207e125d28186278712af36Jordan Rose    // For complicated expressions like 'a.b.c' and 'x.b.c', WeakObjectProfileTy
12767a2704800943fbb69207e125d28186278712af36Jordan Rose    // may not contain enough information to determine that these are different
12777a2704800943fbb69207e125d28186278712af36Jordan Rose    // properties. We can only be 100% sure of a repeated use in certain cases,
12787a2704800943fbb69207e125d28186278712af36Jordan Rose    // and we adjust the diagnostic kind accordingly so that the less certain
12797a2704800943fbb69207e125d28186278712af36Jordan Rose    // case can be turned off if it is too noisy.
128058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    unsigned DiagKind;
128158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    if (Key.isExactProfile())
128258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      DiagKind = diag::warn_arc_repeated_use_of_weak;
128358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    else
128458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      DiagKind = diag::warn_arc_possible_repeated_use_of_weak;
128558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
12867a2704800943fbb69207e125d28186278712af36Jordan Rose    // Classify the weak object being accessed for better warning text.
12877a2704800943fbb69207e125d28186278712af36Jordan Rose    // This enum should stay in sync with the cases in
12887a2704800943fbb69207e125d28186278712af36Jordan Rose    // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.
12897a2704800943fbb69207e125d28186278712af36Jordan Rose    enum {
12907a2704800943fbb69207e125d28186278712af36Jordan Rose      Variable,
12917a2704800943fbb69207e125d28186278712af36Jordan Rose      Property,
12927a2704800943fbb69207e125d28186278712af36Jordan Rose      ImplicitProperty,
12937a2704800943fbb69207e125d28186278712af36Jordan Rose      Ivar
12947a2704800943fbb69207e125d28186278712af36Jordan Rose    } ObjectKind;
12957a2704800943fbb69207e125d28186278712af36Jordan Rose
12967a2704800943fbb69207e125d28186278712af36Jordan Rose    const NamedDecl *D = Key.getProperty();
12977a2704800943fbb69207e125d28186278712af36Jordan Rose    if (isa<VarDecl>(D))
12987a2704800943fbb69207e125d28186278712af36Jordan Rose      ObjectKind = Variable;
12997a2704800943fbb69207e125d28186278712af36Jordan Rose    else if (isa<ObjCPropertyDecl>(D))
13007a2704800943fbb69207e125d28186278712af36Jordan Rose      ObjectKind = Property;
13017a2704800943fbb69207e125d28186278712af36Jordan Rose    else if (isa<ObjCMethodDecl>(D))
13027a2704800943fbb69207e125d28186278712af36Jordan Rose      ObjectKind = ImplicitProperty;
13037a2704800943fbb69207e125d28186278712af36Jordan Rose    else if (isa<ObjCIvarDecl>(D))
13047a2704800943fbb69207e125d28186278712af36Jordan Rose      ObjectKind = Ivar;
13057a2704800943fbb69207e125d28186278712af36Jordan Rose    else
13067a2704800943fbb69207e125d28186278712af36Jordan Rose      llvm_unreachable("Unexpected weak object kind!");
13077a2704800943fbb69207e125d28186278712af36Jordan Rose
130858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    // Show the first time the object was read.
130958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    S.Diag(FirstRead->getLocStart(), DiagKind)
13107348454025693dd20a411c2bcaabd4460cb87559Joerg Sonnenberger      << int(ObjectKind) << D << int(FunctionKind)
131158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      << FirstRead->getSourceRange();
131258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
131358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    // Print all the other accesses as notes.
13146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &Use : Uses) {
13156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (Use.getUseExpr() == FirstRead)
131658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose        continue;
13176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      S.Diag(Use.getUseExpr()->getLocStart(),
131858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose             diag::note_arc_weak_also_accessed_here)
13196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          << Use.getUseExpr()->getSourceRange();
132058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
132158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  }
132258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose}
132358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
132458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosenamespace {
1325610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass UninitValsDiagReporter : public UninitVariablesHandler {
1326610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek  Sema &S;
13275f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  typedef SmallVector<UninitUse, 2> UsesVec;
1328e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer  typedef llvm::PointerIntPair<UsesVec *, 1, bool> MappedType;
13293285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella  // Prefer using MapVector to DenseMap, so that iteration order will be
13303285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella  // the same as insertion order. This is needed to obtain a deterministic
13313285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella  // order of diagnostics when calling flushDiagnostics().
13323285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella  typedef llvm::MapVector<const VarDecl *, MappedType> UsesMap;
133394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  UsesMap *uses;
133494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
1335610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic:
13366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  UninitValsDiagReporter(Sema &S) : S(S), uses(nullptr) {}
133733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  ~UninitValsDiagReporter() override { flushDiagnostics(); }
13389e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
13393285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella  MappedType &getUses(const VarDecl *vd) {
134094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    if (!uses)
134194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      uses = new UsesMap();
13429e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
13433285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella    MappedType &V = (*uses)[vd];
1344e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer    if (!V.getPointer())
1345e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer      V.setPointer(new UsesVec());
134694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
13479e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek    return V;
13489e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek  }
1349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleUseOfUninitVariable(const VarDecl *vd,
1351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 const UninitUse &use) override {
1352e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer    getUses(vd).getPointer()->push_back(use);
13539e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek  }
13549e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
1355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleSelfInit(const VarDecl *vd) override {
1356e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer    getUses(vd).setInt(true);
135794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  }
135894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
135994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  void flushDiagnostics() {
136094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    if (!uses)
136194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      return;
13623285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella
13636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &P : *uses) {
13646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      const VarDecl *vd = P.first;
13656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      const MappedType &V = P.second;
13669e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
1367e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer      UsesVec *vec = V.getPointer();
1368e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer      bool hasSelfInit = V.getInt();
13699e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
13709e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek      // Specially handle the case where we have uses of an uninitialized
13719e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek      // variable, but the root cause is an idiomatic self-init.  We want
13729e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek      // to report the diagnostic at the self-init since that is the root cause.
13730d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay      if (!vec->empty() && hasSelfInit && hasAlwaysUninitializedUse(vec))
13742815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith        DiagnoseUninitializedUse(S, vd,
13752815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith                                 UninitUse(vd->getInit()->IgnoreParenCasts(),
13762815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith                                           /* isAlwaysUninit */ true),
13770d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay                                 /* alwaysReportSelfInit */ true);
13789e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek      else {
13799e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek        // Sort the uses by their SourceLocations.  While not strictly
13809e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek        // guaranteed to produce them in line/column order, this will provide
13819e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek        // a stable ordering.
1382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        std::sort(vec->begin(), vec->end(),
1383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                  [](const UninitUse &a, const UninitUse &b) {
1384651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          // Prefer a more confident report over a less confident one.
1385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (a.getKind() != b.getKind())
1386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            return a.getKind() > b.getKind();
1387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          return a.getUser()->getLocStart() < b.getUser()->getLocStart();
1388651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        });
1389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
13906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        for (const auto &U : *vec) {
13912815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith          // If we have self-init, downgrade all uses to 'may be uninitialized'.
13926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          UninitUse Use = hasSelfInit ? UninitUse(U.getUser(), false) : U;
13932815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
13942815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith          if (DiagnoseUninitializedUse(S, vd, Use))
13959e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek            // Skip further diagnostics for this variable. We try to warn only
13969e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek            // on the first point at which a variable is used uninitialized.
13979e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek            break;
13989e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek        }
139964fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth      }
14009e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
14019e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek      // Release the uses vector.
140294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      delete vec;
140394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    }
140494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    delete uses;
1405610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek  }
14060d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay
14070d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gayprivate:
14080d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay  static bool hasAlwaysUninitializedUse(const UsesVec* vec) {
14096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return std::any_of(vec->begin(), vec->end(), [](const UninitUse &U) {
14106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return U.getKind() == UninitUse::Always ||
14116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines             U.getKind() == UninitUse::AfterCall ||
14126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines             U.getKind() == UninitUse::AfterDecl;
14136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    });
14140d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay  }
1415610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek};
1416610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}
1417610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek
141875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskinamespace clang {
1419df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace {
1420cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkotypedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes;
14212e5156274b8051217565b557bfa14c80f7990e9cRichard Smithtypedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;
1422ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramertypedef std::list<DelayedDiag> DiagList;
142375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
142475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskistruct SortDiagBySourceLocation {
1425ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer  SourceManager &SM;
1426ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer  SortDiagBySourceLocation(SourceManager &SM) : SM(SM) {}
142775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
142875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  bool operator()(const DelayedDiag &left, const DelayedDiag &right) {
142975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski    // Although this call will be slow, this is only called when outputting
143075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski    // multiple warnings.
1431ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer    return SM.isBeforeInTranslationUnit(left.first.first, right.first.first);
143275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
143375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski};
1434df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins}}
143575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1436df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===//
1437df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// -Wthread-safety
1438df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===//
1439df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace clang {
1440176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace threadSafety {
14413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarnamespace {
1442176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
144375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  Sema &S;
144475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  DiagList Warnings;
14452e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  SourceLocation FunLocation, FunEndLocation;
144675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1447176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const FunctionDecl *CurrentFunction;
1448176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  bool Verbose;
1449176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1450176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  OptionalNotes getNotes() const {
1451176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (Verbose && CurrentFunction) {
1452176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(),
1453176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                S.PDiag(diag::note_thread_warning_in_fun)
1454176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                    << CurrentFunction->getNameAsString());
1455176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      return OptionalNotes(1, FNote);
1456176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
1457176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return OptionalNotes();
1458176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1459176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1460176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  OptionalNotes getNotes(const PartialDiagnosticAt &Note) const {
1461176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    OptionalNotes ONS(1, Note);
1462176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (Verbose && CurrentFunction) {
1463176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(),
1464176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                S.PDiag(diag::note_thread_warning_in_fun)
1465176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                    << CurrentFunction->getNameAsString());
1466176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      ONS.push_back(FNote);
1467176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
1468176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return ONS;
1469176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1470176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1471176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  OptionalNotes getNotes(const PartialDiagnosticAt &Note1,
1472176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                         const PartialDiagnosticAt &Note2) const {
1473176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    OptionalNotes ONS;
1474176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    ONS.push_back(Note1);
1475176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    ONS.push_back(Note2);
1476176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (Verbose && CurrentFunction) {
1477176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(),
1478176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                S.PDiag(diag::note_thread_warning_in_fun)
1479176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                    << CurrentFunction->getNameAsString());
1480176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      ONS.push_back(FNote);
1481176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
1482176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return ONS;
1483176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1484176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
148575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  // Helper functions
1486651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void warnLockMismatch(unsigned DiagID, StringRef Kind, Name LockName,
1487651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        SourceLocation Loc) {
1488f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // Gracefully handle rare cases when the analysis can't get a more
1489f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // precise source location.
1490f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    if (!Loc.isValid())
1491f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins      Loc = FunLocation;
1492651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName);
1493176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Warnings.push_back(DelayedDiag(Warning, getNotes()));
149475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
149575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
149675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski public:
14972e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL)
1498176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    : S(S), FunLocation(FL), FunEndLocation(FEL),
1499176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CurrentFunction(nullptr), Verbose(false) {}
1500176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1501176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void setVerbose(bool b) { Verbose = b; }
150275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
150375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  /// \brief Emit all buffered diagnostics in order of sourcelocation.
150475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  /// We need to output diagnostics produced while iterating through
150575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  /// the lockset in deterministic order, so this function orders diagnostics
150675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  /// and outputs them.
150775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  void emitDiagnostics() {
1508ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer    Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));
15096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &Diag : Warnings) {
15106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      S.Diag(Diag.first.first, Diag.first.second);
15116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      for (const auto &Note : Diag.second)
15126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        S.Diag(Note.first, Note.second);
15132e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    }
151475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
151575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1516651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) override {
1517651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_cannot_resolve_lock)
1518651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                         << Loc);
1519176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Warnings.push_back(DelayedDiag(Warning, getNotes()));
152099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  }
1521176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1522651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleUnmatchedUnlock(StringRef Kind, Name LockName,
1523651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             SourceLocation Loc) override {
1524651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    warnLockMismatch(diag::warn_unlock_but_no_lock, Kind, LockName, Loc);
152575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
1526176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
1528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 LockKind Expected, LockKind Received,
1529651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 SourceLocation Loc) override {
1530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (Loc.isInvalid())
1531651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Loc = FunLocation;
1532651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_kind_mismatch)
1533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                         << Kind << LockName << Received
1534651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                         << Expected);
1535176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Warnings.push_back(DelayedDiag(Warning, getNotes()));
1536651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1537176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override {
1539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    warnLockMismatch(diag::warn_double_lock, Kind, LockName, Loc);
154075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
154175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
1543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 SourceLocation LocLocked,
15442e5156274b8051217565b557bfa14c80f7990e9cRichard Smith                                 SourceLocation LocEndOfScope,
1545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 LockErrorKind LEK) override {
15464e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    unsigned DiagID = 0;
15474e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    switch (LEK) {
15484e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      case LEK_LockedSomePredecessors:
15492e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        DiagID = diag::warn_lock_some_predecessors;
15504e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski        break;
15514e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      case LEK_LockedSomeLoopIterations:
15524e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski        DiagID = diag::warn_expecting_lock_held_on_loop;
15534e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski        break;
15544e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      case LEK_LockedAtEndOfFunction:
15554e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski        DiagID = diag::warn_no_unlock;
15564e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski        break;
1557879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins      case LEK_NotLockedAtEndOfFunction:
1558879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins        DiagID = diag::warn_expecting_locked;
1559879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins        break;
15604e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    }
15612e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    if (LocEndOfScope.isInvalid())
15622e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      LocEndOfScope = FunEndLocation;
15632e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
1564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << Kind
1565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                               << LockName);
15665696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    if (LocLocked.isValid()) {
1567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here)
1568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                              << Kind);
1569176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));
15705696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins      return;
15715696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    }
1572176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Warnings.push_back(DelayedDiag(Warning, getNotes()));
157375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
157475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleExclusiveAndShared(StringRef Kind, Name LockName,
1576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                SourceLocation Loc1,
1577651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                SourceLocation Loc2) override {
1578651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(Loc1,
1579651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                S.PDiag(diag::warn_lock_exclusive_and_shared)
1580651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    << Kind << LockName);
1581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Note(Loc2, S.PDiag(diag::note_lock_exclusive_and_shared)
1582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                       << Kind << LockName);
1583176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));
158475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
158575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
1587651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         ProtectedOperationKind POK, AccessKind AK,
1588651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         SourceLocation Loc) override {
1589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert((POK == POK_VarAccess || POK == POK_VarDereference) &&
1590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           "Only works for variables");
1591df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski    unsigned DiagID = POK == POK_VarAccess?
1592df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski                        diag::warn_variable_requires_any_lock:
1593df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski                        diag::warn_var_deref_requires_any_lock;
15942e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
15955b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins      << D->getNameAsString() << getLockKindFromAccessKind(AK));
1596176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Warnings.push_back(DelayedDiag(Warning, getNotes()));
159775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
159875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1599651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
1600651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          ProtectedOperationKind POK, Name LockName,
1601651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          LockKind LK, SourceLocation Loc,
1602651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          Name *PossibleMatch) override {
1603e87158dfbca01577810f301543c3cdcfc955d8b0Caitlin Sadowski    unsigned DiagID = 0;
16043f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    if (PossibleMatch) {
16053f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      switch (POK) {
16063f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_VarAccess:
16073f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_variable_requires_lock_precise;
16083f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
16093f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_VarDereference:
16103f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_var_deref_requires_lock_precise;
16113f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
16123f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_FunctionCall:
16133f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_fun_requires_lock_precise;
16143f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
1615176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        case POK_PassByRef:
1616176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          DiagID = diag::warn_guarded_pass_by_reference;
1617176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          break;
1618176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        case POK_PtPassByRef:
1619176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          DiagID = diag::warn_pt_guarded_pass_by_reference;
1620176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          break;
16213f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      }
1622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
1623651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                       << D->getNameAsString()
1624651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                       << LockName << LK);
16253f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match)
1626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        << *PossibleMatch);
1627176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      if (Verbose && POK == POK_VarAccess) {
1628176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        PartialDiagnosticAt VNote(D->getLocation(),
1629176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                 S.PDiag(diag::note_guarded_by_declared_here)
1630176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                     << D->getNameAsString());
1631176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        Warnings.push_back(DelayedDiag(Warning, getNotes(Note, VNote)));
1632176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      } else
1633176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));
16343f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    } else {
16353f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      switch (POK) {
16363f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_VarAccess:
16373f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_variable_requires_lock;
16383f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
16393f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_VarDereference:
16403f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_var_deref_requires_lock;
16413f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
16423f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_FunctionCall:
16433f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_fun_requires_lock;
16443f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
1645176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        case POK_PassByRef:
1646176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          DiagID = diag::warn_guarded_pass_by_reference;
1647176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          break;
1648176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        case POK_PtPassByRef:
1649176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          DiagID = diag::warn_pt_guarded_pass_by_reference;
1650176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          break;
16513f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      }
1652651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
1653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                       << D->getNameAsString()
1654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                       << LockName << LK);
1655176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      if (Verbose && POK == POK_VarAccess) {
1656176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        PartialDiagnosticAt Note(D->getLocation(),
1657176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                 S.PDiag(diag::note_guarded_by_declared_here)
1658176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                     << D->getNameAsString());
1659176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));
1660176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      } else
1661176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        Warnings.push_back(DelayedDiag(Warning, getNotes()));
166275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski    }
166375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
166475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
166533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,
166633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar                             SourceLocation Loc) override {
1667176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    PartialDiagnosticAt Warning(Loc,
1668176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        S.PDiag(diag::warn_acquire_requires_negative_cap)
1669176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        << Kind << LockName << Neg);
1670176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Warnings.push_back(DelayedDiag(Warning, getNotes()));
1671176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1672176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1673176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1674651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleFunExcludesLock(StringRef Kind, Name FunName, Name LockName,
1675651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             SourceLocation Loc) override {
1676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_fun_excludes_mutex)
1677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                         << Kind << FunName << LockName);
1678176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Warnings.push_back(DelayedDiag(Warning, getNotes()));
1679176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1680176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
168133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  void handleLockAcquiredBefore(StringRef Kind, Name L1Name, Name L2Name,
168233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar                                SourceLocation Loc) override {
16830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    PartialDiagnosticAt Warning(Loc,
16840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      S.PDiag(diag::warn_acquired_before) << Kind << L1Name << L2Name);
16850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    Warnings.push_back(DelayedDiag(Warning, getNotes()));
16860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
16870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
168833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) override {
16890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    PartialDiagnosticAt Warning(Loc,
16900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      S.PDiag(diag::warn_acquired_before_after_cycle) << L1Name);
16910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    Warnings.push_back(DelayedDiag(Warning, getNotes()));
16920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
16930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
1694176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void enterFunction(const FunctionDecl* FD) override {
1695176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    CurrentFunction = FD;
1696176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
1697176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1698176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void leaveFunction(const FunctionDecl* FD) override {
1699176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    CurrentFunction = 0;
170075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
170175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski};
17023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} // namespace
17033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} // namespace threadSafety
17043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} // namespace clang
170575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1706610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===//
1707df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// -Wconsumed
1708df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===//
1709df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1710df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace clang {
1711df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace consumed {
1712df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace {
1713df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsclass ConsumedWarningsHandler : public ConsumedWarningsHandlerBase {
1714df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1715df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  Sema &S;
1716df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  DiagList Warnings;
1717df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1718df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinspublic:
17190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
1720df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  ConsumedWarningsHandler(Sema &S) : S(S) {}
1721651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1722651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void emitDiagnostics() override {
1723df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));
17246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &Diag : Warnings) {
17256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      S.Diag(Diag.first.first, Diag.first.second);
17266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      for (const auto &Note : Diag.second)
17276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        S.Diag(Note.first, Note.second);
1728df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    }
1729df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  }
1730651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1731651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void warnLoopStateMismatch(SourceLocation Loc,
1732651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             StringRef VariableName) override {
17337385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch) <<
17347385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins      VariableName);
17357385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins
17367385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
17377385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins  }
17387385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins
1739cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins  void warnParamReturnTypestateMismatch(SourceLocation Loc,
1740cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins                                        StringRef VariableName,
1741cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins                                        StringRef ExpectedState,
1742651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        StringRef ObservedState) override {
1743cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins
1744cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(
1745cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins      diag::warn_param_return_typestate_mismatch) << VariableName <<
1746cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins        ExpectedState << ObservedState);
1747cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins
1748cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1749cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins  }
1750cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins
1751d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins  void warnParamTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
1752651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                  StringRef ObservedState) override {
1753d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins
1754d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(
1755d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins      diag::warn_param_typestate_mismatch) << ExpectedState << ObservedState);
1756d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins
1757d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1758d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins  }
1759d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins
17600e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins  void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
1761651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                              StringRef TypeName) override {
17620e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(
17630e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins      diag::warn_return_typestate_for_unconsumable_type) << TypeName);
17640e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins
17650e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
17660e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins  }
17670e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins
17680e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins  void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
1769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   StringRef ObservedState) override {
17700e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins
17710e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(
17720e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins      diag::warn_return_typestate_mismatch) << ExpectedState << ObservedState);
17730e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins
17740e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
17750e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins  }
17760e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins
177766540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins  void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State,
1778651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   SourceLocation Loc) override {
1779df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1780df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(
178166540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins      diag::warn_use_of_temp_in_invalid_state) << MethodName << State);
1782df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1783df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1784df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  }
1785df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
178666540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins  void warnUseInInvalidState(StringRef MethodName, StringRef VariableName,
1787651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             StringRef State, SourceLocation Loc) override {
1788df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
178966540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state) <<
179066540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins                                MethodName << VariableName << State);
1791df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1792df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1793df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  }
1794df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins};
1795df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins}}}
1796df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1797df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===//
1798dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based
1799dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//  warnings on a function, method, or block.
1800dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
1801dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
1802d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekclang::sema::AnalysisBasedWarnings::Policy::Policy() {
1803dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  enableCheckFallThrough = 1;
1804d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  enableCheckUnreachable = 0;
18053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  enableThreadSafetyAnalysis = 0;
1806df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  enableConsumedAnalysis = 0;
1807d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek}
1808dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
1809651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic unsigned isEnabled(DiagnosticsEngine &D, unsigned diag) {
1810c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  return (unsigned)!D.isIgnored(diag, SourceLocation());
1811651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
1812651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
18135d98994c7749312a43ce6adf45537979a98e7afdChandler Carruthclang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
18145d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  : S(s),
18155d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    NumFunctionsAnalyzed(0),
181654cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumFunctionsWithBadCFGs(0),
18175d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    NumCFGBlocks(0),
181854cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    MaxCFGBlocksPerFunction(0),
181954cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumUninitAnalysisFunctions(0),
182054cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumUninitAnalysisVariables(0),
182154cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    MaxUninitAnalysisVariablesPerFunction(0),
182254cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumUninitAnalysisBlockVisits(0),
182354cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    MaxUninitAnalysisBlockVisitsPerFunction(0) {
1824651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1825651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  using namespace diag;
1826d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &D = S.getDiagnostics();
1827651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1828651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  DefaultPolicy.enableCheckUnreachable =
1829651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_unreachable) ||
1830651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_unreachable_break) ||
1831651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_unreachable_return) ||
1832651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_unreachable_loop_increment);
1833651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1834651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  DefaultPolicy.enableThreadSafetyAnalysis =
1835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_double_lock);
1836651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1837651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  DefaultPolicy.enableConsumedAnalysis =
1838651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_use_in_invalid_state);
1839dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
1840dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
18416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstatic void flushDiagnostics(Sema &S, const sema::FunctionScopeInfo *fscope) {
18426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  for (const auto &D : fscope->PossiblyUnreachableDiags)
1843351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    S.Diag(D.Loc, D.PD);
1844351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek}
1845351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
1846d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekvoid clang::sema::
1847d064fdc4b7b64ca55b40b70490c79d6f569df78eTed KremenekAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
1848283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek                                     sema::FunctionScopeInfo *fscope,
18493ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek                                     const Decl *D, const BlockExpr *blkExpr) {
1850d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek
1851dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // We avoid doing analysis-based warnings when there are errors for
1852dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // two reasons:
1853dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // (1) The CFGs often can't be constructed (if the body is invalid), so
1854dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  //     don't bother trying.
1855dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // (2) The code already has problems; running the analysis just takes more
1856dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  //     time.
1857d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &Diags = S.getDiagnostics();
185899e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek
1859d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  // Do not do any analysis for declarations in system headers if we are
1860d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  // going to just ignore them.
186199e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek  if (Diags.getSuppressSystemWarnings() &&
1862d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek      S.SourceMgr.isInSystemHeader(D->getLocation()))
1863d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek    return;
1864d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
1865e0054f61fd84133eb0d19c19ae9afaf117933274John McCall  // For code in dependent contexts, we'll do this at instantiation time.
186623661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie  if (cast<DeclContext>(D)->isDependentContext())
186723661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie    return;
1868dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
186912f37e411462b8388eb1309357bd62257debacacDeLesley Hutchins  if (Diags.hasUncompilableErrorOccurred() || Diags.hasFatalErrorOccurred()) {
1870351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    // Flush out any possibly unreachable diagnostics.
1871351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    flushDiagnostics(S, fscope);
1872351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    return;
1873351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  }
1874351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
1875dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  const Stmt *Body = D->getBody();
1876dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  assert(Body);
1877dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
18780cd72319e74899c4e5561cc70b7c4939d3767bd9Ted Kremenek  // Construct the analysis context with the specified CFG build options.
18796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  AnalysisDeclContext AC(/* AnalysisDeclContextManager */ nullptr, D);
1880bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek
1881dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
1882e575359c34a9248c55ec0c03a8fc945f1ee4cb01Benjamin Kramer  // explosion for destructors that can result and the compile time hit.
1883bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true;
1884bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  AC.getCFGBuildOptions().AddEHEdges = false;
1885bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  AC.getCFGBuildOptions().AddInitializers = true;
1886bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  AC.getCFGBuildOptions().AddImplicitDtors = true;
1887faadf48443f8c2fc53d267485d7e0e1bd382fc75Jordan Rose  AC.getCFGBuildOptions().AddTemporaryDtors = true;
1888651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  AC.getCFGBuildOptions().AddCXXNewAllocator = false;
1889faadf48443f8c2fc53d267485d7e0e1bd382fc75Jordan Rose
18900c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // Force that certain expressions appear as CFGElements in the CFG.  This
18910c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // is used to speed up various analyses.
18920c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // FIXME: This isn't the right factoring.  This is here for initial
18930c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // prototyping, but we need a way for analyses to say what expressions they
18940c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // expect to always be CFGElements and then fill in the BuildOptions
18950c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // appropriately.  This is essentially a layering violation.
1896df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis ||
1897df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins      P.enableConsumedAnalysis) {
18981fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    // Unreachable code analysis and thread safety require a linearized CFG.
18990f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek    AC.getCFGBuildOptions().setAllAlwaysAdd();
19000f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek  }
19010f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek  else {
19020f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek    AC.getCFGBuildOptions()
19030f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek      .setAlwaysAdd(Stmt::BinaryOperatorClass)
19046cfa78f6bd4e7d5e23366a0907f8f8792366bc4cRichard Smith      .setAlwaysAdd(Stmt::CompoundAssignOperatorClass)
19050f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek      .setAlwaysAdd(Stmt::BlockExprClass)
19060f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek      .setAlwaysAdd(Stmt::CStyleCastExprClass)
19070f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek      .setAlwaysAdd(Stmt::DeclRefExprClass)
19080f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek      .setAlwaysAdd(Stmt::ImplicitCastExprClass)
1909e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      .setAlwaysAdd(Stmt::UnaryOperatorClass)
1910e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      .setAlwaysAdd(Stmt::AttributedStmtClass);
19110f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek  }
1912bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek
19136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // Install the logical handler for -Wtautological-overlap-compare
19146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  std::unique_ptr<LogicalErrorHandler> LEH;
1915c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
1916c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                       D->getLocStart())) {
19176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    LEH.reset(new LogicalErrorHandler(S));
19186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AC.getCFGBuildOptions().Observer = LEH.get();
19196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
19200cd72319e74899c4e5561cc70b7c4939d3767bd9Ted Kremenek
1921351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  // Emit delayed diagnostics.
192223661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie  if (!fscope->PossiblyUnreachableDiags.empty()) {
1923351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    bool analyzed = false;
19240d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
19250d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    // Register the expressions with the CFGBuilder.
19266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &D : fscope->PossiblyUnreachableDiags) {
19276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (D.stmt)
19286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        AC.registerForcedBlockExpression(D.stmt);
19290d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    }
19300d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
19310d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    if (AC.getCFG()) {
19320d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek      analyzed = true;
19336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      for (const auto &D : fscope->PossiblyUnreachableDiags) {
19340d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        bool processed = false;
19356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        if (D.stmt) {
19366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          const CFGBlock *block = AC.getBlockForRegisteredExpression(D.stmt);
193771b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman          CFGReverseBlockReachabilityAnalysis *cra =
193871b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman              AC.getCFGReachablityAnalysis();
193971b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman          // FIXME: We should be able to assert that block is non-null, but
194071b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman          // the CFG analysis can skip potentially-evaluated expressions in
194171b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman          // edge cases; see test/Sema/vla-2.c.
194271b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman          if (block && cra) {
1943351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek            // Can this block be reached from the entrance?
19440d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek            if (cra->isReachable(&AC.getCFG()->getEntry(), block))
1945351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek              S.Diag(D.Loc, D.PD);
19460d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek            processed = true;
1947351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek          }
19480d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        }
19490d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        if (!processed) {
19500d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek          // Emit the warning anyway if we cannot map to a basic block.
19510d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek          S.Diag(D.Loc, D.PD);
1952351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek        }
1953351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek      }
19540d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    }
1955351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
1956351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    if (!analyzed)
1957351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek      flushDiagnostics(S, fscope);
1958351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  }
1959351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
1960351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
1961dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Warning: check missing 'return'
196223661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie  if (P.enableCheckFallThrough) {
1963dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    const CheckFallThroughDiagnostics &CD =
1964dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
1965793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor       : (isa<CXXMethodDecl>(D) &&
1966793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor          cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call &&
1967793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor          cast<CXXMethodDecl>(D)->getParent()->isLambda())
1968793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor            ? CheckFallThroughDiagnostics::MakeForLambda()
1969793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor            : CheckFallThroughDiagnostics::MakeForFunction(D));
19703ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek    CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC);
1971dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
1972dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
1973dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Warning: check for unreachable code
19745dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek  if (P.enableCheckUnreachable) {
19755dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek    // Only check for unreachable code on non-template instantiations.
19765dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek    // Different template instantiations can effectively change the control-flow
19775dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek    // and it is very difficult to prove that a snippet of code in a template
19785dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek    // is unreachable for all instantiations.
197975df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek    bool isTemplateInstantiation = false;
198075df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
198175df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek      isTemplateInstantiation = Function->isTemplateInstantiation();
198275df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek    if (!isTemplateInstantiation)
19835dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek      CheckUnreachable(S, AC);
19845dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek  }
198575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
19863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // Check for thread safety violations
198723661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie  if (P.enableThreadSafetyAnalysis) {
1988f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    SourceLocation FL = AC.getDecl()->getLocation();
19892e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    SourceLocation FEL = AC.getDecl()->getLocEnd();
1990176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    threadSafety::ThreadSafetyReporter Reporter(S, FL, FEL);
1991c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    if (!Diags.isIgnored(diag::warn_thread_safety_beta, D->getLocStart()))
1992fb4afc2fc659faff43a6df4c1d0e07df9c90479dDeLesley Hutchins      Reporter.setIssueBetaWarnings(true);
1993176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (!Diags.isIgnored(diag::warn_thread_safety_verbose, D->getLocStart()))
1994176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Reporter.setVerbose(true);
1995fb4afc2fc659faff43a6df4c1d0e07df9c90479dDeLesley Hutchins
19960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    threadSafety::runThreadSafetyAnalysis(AC, Reporter,
19970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                          &S.ThreadSafetyDeclCache);
199875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski    Reporter.emitDiagnostics();
199975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
20003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2001df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  // Check for violations of consumed properties.
2002df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  if (P.enableConsumedAnalysis) {
2003df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    consumed::ConsumedWarningsHandler WarningHandler(S);
20042d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner    consumed::ConsumedAnalyzer Analyzer(WarningHandler);
2005df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    Analyzer.run(AC);
2006df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  }
2007df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
2008c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  if (!Diags.isIgnored(diag::warn_uninit_var, D->getLocStart()) ||
2009c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      !Diags.isIgnored(diag::warn_sometimes_uninit_var, D->getLocStart()) ||
2010c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      !Diags.isIgnored(diag::warn_maybe_uninit_var, D->getLocStart())) {
2011c5e43c19ddb40b8a1371291f73ae66fe54951ca5Ted Kremenek    if (CFG *cfg = AC.getCFG()) {
2012c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek      UninitValsDiagReporter reporter(S);
201357080fbac1ccce702255423335d52e81bcf17b6bFariborz Jahanian      UninitVariablesAnalysisStats stats;
201412efd57ee474c06880a7434ece21a39ac3f34e24Benjamin Kramer      std::memset(&stats, 0, sizeof(UninitVariablesAnalysisStats));
2015a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek      runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC,
20165d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth                                        reporter, stats);
20175d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
20185d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      if (S.CollectStats && stats.NumVariablesAnalyzed > 0) {
20195d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        ++NumUninitAnalysisFunctions;
20205d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        NumUninitAnalysisVariables += stats.NumVariablesAnalyzed;
20215d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        NumUninitAnalysisBlockVisits += stats.NumBlockVisits;
20225d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        MaxUninitAnalysisVariablesPerFunction =
20235d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth            std::max(MaxUninitAnalysisVariablesPerFunction,
20245d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth                     stats.NumVariablesAnalyzed);
20255d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        MaxUninitAnalysisBlockVisitsPerFunction =
20265d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth            std::max(MaxUninitAnalysisBlockVisitsPerFunction,
20275d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth                     stats.NumBlockVisits);
20285d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      }
20295d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    }
20305d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  }
20315d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
20321973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko  bool FallThroughDiagFull =
2033c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      !Diags.isIgnored(diag::warn_unannotated_fallthrough, D->getLocStart());
2034c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  bool FallThroughDiagPerFunction = !Diags.isIgnored(
2035c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      diag::warn_unannotated_fallthrough_per_function, D->getLocStart());
2036c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt  if (FallThroughDiagFull || FallThroughDiagPerFunction) {
20371973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko    DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull);
2038e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  }
2039e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
204058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  if (S.getLangOpts().ObjCARCWeak &&
2041c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, D->getLocStart()))
2042b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap());
204358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
2044651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2045651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Check for infinite self-recursion in functions
2046c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  if (!Diags.isIgnored(diag::warn_infinite_recursive_function,
2047c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                       D->getLocStart())) {
2048651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
2049651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      checkRecursiveFunction(S, FD, Body, AC);
2050651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
2051651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
2052651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
20536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // If none of the previous checks caused a CFG build, trigger one here
20546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // for -Wtautological-overlap-compare
2055c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
20566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                               D->getLocStart())) {
20576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AC.getCFG();
20586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
20596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
20605d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  // Collect statistics about the CFG if it was built.
20615d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  if (S.CollectStats && AC.isCFGBuilt()) {
20625d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    ++NumFunctionsAnalyzed;
20635d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    if (CFG *cfg = AC.getCFG()) {
20645d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      // If we successfully built a CFG for this context, record some more
20655d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      // detail information about it.
20663ea4c49709c5bba5f8b16c6ceb725d9b9a1c48c6Chandler Carruth      NumCFGBlocks += cfg->getNumBlockIDs();
20675d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction,
20683ea4c49709c5bba5f8b16c6ceb725d9b9a1c48c6Chandler Carruth                                         cfg->getNumBlockIDs());
20695d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    } else {
20705d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      ++NumFunctionsWithBadCFGs;
2071610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek    }
2072610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek  }
2073dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
20745d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
20755d98994c7749312a43ce6adf45537979a98e7afdChandler Carruthvoid clang::sema::AnalysisBasedWarnings::PrintStats() const {
20765d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  llvm::errs() << "\n*** Analysis Based Warnings Stats:\n";
20775d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
20785d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs;
20795d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned AvgCFGBlocksPerFunction =
20805d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt;
20815d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  llvm::errs() << NumFunctionsAnalyzed << " functions analyzed ("
20825d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << NumFunctionsWithBadCFGs << " w/o CFGs).\n"
20835d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << NumCFGBlocks << " CFG blocks built.\n"
20845d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << AvgCFGBlocksPerFunction
20855d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " average CFG blocks per function.\n"
20865d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << MaxCFGBlocksPerFunction
20875d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " max CFG blocks per function.\n";
20885d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
20895d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0
20905d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      : NumUninitAnalysisVariables/NumUninitAnalysisFunctions;
20915d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0
20925d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions;
20935d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  llvm::errs() << NumUninitAnalysisFunctions
20945d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " functions analyzed for uninitialiazed variables\n"
20955d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << NumUninitAnalysisVariables << " variables analyzed.\n"
20965d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << AvgUninitVariablesPerFunction
20975d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " average variables per function.\n"
20985d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << MaxUninitAnalysisVariablesPerFunction
20995d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " max variables per function.\n"
21005d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << NumUninitAnalysisBlockVisits << " block visits.\n"
21015d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << AvgUninitBlockVisitsPerFunction
21025d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " average block visits per function.\n"
21035d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << MaxUninitAnalysisBlockVisitsPerFunction
21045d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " max block visits per function.\n";
21055d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth}
2106