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
1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \brief Warn on logical operator errors in CFGBuilder
1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass LogicalErrorHandler : public CFGCallback {
1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Sema &S;
1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic:
1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  LogicalErrorHandler(Sema &S) : CFGCallback(), S(S) {}
1266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  static bool HasMacroID(const Expr *E) {
1286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (E->getExprLoc().isMacroID())
1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return true;
1306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Recurse to children.
1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (ConstStmtRange SubStmts = E->children(); SubStmts; ++SubStmts)
1336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (*SubStmts)
1346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        if (const Expr *SubExpr = dyn_cast<Expr>(*SubStmts))
1356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          if (HasMacroID(SubExpr))
1366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines            return true;
1376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return false;
1396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {
1426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (HasMacroID(B))
1436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return;
1446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    SourceRange DiagRange = B->getSourceRange();
1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    S.Diag(B->getExprLoc(), diag::warn_tautological_overlap_comparison)
1476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        << DiagRange << isAlwaysTrue;
1486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void compareBitwiseEquality(const BinaryOperator *B, bool isAlwaysTrue) {
1516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (HasMacroID(B))
1526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return;
1536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    SourceRange DiagRange = B->getSourceRange();
1556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    S.Diag(B->getExprLoc(), diag::warn_comparison_bitwise_always)
1566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        << DiagRange << isAlwaysTrue;
1576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
1596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===//
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Check for infinite self-recursion in functions
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===//
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// All blocks are in one of three states.  States are ordered so that blocks
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// can only move to higher states.
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesenum RecursiveState {
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  FoundNoPath,
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  FoundPath,
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  FoundPathWithNoRecursiveCall
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void checkForFunctionCall(Sema &S, const FunctionDecl *FD,
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 CFGBlock &Block, unsigned ExitID,
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 llvm::SmallVectorImpl<RecursiveState> &States,
176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 RecursiveState State) {
177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned ID = Block.getBlockID();
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // A block's state can only move to a higher state.
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (States[ID] >= State)
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  States[ID] = State;
184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Found a path to the exit node without a recursive call.
186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (ID == ExitID && State == FoundPathWithNoRecursiveCall)
187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (State == FoundPathWithNoRecursiveCall) {
190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // If the current state is FoundPathWithNoRecursiveCall, the successors
191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // will be either FoundPathWithNoRecursiveCall or FoundPath.  To determine
192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // which, process all the Stmt's in this block to find any recursive calls.
1936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &B : Block) {
1946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (B.getKind() != CFGElement::Statement)
195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        continue;
196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      const CallExpr *CE = dyn_cast<CallExpr>(B.getAs<CFGStmt>()->getStmt());
198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (CE && CE->getCalleeDecl() &&
199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          CE->getCalleeDecl()->getCanonicalDecl() == FD) {
200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        // Skip function calls which are qualified with a templated class.
202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                CE->getCallee()->IgnoreParenImpCasts())) {
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (NestedNameSpecifier *NNS = DRE->getQualifier()) {
205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            if (NNS->getKind() == NestedNameSpecifier::TypeSpec &&
206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                isa<TemplateSpecializationType>(NNS->getAsType())) {
207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines               continue;
208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            }
209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          }
210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        }
211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE)) {
213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (isa<CXXThisExpr>(MCE->getImplicitObjectArgument()) ||
214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              !MCE->getMethodDecl()->isVirtual()) {
215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            State = FoundPath;
216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            break;
217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          }
218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        } else {
219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          State = FoundPath;
220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          break;
221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        }
222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
225651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (CFGBlock::succ_iterator I = Block.succ_begin(), E = Block.succ_end();
227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       I != E; ++I)
228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*I)
229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      checkForFunctionCall(S, FD, **I, ExitID, States, State);
230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void checkRecursiveFunction(Sema &S, const FunctionDecl *FD,
233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   const Stmt *Body,
234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   AnalysisDeclContext &AC) {
235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  FD = FD->getCanonicalDecl();
236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Only run on non-templated functions and non-templated members of
238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // templated classes.
239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate &&
240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      FD->getTemplatedKind() != FunctionDecl::TK_MemberSpecialization)
241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CFG *cfg = AC.getCFG();
2446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!cfg) return;
245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // If the exit block is unreachable, skip processing the function.
247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (cfg->getExit().pred_empty())
248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Mark all nodes as FoundNoPath, then begin processing the entry block.
251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::SmallVector<RecursiveState, 16> states(cfg->getNumBlockIDs(),
252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                               FoundNoPath);
253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  checkForFunctionCall(S, FD, cfg->getEntry(), cfg->getExit().getBlockID(),
254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                       states, FoundPathWithNoRecursiveCall);
255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Check that the exit block is reachable.  This prevents triggering the
257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // warning on functions that do not terminate.
258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (states[cfg->getExit().getBlockID()] == FoundPath)
259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    S.Diag(Body->getLocStart(), diag::warn_infinite_recursive_function);
260dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
261dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
262dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
263dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Check for missing return value.
264dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
265dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
26616565aa95b086fb239baf82335dccc1b1ec93942John McCallenum ControlFlowKind {
26716565aa95b086fb239baf82335dccc1b1ec93942John McCall  UnknownFallThrough,
26816565aa95b086fb239baf82335dccc1b1ec93942John McCall  NeverFallThrough,
26916565aa95b086fb239baf82335dccc1b1ec93942John McCall  MaybeFallThrough,
27016565aa95b086fb239baf82335dccc1b1ec93942John McCall  AlwaysFallThrough,
27116565aa95b086fb239baf82335dccc1b1ec93942John McCall  NeverFallThroughOrReturn
27216565aa95b086fb239baf82335dccc1b1ec93942John McCall};
273dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
274dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThrough - Check that we don't fall off the end of a
275dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// Statement that should return a value.
276dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek///
277f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// \returns AlwaysFallThrough iff we always fall off the end of the statement,
278f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// MaybeFallThrough iff we might or might not fall off the end,
279f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// NeverFallThroughOrReturn iff we never fall off the end of the statement or
280f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// return.  We assume NeverFallThrough iff we never fall off the end of the
281dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// statement but we may return.  We assume that functions not marked noreturn
282dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// will return.
2831d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekstatic ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) {
284dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  CFG *cfg = AC.getCFG();
2856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!cfg) return UnknownFallThrough;
286dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
287dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // The CFG leaves in dead things, and we don't want the dead code paths to
288dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // confuse us, so we mark all live things first.
289dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  llvm::BitVector live(cfg->getNumBlockIDs());
2900f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek  unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(),
291dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                                          live);
292dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
293dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool AddEHEdges = AC.getAddEHEdges();
294dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (!AddEHEdges && count != cfg->getNumBlockIDs())
295dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // When there are things remaining dead, and we didn't add EH edges
296dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // from CallExprs to the catch clauses, we have to go back and
297dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // mark them as live.
2986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto *B : *cfg) {
2996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (!live[B->getBlockID()]) {
3006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        if (B->pred_begin() == B->pred_end()) {
3016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          if (B->getTerminator() && isa<CXXTryStmt>(B->getTerminator()))
302dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek            // When not adding EH edges from calls, catch clauses
303dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek            // can otherwise seem dead.  Avoid noting them as dead.
3046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines            count += reachable_code::ScanReachableFromBlock(B, live);
305dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          continue;
306dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        }
307dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
308dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
309dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
310dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Now we know what is live, we check the live precessors of the exit block
311dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // and look for fall through paths, being careful to ignore normal returns,
312dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // and exceptional paths.
313dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasLiveReturn = false;
314dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasFakeEdge = false;
315dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasPlainEdge = false;
316dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasAbnormalEdge = false;
31790b828aa279542559f655d1af666580288cb1841Ted Kremenek
31890b828aa279542559f655d1af666580288cb1841Ted Kremenek  // Ignore default cases that aren't likely to be reachable because all
31990b828aa279542559f655d1af666580288cb1841Ted Kremenek  // enums in a switch(X) have explicit case statements.
32090b828aa279542559f655d1af666580288cb1841Ted Kremenek  CFGBlock::FilterOptions FO;
32190b828aa279542559f655d1af666580288cb1841Ted Kremenek  FO.IgnoreDefaultsWithCoveredEnums = 1;
32290b828aa279542559f655d1af666580288cb1841Ted Kremenek
32390b828aa279542559f655d1af666580288cb1841Ted Kremenek  for (CFGBlock::filtered_pred_iterator
32490b828aa279542559f655d1af666580288cb1841Ted Kremenek	 I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) {
32590b828aa279542559f655d1af666580288cb1841Ted Kremenek    const CFGBlock& B = **I;
326dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (!live[B.getBlockID()])
327dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
3285811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek
329e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    // Skip blocks which contain an element marked as no-return. They don't
330e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    // represent actually viable edges into the exit block, so mark them as
331e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    // abnormal.
332e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    if (B.hasNoReturnElement()) {
333e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth      HasAbnormalEdge = true;
334e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth      continue;
335e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    }
336e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth
3375811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // Destructors can appear after the 'return' in the CFG.  This is
3385811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // normal.  We need to look pass the destructors for the return
3395811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // statement (if it exists).
3405811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend();
341e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth
342e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    for ( ; ri != re ; ++ri)
343fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie      if (ri->getAs<CFGStmt>())
3445811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek        break;
345e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth
3465811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // No more CFGElements in the block?
3475811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    if (ri == re) {
348dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) {
349dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasAbnormalEdge = true;
350dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        continue;
351dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
352dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      // A labeled empty statement, or the entry block...
353dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasPlainEdge = true;
354dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
355dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
356f39e6a388aaa2f155b46c61e655784b2473218ebTed Kremenek
357fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie    CFGStmt CS = ri->castAs<CFGStmt>();
358f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek    const Stmt *S = CS.getStmt();
359dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<ReturnStmt>(S)) {
360dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasLiveReturn = true;
361dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
362dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
363dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<ObjCAtThrowStmt>(S)) {
364dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasFakeEdge = true;
365dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
366dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
367dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<CXXThrowExpr>(S)) {
368dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasFakeEdge = true;
369dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
370dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
3718cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier    if (isa<MSAsmStmt>(S)) {
3728cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      // TODO: Verify this is correct.
3738cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      HasFakeEdge = true;
3748cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      HasLiveReturn = true;
3758cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      continue;
3768cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier    }
377dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<CXXTryStmt>(S)) {
378dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasAbnormalEdge = true;
379dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
380dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
381e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit())
382e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth        == B.succ_end()) {
383e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth      HasAbnormalEdge = true;
384e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth      continue;
385dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
386e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth
387e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth    HasPlainEdge = true;
388dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
389dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (!HasPlainEdge) {
390dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (HasLiveReturn)
391dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      return NeverFallThrough;
392dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return NeverFallThroughOrReturn;
393dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
394dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn)
395dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return MaybeFallThrough;
396dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // This says AlwaysFallThrough for calls to functions that are not marked
397dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // noreturn, that don't return.  If people would like this warning to be more
398dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // accurate, such functions should be marked as noreturn.
399dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  return AlwaysFallThrough;
400dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
401dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
4023c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohmannamespace {
4033c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman
404dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstruct CheckFallThroughDiagnostics {
405dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_MaybeFallThrough_HasNoReturn;
406dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_MaybeFallThrough_ReturnsNonVoid;
407dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_AlwaysFallThrough_HasNoReturn;
408dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
409dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_NeverFallThroughOrReturn;
410793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor  enum { Function, Block, Lambda } funMode;
4110827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis  SourceLocation FuncLoc;
412d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
413ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor  static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
414dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CheckFallThroughDiagnostics D;
4150827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    D.FuncLoc = Func->getLocation();
416dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_HasNoReturn =
417dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_noreturn_function;
418dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_ReturnsNonVoid =
419dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_maybe_falloff_nonvoid_function;
420dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_HasNoReturn =
421dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_noreturn_function;
422dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_ReturnsNonVoid =
423dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_nonvoid_function;
424ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor
425ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    // Don't suggest that virtual functions be marked "noreturn", since they
426ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    // might be overridden by non-noreturn functions.
427ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    bool isVirtualMethod = false;
428ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func))
429ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor      isVirtualMethod = Method->isVirtual();
430ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor
431fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor    // Don't suggest that template instantiations be marked "noreturn"
432fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor    bool isTemplateInstantiation = false;
43375df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func))
43475df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek      isTemplateInstantiation = Function->isTemplateInstantiation();
435fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor
436fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor    if (!isVirtualMethod && !isTemplateInstantiation)
437ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor      D.diag_NeverFallThroughOrReturn =
438ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor        diag::warn_suggest_noreturn_function;
439ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    else
440ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor      D.diag_NeverFallThroughOrReturn = 0;
441ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor
442793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.funMode = Function;
443dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return D;
444dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
445d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
446dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  static CheckFallThroughDiagnostics MakeForBlock() {
447dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CheckFallThroughDiagnostics D;
448dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_HasNoReturn =
449dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_noreturn_block_has_return_expr;
450dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_ReturnsNonVoid =
451dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_maybe_falloff_nonvoid_block;
452dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_HasNoReturn =
453dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_noreturn_block_has_return_expr;
454dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_ReturnsNonVoid =
455dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_falloff_nonvoid_block;
4566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    D.diag_NeverFallThroughOrReturn = 0;
457793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.funMode = Block;
458793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    return D;
459793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor  }
460793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor
461793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor  static CheckFallThroughDiagnostics MakeForLambda() {
462793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    CheckFallThroughDiagnostics D;
463793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.diag_MaybeFallThrough_HasNoReturn =
464793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor      diag::err_noreturn_lambda_has_return_expr;
465793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.diag_MaybeFallThrough_ReturnsNonVoid =
466793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor      diag::warn_maybe_falloff_nonvoid_lambda;
467793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.diag_AlwaysFallThrough_HasNoReturn =
468793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor      diag::err_noreturn_lambda_has_return_expr;
469793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.diag_AlwaysFallThrough_ReturnsNonVoid =
470793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor      diag::warn_falloff_nonvoid_lambda;
471793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.diag_NeverFallThroughOrReturn = 0;
472793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    D.funMode = Lambda;
473dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return D;
474dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
475d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
476d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid,
477dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                        bool HasNoReturn) const {
478793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    if (funMode == Function) {
4790827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      return (ReturnsVoid ||
480ef8225444452a1486bd721f3285301fe84643b00Stephen Hines              D.isIgnored(diag::warn_maybe_falloff_nonvoid_function,
481ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                          FuncLoc)) &&
482ef8225444452a1486bd721f3285301fe84643b00Stephen Hines             (!HasNoReturn ||
483ef8225444452a1486bd721f3285301fe84643b00Stephen Hines              D.isIgnored(diag::warn_noreturn_function_has_return_expr,
484ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                          FuncLoc)) &&
485ef8225444452a1486bd721f3285301fe84643b00Stephen Hines             (!ReturnsVoid ||
486ef8225444452a1486bd721f3285301fe84643b00Stephen Hines              D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc));
487dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
488d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
489793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor    // For blocks / lambdas.
4906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return ReturnsVoid && !HasNoReturn;
491dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
492dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek};
493dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
4943c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman}
4953c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman
496dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
497dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// function that should return a value.  Check that we don't fall off the end
498dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// of a noreturn function.  We assume that functions and blocks not marked
499dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// noreturn will return.
500dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
5013ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek                                    const BlockExpr *blkExpr,
502dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                    const CheckFallThroughDiagnostics& CD,
5031d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek                                    AnalysisDeclContext &AC) {
504dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
505dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool ReturnsVoid = false;
506dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasNoReturn = false;
507dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
508dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
509651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ReturnsVoid = FD->getReturnType()->isVoidType();
510cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith    HasNoReturn = FD->isNoReturn();
511dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
512dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
513651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ReturnsVoid = MD->getReturnType()->isVoidType();
514dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    HasNoReturn = MD->hasAttr<NoReturnAttr>();
515dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
516dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  else if (isa<BlockDecl>(D)) {
5173ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek    QualType BlockTy = blkExpr->getType();
518d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek    if (const FunctionType *FT =
519dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          BlockTy->getPointeeType()->getAs<FunctionType>()) {
520651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (FT->getReturnType()->isVoidType())
521dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        ReturnsVoid = true;
522dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (FT->getNoReturnAttr())
523dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasNoReturn = true;
524dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
525dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
526dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
527d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &Diags = S.getDiagnostics();
528dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
529dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Short circuit for compilation speed.
530dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
531dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      return;
532d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
533dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // FIXME: Function try block
534dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) {
535dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    switch (CheckFallThrough(AC)) {
53616565aa95b086fb239baf82335dccc1b1ec93942John McCall      case UnknownFallThrough:
53716565aa95b086fb239baf82335dccc1b1ec93942John McCall        break;
53816565aa95b086fb239baf82335dccc1b1ec93942John McCall
539dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case MaybeFallThrough:
540dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        if (HasNoReturn)
541dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
542dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_MaybeFallThrough_HasNoReturn);
543dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        else if (!ReturnsVoid)
544dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
545dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_MaybeFallThrough_ReturnsNonVoid);
546dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
547dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case AlwaysFallThrough:
548dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        if (HasNoReturn)
549dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
550dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_AlwaysFallThrough_HasNoReturn);
551dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        else if (!ReturnsVoid)
552dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
553dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_AlwaysFallThrough_ReturnsNonVoid);
554dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
555dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case NeverFallThroughOrReturn:
556b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth        if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
557b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth          if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
558b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn)
559b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor              << 0 << FD;
560b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor          } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
561b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn)
562b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor              << 1 << MD;
563b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth          } else {
564b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn);
565b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth          }
566b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth        }
567dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
568dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case NeverFallThrough:
569dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
570dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
571dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
572dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
573dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
574dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
575610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// -Wuninitialized
576610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===//
577610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek
5786f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremeneknamespace {
5799f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// ContainsReference - A visitor class to search for references to
5809f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// a particular declaration (the needle) within any evaluated component of an
5819f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// expression (recursively).
5826f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenekclass ContainsReference : public EvaluatedExprVisitor<ContainsReference> {
5839f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  bool FoundReference;
5849f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  const DeclRefExpr *Needle;
5859f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
5866f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenekpublic:
5879f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  ContainsReference(ASTContext &Context, const DeclRefExpr *Needle)
5889f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    : EvaluatedExprVisitor<ContainsReference>(Context),
5899f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth      FoundReference(false), Needle(Needle) {}
5909f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
5919f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  void VisitExpr(Expr *E) {
5926f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek    // Stop evaluating if we already have a reference.
5939f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    if (FoundReference)
5946f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek      return;
5959f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
5969f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    EvaluatedExprVisitor<ContainsReference>::VisitExpr(E);
5976f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek  }
5989f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
5999f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  void VisitDeclRefExpr(DeclRefExpr *E) {
6009f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    if (E == Needle)
6019f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth      FoundReference = true;
6029f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    else
6039f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth      EvaluatedExprVisitor<ContainsReference>::VisitDeclRefExpr(E);
6046f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek  }
6059f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
6069f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  bool doesContainReference() const { return FoundReference; }
6076f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek};
6086f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek}
6096f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek
6104f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikiestatic bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
611a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian  QualType VariableTy = VD->getType().getCanonicalType();
612a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian  if (VariableTy->isBlockPointerType() &&
613a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian      !VD->hasAttr<BlocksAttr>()) {
614ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization)
615ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        << VD->getDeclName()
616ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
617a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian    return true;
618a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian  }
6198adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith
6204f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie  // Don't issue a fixit if there is already an initializer.
6214f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie  if (VD->getInit())
6224f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie    return false;
6237b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu
6247b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu  // Don't suggest a fixit inside macros.
6257b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu  if (VD->getLocEnd().isMacroID())
6267b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu    return false;
6277b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu
6286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  SourceLocation Loc = S.getLocForEndOfToken(VD->getLocEnd());
6298adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith
6308adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith  // Suggest possible initialization (if any).
6318adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith  std::string Init = S.getFixItZeroInitializerForType(VariableTy, Loc);
6328adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith  if (Init.empty())
6338adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith    return false;
6348adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith
6357984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith  S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
6367984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith    << FixItHint::CreateInsertion(Loc, Init);
6377984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith  return true;
6384f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie}
6394f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie
640bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// Create a fixit to remove an if-like statement, on the assumption that its
641bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// condition is CondVal.
642bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smithstatic void CreateIfFixit(Sema &S, const Stmt *If, const Stmt *Then,
643bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                          const Stmt *Else, bool CondVal,
644bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                          FixItHint &Fixit1, FixItHint &Fixit2) {
645bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  if (CondVal) {
646bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    // If condition is always true, remove all but the 'then'.
647bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    Fixit1 = FixItHint::CreateRemoval(
648bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        CharSourceRange::getCharRange(If->getLocStart(),
649bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                                      Then->getLocStart()));
650bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    if (Else) {
651bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      SourceLocation ElseKwLoc = Lexer::getLocForEndOfToken(
652bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith          Then->getLocEnd(), 0, S.getSourceManager(), S.getLangOpts());
653bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Fixit2 = FixItHint::CreateRemoval(
654bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith          SourceRange(ElseKwLoc, Else->getLocEnd()));
655bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    }
656bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  } else {
657bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    // If condition is always false, remove all but the 'else'.
658bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    if (Else)
659bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Fixit1 = FixItHint::CreateRemoval(
660bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith          CharSourceRange::getCharRange(If->getLocStart(),
661bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                                        Else->getLocStart()));
662bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    else
663bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Fixit1 = FixItHint::CreateRemoval(If->getSourceRange());
664bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  }
665bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith}
666bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
667bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// DiagUninitUse -- Helper function to produce a diagnostic for an
668bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// uninitialized use of a variable.
669bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smithstatic void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,
670bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                          bool IsCapturedByBlock) {
671bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  bool Diagnosed = false;
672bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
6738a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  switch (Use.getKind()) {
6748a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  case UninitUse::Always:
6758a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    S.Diag(Use.getUser()->getLocStart(), diag::warn_uninit_var)
6768a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        << VD->getDeclName() << IsCapturedByBlock
6778a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        << Use.getUser()->getSourceRange();
6788a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    return;
6798a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith
6808a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  case UninitUse::AfterDecl:
6818a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  case UninitUse::AfterCall:
6828a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    S.Diag(VD->getLocation(), diag::warn_sometimes_uninit_var)
6838a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      << VD->getDeclName() << IsCapturedByBlock
6848a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      << (Use.getKind() == UninitUse::AfterDecl ? 4 : 5)
6858a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      << const_cast<DeclContext*>(VD->getLexicalDeclContext())
6868a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      << VD->getSourceRange();
6878a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    S.Diag(Use.getUser()->getLocStart(), diag::note_uninit_var_use)
6888a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      << IsCapturedByBlock << Use.getUser()->getSourceRange();
6898a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    return;
6908a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith
6918a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  case UninitUse::Maybe:
6928a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  case UninitUse::Sometimes:
6938a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    // Carry on to report sometimes-uninitialized branches, if possible,
6948a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    // or a 'may be used uninitialized' diagnostic otherwise.
6958a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    break;
6968a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith  }
6978a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith
698bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  // Diagnose each branch which leads to a sometimes-uninitialized use.
6992815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith  for (UninitUse::branch_iterator I = Use.branch_begin(), E = Use.branch_end();
7002815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith       I != E; ++I) {
701bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    assert(Use.getKind() == UninitUse::Sometimes);
702bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
703bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    const Expr *User = Use.getUser();
7042815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    const Stmt *Term = I->Terminator;
705bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
706bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    // Information used when building the diagnostic.
7072815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    unsigned DiagKind;
7080bea86307eb8c16339315a1e261fc490eb505c5bDavid Blaikie    StringRef Str;
709bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    SourceRange Range;
710bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
711fc09336a5965040736f9bc63a70416003972364eStefanus Du Toit    // FixIts to suppress the diagnostic by removing the dead condition.
712bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    // For all binary terminators, branch 0 is taken if the condition is true,
713bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    // and branch 1 is taken if the condition is false.
714bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    int RemoveDiagKind = -1;
715bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    const char *FixitStr =
716bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        S.getLangOpts().CPlusPlus ? (I->Output ? "true" : "false")
717bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                                  : (I->Output ? "1" : "0");
718bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    FixItHint Fixit1, Fixit2;
719bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
7208a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    switch (Term ? Term->getStmtClass() : Stmt::DeclStmtClass) {
7212815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    default:
722bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      // Don't know how to report this. Just fall back to 'may be used
7238a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      // uninitialized'. FIXME: Can this happen?
7242815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      continue;
7252815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
7262815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    // "condition is true / condition is false".
727bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    case Stmt::IfStmtClass: {
728bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      const IfStmt *IS = cast<IfStmt>(Term);
7292815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 0;
7302815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "if";
731bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Range = IS->getCond()->getSourceRange();
732bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 0;
733bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      CreateIfFixit(S, IS, IS->getThen(), IS->getElse(),
734bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                    I->Output, Fixit1, Fixit2);
7352815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
736bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    }
737bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    case Stmt::ConditionalOperatorClass: {
738bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      const ConditionalOperator *CO = cast<ConditionalOperator>(Term);
7392815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 0;
7402815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "?:";
741bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Range = CO->getCond()->getSourceRange();
742bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 0;
743bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(),
744bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                    I->Output, Fixit1, Fixit2);
7452815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
746bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    }
7472815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::BinaryOperatorClass: {
7482815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      const BinaryOperator *BO = cast<BinaryOperator>(Term);
7492815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      if (!BO->isLogicalOp())
7502815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith        continue;
7512815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 0;
7522815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = BO->getOpcodeStr();
7532815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = BO->getLHS()->getSourceRange();
754bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 0;
755bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      if ((BO->getOpcode() == BO_LAnd && I->Output) ||
756bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith          (BO->getOpcode() == BO_LOr && !I->Output))
757bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        // true && y -> y, false || y -> y.
758bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        Fixit1 = FixItHint::CreateRemoval(SourceRange(BO->getLocStart(),
759bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith                                                      BO->getOperatorLoc()));
760bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      else
761bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        // false && y -> false, true || y -> true.
762bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        Fixit1 = FixItHint::CreateReplacement(BO->getSourceRange(), FixitStr);
7632815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
7642815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    }
7652815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
7662815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    // "loop is entered / loop is exited".
7672815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::WhileStmtClass:
7682815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 1;
7692815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "while";
7702815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = cast<WhileStmt>(Term)->getCond()->getSourceRange();
771bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 1;
772bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
7732815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
7742815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::ForStmtClass:
7752815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 1;
7762815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "for";
7772815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = cast<ForStmt>(Term)->getCond()->getSourceRange();
778bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 1;
779bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      if (I->Output)
780bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        Fixit1 = FixItHint::CreateRemoval(Range);
781bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      else
782bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
7832815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
7848a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    case Stmt::CXXForRangeStmtClass:
7858a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      if (I->Output == 1) {
7868a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        // The use occurs if a range-based for loop's body never executes.
7878a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        // That may be impossible, and there's no syntactic fix for this,
7888a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        // so treat it as a 'may be uninitialized' case.
7898a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith        continue;
7908a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      }
7918a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      DiagKind = 1;
7928a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      Str = "for";
7938a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      Range = cast<CXXForRangeStmt>(Term)->getRangeInit()->getSourceRange();
7948a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith      break;
7952815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
7962815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    // "condition is true / loop is exited".
7972815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::DoStmtClass:
7982815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 2;
7992815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "do";
8002815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = cast<DoStmt>(Term)->getCond()->getSourceRange();
801bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      RemoveDiagKind = 1;
802bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
8032815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
8042815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
8052815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    // "switch case is taken".
8062815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::CaseStmtClass:
8072815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 3;
8082815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "case";
8092815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = cast<CaseStmt>(Term)->getLHS()->getSourceRange();
8102815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
8112815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    case Stmt::DefaultStmtClass:
8122815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      DiagKind = 3;
8132815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Str = "default";
8142815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      Range = cast<DefaultStmt>(Term)->getDefaultLoc();
8152815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith      break;
8162815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    }
8172815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
818bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    S.Diag(Range.getBegin(), diag::warn_sometimes_uninit_var)
819bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      << VD->getDeclName() << IsCapturedByBlock << DiagKind
820bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      << Str << I->Output << Range;
821bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    S.Diag(User->getLocStart(), diag::note_uninit_var_use)
822bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      << IsCapturedByBlock << User->getSourceRange();
823bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    if (RemoveDiagKind != -1)
824bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      S.Diag(Fixit1.RemoveRange.getBegin(), diag::note_uninit_fixit_remove_cond)
825bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2;
826bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
827bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    Diagnosed = true;
8282815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith  }
829bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith
830bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith  if (!Diagnosed)
8318a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith    S.Diag(Use.getUser()->getLocStart(), diag::warn_maybe_uninit_var)
832bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        << VD->getDeclName() << IsCapturedByBlock
833bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith        << Use.getUser()->getSourceRange();
8342815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith}
8352815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
836262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an
837262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// uninitialized variable. This manages the different forms of diagnostic
838262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// emitted for particular types of uses. Returns true if the use was diagnosed
8392815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith/// as a warning. If a particular use is one we omit warnings for, returns
840262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// false.
841262d50e1dcf529317da193ad585c11c16281a7acChandler Carruthstatic bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
8422815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith                                     const UninitUse &Use,
8439e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek                                     bool alwaysReportSelfInit = false) {
8444c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
8452815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Use.getUser())) {
846f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // Inspect the initializer of the variable declaration which is
847f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // being referenced prior to its initialization. We emit
848f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // specialized diagnostics for self-initialization, and we
849f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // specifically avoid warning about self references which take the
850f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // form of:
851f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    //
852f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    //   int x = x;
853f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    //
854f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // This is used to indicate to GCC that 'x' is intentionally left
855f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // uninitialized. Proven code paths which access 'x' in
856f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    // an uninitialized state after this will still warn.
857f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu    if (const Expr *Initializer = VD->getInit()) {
858f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu      if (!alwaysReportSelfInit && DRE == Initializer->IgnoreParenImpCasts())
859f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu        return false;
860f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu
861f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu      ContainsReference CR(S.Context, DRE);
862f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu      CR.Visit(const_cast<Expr*>(Initializer));
863f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu      if (CR.doesContainReference()) {
8644c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth        S.Diag(DRE->getLocStart(),
8654c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth               diag::warn_uninit_self_reference_in_init)
866f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu          << VD->getDeclName() << VD->getLocation() << DRE->getSourceRange();
867f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu        return true;
8684c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      }
8694c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    }
870f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu
871bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    DiagUninitUse(S, VD, Use, false);
8724c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  } else {
8732815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith    const BlockExpr *BE = cast<BlockExpr>(Use.getUser());
874bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    if (VD->getType()->isBlockPointerType() && !VD->hasAttr<BlocksAttr>())
875bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      S.Diag(BE->getLocStart(),
876bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith             diag::warn_uninit_byref_blockvar_captured_by_block)
877a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian        << VD->getDeclName();
878bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith    else
879bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith      DiagUninitUse(S, VD, Use, true);
8804c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  }
8814c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
8824c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  // Report where the variable was declared when the use wasn't within
8834f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie  // the initializer of that declaration & we didn't already suggest
8844f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie  // an initialization fixit.
885f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu  if (!SuggestInitializationFixit(S, VD))
8864c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    S.Diag(VD->getLocStart(), diag::note_uninit_var_def)
8874c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      << VD->getDeclName();
8884c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
889262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth  return true;
89064fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth}
89164fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth
892e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smithnamespace {
893e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> {
894e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  public:
895e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    FallthroughMapper(Sema &S)
896e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      : FoundSwitchStatements(false),
897e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        S(S) {
898e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
899e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
900e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool foundSwitchStatements() const { return FoundSwitchStatements; }
901e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
902e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    void markFallthroughVisited(const AttributedStmt *Stmt) {
903e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      bool Found = FallthroughStmts.erase(Stmt);
904e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      assert(Found);
9053bb2994a7de3679fb825f3a36f3dc11ea1daf6a6Kaelyn Uhrain      (void)Found;
906e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
907e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
908e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts;
909e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
910e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    const AttrStmts &getFallthroughStmts() const {
911e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      return FallthroughStmts;
912e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
913e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
9144874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko    void fillReachableBlocks(CFG *Cfg) {
9154874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      assert(ReachableBlocks.empty() && "ReachableBlocks already filled");
9164874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      std::deque<const CFGBlock *> BlockQueue;
9174874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko
9184874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      ReachableBlocks.insert(&Cfg->getEntry());
9194874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      BlockQueue.push_back(&Cfg->getEntry());
920878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko      // Mark all case blocks reachable to avoid problems with switching on
921878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko      // constants, covered enums, etc.
922878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko      // These blocks can contain fall-through annotations, and we don't want to
923878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko      // issue a warn_fallthrough_attr_unreachable for them.
9246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      for (const auto *B : *Cfg) {
925878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko        const Stmt *L = B->getLabel();
926878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko        if (L && isa<SwitchCase>(L) && ReachableBlocks.insert(B))
927878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko          BlockQueue.push_back(B);
928878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko      }
929878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko
9304874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      while (!BlockQueue.empty()) {
9314874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko        const CFGBlock *P = BlockQueue.front();
9324874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko        BlockQueue.pop_front();
9334874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko        for (CFGBlock::const_succ_iterator I = P->succ_begin(),
9344874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko                                           E = P->succ_end();
9354874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko             I != E; ++I) {
9360162b832fd6450cd3a23019a3c900382d0e9415cAlexander Kornienko          if (*I && ReachableBlocks.insert(*I))
9374874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko            BlockQueue.push_back(*I);
9384874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko        }
9394874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      }
9404874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko    }
9414874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko
942e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) {
9434874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko      assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
9444874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko
945e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      int UnannotatedCnt = 0;
946e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      AnnotatedCnt = 0;
947e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
9486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      std::deque<const CFGBlock*> BlockQueue(B.pred_begin(), B.pred_end());
949e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      while (!BlockQueue.empty()) {
950e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        const CFGBlock *P = BlockQueue.front();
951e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        BlockQueue.pop_front();
952651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (!P) continue;
953e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
954e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        const Stmt *Term = P->getTerminator();
955e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (Term && isa<SwitchStmt>(Term))
956e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          continue; // Switch statement, good.
957e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
958e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel());
959e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end())
960e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          continue; // Previous case label has no statements, good.
961e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
962c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko        const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel());
963c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko        if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end())
964c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko          continue; // Case label is preceded with a normal label, good.
965c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko
9664874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko        if (!ReachableBlocks.count(P)) {
967878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko          for (CFGBlock::const_reverse_iterator ElemIt = P->rbegin(),
968878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko                                                ElemEnd = P->rend();
969878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko               ElemIt != ElemEnd; ++ElemIt) {
970b07805485c603be3d8011f72611465324c9e664bDavid Blaikie            if (Optional<CFGStmt> CS = ElemIt->getAs<CFGStmt>()) {
971b07805485c603be3d8011f72611465324c9e664bDavid Blaikie              if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) {
972e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                S.Diag(AS->getLocStart(),
973e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                       diag::warn_fallthrough_attr_unreachable);
974e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                markFallthroughVisited(AS);
975e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                ++AnnotatedCnt;
976878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko                break;
977e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith              }
978e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith              // Don't care about other unreachable statements.
979e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith            }
980e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          }
981e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // If there are no unreachable statements, this may be a special
982e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // case in CFG:
983e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // case X: {
984e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          //    A a;  // A has a destructor.
985e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          //    break;
986e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // }
987e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // // <<<< This place is represented by a 'hanging' CFG block.
988e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // case Y:
989e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          continue;
990e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        }
991e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
992e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        const Stmt *LastStmt = getLastStmt(*P);
993e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
994e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          markFallthroughVisited(AS);
995e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          ++AnnotatedCnt;
996e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          continue; // Fallthrough annotation, good.
997e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        }
998e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
999e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (!LastStmt) { // This block contains no executable statements.
1000e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          // Traverse its predecessors.
1001e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          std::copy(P->pred_begin(), P->pred_end(),
1002e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                    std::back_inserter(BlockQueue));
1003e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          continue;
1004e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        }
1005e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1006e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        ++UnannotatedCnt;
1007e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      }
1008e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      return !!UnannotatedCnt;
1009e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1010e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1011e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    // RecursiveASTVisitor setup.
1012e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool shouldWalkTypesOfTypeLocs() const { return false; }
1013e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1014e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool VisitAttributedStmt(AttributedStmt *S) {
1015e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      if (asFallThroughAttr(S))
1016e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        FallthroughStmts.insert(S);
1017e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      return true;
1018e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1019e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1020e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool VisitSwitchStmt(SwitchStmt *S) {
1021e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      FoundSwitchStatements = true;
1022e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      return true;
1023e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1024e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1025b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko    // We don't want to traverse local type declarations. We analyze their
1026b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko    // methods separately.
1027b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko    bool TraverseDecl(Decl *D) { return true; }
1028b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko
1029ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    // We analyze lambda bodies separately. Skip them here.
1030ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
1031ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
1032e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  private:
1033e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1034e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
1035e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {
1036e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
1037e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          return AS;
1038e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      }
10396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return nullptr;
1040e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1041e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1042e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    static const Stmt *getLastStmt(const CFGBlock &B) {
1043e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      if (const Stmt *Term = B.getTerminator())
1044e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        return Term;
1045e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      for (CFGBlock::const_reverse_iterator ElemIt = B.rbegin(),
1046e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                                            ElemEnd = B.rend();
1047e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                                            ElemIt != ElemEnd; ++ElemIt) {
1048b07805485c603be3d8011f72611465324c9e664bDavid Blaikie        if (Optional<CFGStmt> CS = ElemIt->getAs<CFGStmt>())
1049b07805485c603be3d8011f72611465324c9e664bDavid Blaikie          return CS->getStmt();
1050e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      }
1051e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      // Workaround to detect a statement thrown out by CFGBuilder:
1052e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      //   case X: {} case Y:
1053e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      //   case X: ; case Y:
1054e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))
1055e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        if (!isa<SwitchCase>(SW->getSubStmt()))
1056e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith          return SW->getSubStmt();
1057e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
10586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return nullptr;
1059e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1060e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1061e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    bool FoundSwitchStatements;
1062e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    AttrStmts FallthroughStmts;
1063e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    Sema &S;
10644874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko    llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
1065e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  };
1066e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith}
1067e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
10681973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienkostatic void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC,
1069c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt                                            bool PerFunction) {
10703078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // Only perform this analysis when using C++11.  There is no good workflow
10713078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // for this warning when not using C++11.  There is no good way to silence
10723078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // the warning (no attribute is available) unless we are using C++11's support
10733078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // for generalized attributes.  Once could use pragmas to silence the warning,
10743078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // but as a general solution that is gross and not in the spirit of this
10753078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // warning.
10763078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  //
10773078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // NOTE: This an intermediate solution.  There are on-going discussions on
10783078353fb56772193b9304510048ac075a2c95b5Ted Kremenek  // how to properly support this warning outside of C++11 with an annotation.
107980ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith  if (!AC.getASTContext().getLangOpts().CPlusPlus11)
10803078353fb56772193b9304510048ac075a2c95b5Ted Kremenek    return;
10813078353fb56772193b9304510048ac075a2c95b5Ted Kremenek
1082e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  FallthroughMapper FM(S);
1083e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  FM.TraverseStmt(AC.getBody());
1084e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1085e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  if (!FM.foundSwitchStatements())
1086e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    return;
1087e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1088c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt  if (PerFunction && FM.getFallthroughStmts().empty())
10891973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko    return;
10901973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko
1091e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  CFG *Cfg = AC.getCFG();
1092e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1093e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  if (!Cfg)
1094e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    return;
1095e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
10964874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko  FM.fillReachableBlocks(Cfg);
1097e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1098e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  for (CFG::reverse_iterator I = Cfg->rbegin(), E = Cfg->rend(); I != E; ++I) {
1099e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko    const CFGBlock *B = *I;
1100e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko    const Stmt *Label = B->getLabel();
1101e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1102e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    if (!Label || !isa<SwitchCase>(Label))
1103e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      continue;
1104e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
11054874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko    int AnnotatedCnt;
11064874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko
1107e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko    if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt))
1108e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      continue;
1109e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
11101973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko    S.Diag(Label->getLocStart(),
1111c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt        PerFunction ? diag::warn_unannotated_fallthrough_per_function
1112c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt                    : diag::warn_unannotated_fallthrough);
1113e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1114e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    if (!AnnotatedCnt) {
1115e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      SourceLocation L = Label->getLocStart();
1116e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      if (L.isMacroID())
1117e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        continue;
111880ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith      if (S.getLangOpts().CPlusPlus11) {
1119e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko        const Stmt *Term = B->getTerminator();
1120e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko        // Skip empty cases.
1121e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko        while (B->empty() && !Term && B->succ_size() == 1) {
1122e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko          B = *B->succ_begin();
1123e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko          Term = B->getTerminator();
1124e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko        }
1125e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko        if (!(B->empty() && Term && isa<BreakStmt>(Term))) {
112666da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko          Preprocessor &PP = S.getPreprocessor();
112766da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko          TokenValue Tokens[] = {
112866da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko            tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"),
112966da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko            tok::coloncolon, PP.getIdentifierInfo("fallthrough"),
113066da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko            tok::r_square, tok::r_square
113166da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko          };
11321952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko          StringRef AnnotationSpelling = "[[clang::fallthrough]]";
11331952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko          StringRef MacroName = PP.getLastMacroWithSpelling(L, Tokens);
11341952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko          if (!MacroName.empty())
11351952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko            AnnotationSpelling = MacroName;
11361952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko          SmallString<64> TextToInsert(AnnotationSpelling);
11371952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko          TextToInsert += "; ";
1138a189d8976f1193b788508a1a29b2e9d0aca06acaAlexander Kornienko          S.Diag(L, diag::note_insert_fallthrough_fixit) <<
113966da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko              AnnotationSpelling <<
11401952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko              FixItHint::CreateInsertion(L, TextToInsert);
1141a189d8976f1193b788508a1a29b2e9d0aca06acaAlexander Kornienko        }
1142e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      }
1143e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      S.Diag(L, diag::note_insert_break_fixit) <<
1144e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith        FixItHint::CreateInsertion(L, "break; ");
1145e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith    }
1146e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  }
1147e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
11486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  for (const auto *F : FM.getFallthroughStmts())
11496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    S.Diag(F->getLocStart(), diag::warn_fallthrough_attr_invalid_placement);
1150e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith}
1151e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
1152c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rosestatic bool isInLoop(const ASTContext &Ctx, const ParentMap &PM,
1153c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose                     const Stmt *S) {
1154b5cd1220dd650a358622241237aa595c5d675506Jordan Rose  assert(S);
1155b5cd1220dd650a358622241237aa595c5d675506Jordan Rose
1156b5cd1220dd650a358622241237aa595c5d675506Jordan Rose  do {
1157b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    switch (S->getStmtClass()) {
1158b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    case Stmt::ForStmtClass:
1159b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    case Stmt::WhileStmtClass:
1160b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    case Stmt::CXXForRangeStmtClass:
1161b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    case Stmt::ObjCForCollectionStmtClass:
1162b5cd1220dd650a358622241237aa595c5d675506Jordan Rose      return true;
1163c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    case Stmt::DoStmtClass: {
1164c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      const Expr *Cond = cast<DoStmt>(S)->getCond();
1165c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      llvm::APSInt Val;
1166c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      if (!Cond->EvaluateAsInt(Val, Ctx))
1167c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        return true;
1168c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      return Val.getBoolValue();
1169c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    }
1170b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    default:
1171b5cd1220dd650a358622241237aa595c5d675506Jordan Rose      break;
1172b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    }
1173b5cd1220dd650a358622241237aa595c5d675506Jordan Rose  } while ((S = PM.getParent(S)));
1174b5cd1220dd650a358622241237aa595c5d675506Jordan Rose
1175b5cd1220dd650a358622241237aa595c5d675506Jordan Rose  return false;
1176b5cd1220dd650a358622241237aa595c5d675506Jordan Rose}
1177b5cd1220dd650a358622241237aa595c5d675506Jordan Rose
117858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
117958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosestatic void diagnoseRepeatedUseOfWeak(Sema &S,
118058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose                                      const sema::FunctionScopeInfo *CurFn,
1181b5cd1220dd650a358622241237aa595c5d675506Jordan Rose                                      const Decl *D,
1182b5cd1220dd650a358622241237aa595c5d675506Jordan Rose                                      const ParentMap &PM) {
118358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy;
118458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap;
118558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector;
1186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef std::pair<const Stmt *, WeakObjectUseMap::const_iterator>
1187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StmtUsesPair;
118858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
1189c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose  ASTContext &Ctx = S.getASTContext();
1190c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose
119158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  const WeakObjectUseMap &WeakMap = CurFn->getWeakObjectUses();
119258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
119358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // Extract all weak objects that are referenced more than once.
119458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  SmallVector<StmtUsesPair, 8> UsesByStmt;
119558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  for (WeakObjectUseMap::const_iterator I = WeakMap.begin(), E = WeakMap.end();
119658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose       I != E; ++I) {
119758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    const WeakUseVector &Uses = I->second;
119858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
119958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    // Find the first read of the weak object.
120058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end();
120158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    for ( ; UI != UE; ++UI) {
120258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      if (UI->isUnsafe())
120358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose        break;
120458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
120558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
120658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    // If there were only writes to this object, don't warn.
120758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    if (UI == UE)
120858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      continue;
120958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
1210b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    // If there was only one read, followed by any number of writes, and the
1211c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    // read is not within a loop, don't warn. Additionally, don't warn in a
1212c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    // loop if the base object is a local variable -- local variables are often
1213c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    // changed in loops.
1214b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    if (UI == Uses.begin()) {
1215b5cd1220dd650a358622241237aa595c5d675506Jordan Rose      WeakUseVector::const_iterator UI2 = UI;
1216b5cd1220dd650a358622241237aa595c5d675506Jordan Rose      for (++UI2; UI2 != UE; ++UI2)
1217b5cd1220dd650a358622241237aa595c5d675506Jordan Rose        if (UI2->isUnsafe())
1218b5cd1220dd650a358622241237aa595c5d675506Jordan Rose          break;
1219b5cd1220dd650a358622241237aa595c5d675506Jordan Rose
1220c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      if (UI2 == UE) {
1221c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        if (!isInLoop(Ctx, PM, UI->getUseExpr()))
1222b5cd1220dd650a358622241237aa595c5d675506Jordan Rose          continue;
1223c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose
1224c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        const WeakObjectProfileTy &Profile = I->first;
1225c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        if (!Profile.isExactProfile())
1226c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose          continue;
1227c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose
1228c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        const NamedDecl *Base = Profile.getBase();
1229c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        if (!Base)
1230c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose          Base = Profile.getProperty();
1231c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        assert(Base && "A profile always has a base or property.");
1232c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose
1233c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose        if (const VarDecl *BaseVar = dyn_cast<VarDecl>(Base))
1234c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose          if (BaseVar->hasLocalStorage() && !isa<ParmVarDecl>(Base))
1235c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose            continue;
1236c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose      }
1237b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    }
1238b5cd1220dd650a358622241237aa595c5d675506Jordan Rose
123958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    UsesByStmt.push_back(StmtUsesPair(UI->getUseExpr(), I));
124058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  }
124158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
124258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  if (UsesByStmt.empty())
124358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    return;
124458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
124558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // Sort by first use so that we emit the warnings in a deterministic order.
1246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceManager &SM = S.getSourceManager();
124758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  std::sort(UsesByStmt.begin(), UsesByStmt.end(),
1248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            [&SM](const StmtUsesPair &LHS, const StmtUsesPair &RHS) {
1249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return SM.isBeforeInTranslationUnit(LHS.first->getLocStart(),
1250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        RHS.first->getLocStart());
1251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  });
125258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
125358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // Classify the current code body for better warning text.
125458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // This enum should stay in sync with the cases in
125558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.
125658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // FIXME: Should we use a common classification enum and the same set of
125758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // possibilities all throughout Sema?
125858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  enum {
125958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    Function,
126058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    Method,
126158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    Block,
126258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    Lambda
126358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  } FunctionKind;
126458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
126558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  if (isa<sema::BlockScopeInfo>(CurFn))
126658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    FunctionKind = Block;
126758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  else if (isa<sema::LambdaScopeInfo>(CurFn))
126858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    FunctionKind = Lambda;
126958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  else if (isa<ObjCMethodDecl>(D))
127058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    FunctionKind = Method;
127158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  else
127258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    FunctionKind = Function;
127358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
127458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  // Iterate through the sorted problems and emit warnings for each.
12756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  for (const auto &P : UsesByStmt) {
12766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const Stmt *FirstRead = P.first;
12776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const WeakObjectProfileTy &Key = P.second->first;
12786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const WeakUseVector &Uses = P.second->second;
127958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
12807a2704800943fbb69207e125d28186278712af36Jordan Rose    // For complicated expressions like 'a.b.c' and 'x.b.c', WeakObjectProfileTy
12817a2704800943fbb69207e125d28186278712af36Jordan Rose    // may not contain enough information to determine that these are different
12827a2704800943fbb69207e125d28186278712af36Jordan Rose    // properties. We can only be 100% sure of a repeated use in certain cases,
12837a2704800943fbb69207e125d28186278712af36Jordan Rose    // and we adjust the diagnostic kind accordingly so that the less certain
12847a2704800943fbb69207e125d28186278712af36Jordan Rose    // case can be turned off if it is too noisy.
128558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    unsigned DiagKind;
128658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    if (Key.isExactProfile())
128758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      DiagKind = diag::warn_arc_repeated_use_of_weak;
128858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    else
128958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      DiagKind = diag::warn_arc_possible_repeated_use_of_weak;
129058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
12917a2704800943fbb69207e125d28186278712af36Jordan Rose    // Classify the weak object being accessed for better warning text.
12927a2704800943fbb69207e125d28186278712af36Jordan Rose    // This enum should stay in sync with the cases in
12937a2704800943fbb69207e125d28186278712af36Jordan Rose    // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.
12947a2704800943fbb69207e125d28186278712af36Jordan Rose    enum {
12957a2704800943fbb69207e125d28186278712af36Jordan Rose      Variable,
12967a2704800943fbb69207e125d28186278712af36Jordan Rose      Property,
12977a2704800943fbb69207e125d28186278712af36Jordan Rose      ImplicitProperty,
12987a2704800943fbb69207e125d28186278712af36Jordan Rose      Ivar
12997a2704800943fbb69207e125d28186278712af36Jordan Rose    } ObjectKind;
13007a2704800943fbb69207e125d28186278712af36Jordan Rose
13017a2704800943fbb69207e125d28186278712af36Jordan Rose    const NamedDecl *D = Key.getProperty();
13027a2704800943fbb69207e125d28186278712af36Jordan Rose    if (isa<VarDecl>(D))
13037a2704800943fbb69207e125d28186278712af36Jordan Rose      ObjectKind = Variable;
13047a2704800943fbb69207e125d28186278712af36Jordan Rose    else if (isa<ObjCPropertyDecl>(D))
13057a2704800943fbb69207e125d28186278712af36Jordan Rose      ObjectKind = Property;
13067a2704800943fbb69207e125d28186278712af36Jordan Rose    else if (isa<ObjCMethodDecl>(D))
13077a2704800943fbb69207e125d28186278712af36Jordan Rose      ObjectKind = ImplicitProperty;
13087a2704800943fbb69207e125d28186278712af36Jordan Rose    else if (isa<ObjCIvarDecl>(D))
13097a2704800943fbb69207e125d28186278712af36Jordan Rose      ObjectKind = Ivar;
13107a2704800943fbb69207e125d28186278712af36Jordan Rose    else
13117a2704800943fbb69207e125d28186278712af36Jordan Rose      llvm_unreachable("Unexpected weak object kind!");
13127a2704800943fbb69207e125d28186278712af36Jordan Rose
131358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    // Show the first time the object was read.
131458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    S.Diag(FirstRead->getLocStart(), DiagKind)
13157348454025693dd20a411c2bcaabd4460cb87559Joerg Sonnenberger      << int(ObjectKind) << D << int(FunctionKind)
131658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      << FirstRead->getSourceRange();
131758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
131858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    // Print all the other accesses as notes.
13196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &Use : Uses) {
13206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (Use.getUseExpr() == FirstRead)
132158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose        continue;
13226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      S.Diag(Use.getUseExpr()->getLocStart(),
132358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose             diag::note_arc_weak_also_accessed_here)
13246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          << Use.getUseExpr()->getSourceRange();
132558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
132658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  }
132758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose}
132858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
132958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosenamespace {
1330610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass UninitValsDiagReporter : public UninitVariablesHandler {
1331610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek  Sema &S;
13325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  typedef SmallVector<UninitUse, 2> UsesVec;
1333e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer  typedef llvm::PointerIntPair<UsesVec *, 1, bool> MappedType;
13343285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella  // Prefer using MapVector to DenseMap, so that iteration order will be
13353285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella  // the same as insertion order. This is needed to obtain a deterministic
13363285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella  // order of diagnostics when calling flushDiagnostics().
13373285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella  typedef llvm::MapVector<const VarDecl *, MappedType> UsesMap;
133894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  UsesMap *uses;
133994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
1340610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic:
13416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  UninitValsDiagReporter(Sema &S) : S(S), uses(nullptr) {}
134294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  ~UninitValsDiagReporter() {
134394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    flushDiagnostics();
134494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  }
13459e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
13463285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella  MappedType &getUses(const VarDecl *vd) {
134794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    if (!uses)
134894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      uses = new UsesMap();
13499e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
13503285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella    MappedType &V = (*uses)[vd];
1351e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer    if (!V.getPointer())
1352e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer      V.setPointer(new UsesVec());
135394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
13549e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek    return V;
13559e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek  }
1356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleUseOfUninitVariable(const VarDecl *vd,
1358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 const UninitUse &use) override {
1359e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer    getUses(vd).getPointer()->push_back(use);
13609e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek  }
13619e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
1362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleSelfInit(const VarDecl *vd) override {
1363e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer    getUses(vd).setInt(true);
136494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  }
136594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
136694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  void flushDiagnostics() {
136794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    if (!uses)
136894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      return;
13693285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella
13706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &P : *uses) {
13716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      const VarDecl *vd = P.first;
13726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      const MappedType &V = P.second;
13739e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
1374e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer      UsesVec *vec = V.getPointer();
1375e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer      bool hasSelfInit = V.getInt();
13769e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
13779e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek      // Specially handle the case where we have uses of an uninitialized
13789e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek      // variable, but the root cause is an idiomatic self-init.  We want
13799e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek      // to report the diagnostic at the self-init since that is the root cause.
13800d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay      if (!vec->empty() && hasSelfInit && hasAlwaysUninitializedUse(vec))
13812815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith        DiagnoseUninitializedUse(S, vd,
13822815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith                                 UninitUse(vd->getInit()->IgnoreParenCasts(),
13832815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith                                           /* isAlwaysUninit */ true),
13840d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay                                 /* alwaysReportSelfInit */ true);
13859e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek      else {
13869e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek        // Sort the uses by their SourceLocations.  While not strictly
13879e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek        // guaranteed to produce them in line/column order, this will provide
13889e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek        // a stable ordering.
1389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        std::sort(vec->begin(), vec->end(),
1390651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                  [](const UninitUse &a, const UninitUse &b) {
1391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          // Prefer a more confident report over a less confident one.
1392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (a.getKind() != b.getKind())
1393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            return a.getKind() > b.getKind();
1394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          return a.getUser()->getLocStart() < b.getUser()->getLocStart();
1395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        });
1396651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
13976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        for (const auto &U : *vec) {
13982815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith          // If we have self-init, downgrade all uses to 'may be uninitialized'.
13996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          UninitUse Use = hasSelfInit ? UninitUse(U.getUser(), false) : U;
14002815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith
14012815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith          if (DiagnoseUninitializedUse(S, vd, Use))
14029e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek            // Skip further diagnostics for this variable. We try to warn only
14039e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek            // on the first point at which a variable is used uninitialized.
14049e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek            break;
14059e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek        }
140664fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth      }
14079e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek
14089e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek      // Release the uses vector.
140994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      delete vec;
141094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    }
141194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    delete uses;
1412610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek  }
14130d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay
14140d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gayprivate:
14150d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay  static bool hasAlwaysUninitializedUse(const UsesVec* vec) {
14166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return std::any_of(vec->begin(), vec->end(), [](const UninitUse &U) {
14176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return U.getKind() == UninitUse::Always ||
14186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines             U.getKind() == UninitUse::AfterCall ||
14196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines             U.getKind() == UninitUse::AfterDecl;
14206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    });
14210d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay  }
1422610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek};
1423610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}
1424610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek
142575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskinamespace clang {
1426df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace {
1427cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkotypedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes;
14282e5156274b8051217565b557bfa14c80f7990e9cRichard Smithtypedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;
1429ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramertypedef std::list<DelayedDiag> DiagList;
143075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
143175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskistruct SortDiagBySourceLocation {
1432ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer  SourceManager &SM;
1433ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer  SortDiagBySourceLocation(SourceManager &SM) : SM(SM) {}
143475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
143575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  bool operator()(const DelayedDiag &left, const DelayedDiag &right) {
143675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski    // Although this call will be slow, this is only called when outputting
143775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski    // multiple warnings.
1438ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer    return SM.isBeforeInTranslationUnit(left.first.first, right.first.first);
143975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
144075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski};
1441df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins}}
144275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1443df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===//
1444df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// -Wthread-safety
1445df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===//
1446df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace clang {
1447df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace thread_safety {
144899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikienamespace {
144975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskiclass ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {
145075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  Sema &S;
145175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  DiagList Warnings;
14522e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  SourceLocation FunLocation, FunEndLocation;
145375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
145475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  // Helper functions
1455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void warnLockMismatch(unsigned DiagID, StringRef Kind, Name LockName,
1456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        SourceLocation Loc) {
1457f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // Gracefully handle rare cases when the analysis can't get a more
1458f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // precise source location.
1459f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    if (!Loc.isValid())
1460f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins      Loc = FunLocation;
1461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName);
14622e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
146375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
146475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
146575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski public:
14662e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL)
14672e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    : S(S), FunLocation(FL), FunEndLocation(FEL) {}
146875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
146975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  /// \brief Emit all buffered diagnostics in order of sourcelocation.
147075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  /// We need to output diagnostics produced while iterating through
147175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  /// the lockset in deterministic order, so this function orders diagnostics
147275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  /// and outputs them.
147375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  void emitDiagnostics() {
1474ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer    Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));
14756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &Diag : Warnings) {
14766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      S.Diag(Diag.first.first, Diag.first.second);
14776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      for (const auto &Note : Diag.second)
14786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        S.Diag(Note.first, Note.second);
14792e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    }
148075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
148175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1482651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) override {
1483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_cannot_resolve_lock)
1484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                         << Loc);
14852e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
148699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  }
1487651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleUnmatchedUnlock(StringRef Kind, Name LockName,
1488651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             SourceLocation Loc) override {
1489651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    warnLockMismatch(diag::warn_unlock_but_no_lock, Kind, LockName, Loc);
149075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
1491651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
1492651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 LockKind Expected, LockKind Received,
1493651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 SourceLocation Loc) override {
1494651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (Loc.isInvalid())
1495651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Loc = FunLocation;
1496651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_kind_mismatch)
1497651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                         << Kind << LockName << Received
1498651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                         << Expected);
1499651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1500651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1501651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override {
1502651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    warnLockMismatch(diag::warn_double_lock, Kind, LockName, Loc);
150375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
150475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1505651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
1506651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 SourceLocation LocLocked,
15072e5156274b8051217565b557bfa14c80f7990e9cRichard Smith                                 SourceLocation LocEndOfScope,
1508651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 LockErrorKind LEK) override {
15094e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    unsigned DiagID = 0;
15104e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    switch (LEK) {
15114e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      case LEK_LockedSomePredecessors:
15122e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        DiagID = diag::warn_lock_some_predecessors;
15134e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski        break;
15144e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      case LEK_LockedSomeLoopIterations:
15154e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski        DiagID = diag::warn_expecting_lock_held_on_loop;
15164e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski        break;
15174e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      case LEK_LockedAtEndOfFunction:
15184e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski        DiagID = diag::warn_no_unlock;
15194e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski        break;
1520879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins      case LEK_NotLockedAtEndOfFunction:
1521879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins        DiagID = diag::warn_expecting_locked;
1522879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins        break;
15234e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    }
15242e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    if (LocEndOfScope.isInvalid())
15252e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      LocEndOfScope = FunEndLocation;
15262e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
1527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << Kind
1528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                               << LockName);
15295696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    if (LocLocked.isValid()) {
1530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here)
1531651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                              << Kind);
15325696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins      Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
15335696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins      return;
15345696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    }
15355696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
153675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
153775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleExclusiveAndShared(StringRef Kind, Name LockName,
1539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                SourceLocation Loc1,
1540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                SourceLocation Loc2) override {
1541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(Loc1,
1542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                S.PDiag(diag::warn_lock_exclusive_and_shared)
1543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    << Kind << LockName);
1544651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Note(Loc2, S.PDiag(diag::note_lock_exclusive_and_shared)
1545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                       << Kind << LockName);
15462e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
154775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
154875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
1550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         ProtectedOperationKind POK, AccessKind AK,
1551651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         SourceLocation Loc) override {
1552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert((POK == POK_VarAccess || POK == POK_VarDereference) &&
1553651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           "Only works for variables");
1554df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski    unsigned DiagID = POK == POK_VarAccess?
1555df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski                        diag::warn_variable_requires_any_lock:
1556df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski                        diag::warn_var_deref_requires_any_lock;
15572e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
15585b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins      << D->getNameAsString() << getLockKindFromAccessKind(AK));
15592e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
156075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
156175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
1563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          ProtectedOperationKind POK, Name LockName,
1564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          LockKind LK, SourceLocation Loc,
1565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          Name *PossibleMatch) override {
1566e87158dfbca01577810f301543c3cdcfc955d8b0Caitlin Sadowski    unsigned DiagID = 0;
15673f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    if (PossibleMatch) {
15683f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      switch (POK) {
15693f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_VarAccess:
15703f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_variable_requires_lock_precise;
15713f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
15723f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_VarDereference:
15733f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_var_deref_requires_lock_precise;
15743f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
15753f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_FunctionCall:
15763f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_fun_requires_lock_precise;
15773f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
15783f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      }
1579651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
1580651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                       << D->getNameAsString()
1581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                       << LockName << LK);
15823f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match)
1583651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        << *PossibleMatch);
15843f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
15853f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    } else {
15863f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      switch (POK) {
15873f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_VarAccess:
15883f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_variable_requires_lock;
15893f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
15903f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_VarDereference:
15913f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_var_deref_requires_lock;
15923f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
15933f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        case POK_FunctionCall:
15943f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          DiagID = diag::warn_fun_requires_lock;
15953f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins          break;
15963f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      }
1597651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
1598651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                       << D->getNameAsString()
1599651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                       << LockName << LK);
16003f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins      Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
160175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski    }
160275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
160375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1604651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void handleFunExcludesLock(StringRef Kind, Name FunName, Name LockName,
1605651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             SourceLocation Loc) override {
1606651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_fun_excludes_mutex)
1607651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                         << Kind << FunName << LockName);
16082e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
160975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
161075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski};
161175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski}
161275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski}
161399ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie}
161475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
1615610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===//
1616df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// -Wconsumed
1617df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===//
1618df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1619df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace clang {
1620df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace consumed {
1621df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace {
1622df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsclass ConsumedWarningsHandler : public ConsumedWarningsHandlerBase {
1623df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1624df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  Sema &S;
1625df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  DiagList Warnings;
1626df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1627df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinspublic:
1628df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1629df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  ConsumedWarningsHandler(Sema &S) : S(S) {}
1630651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1631651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void emitDiagnostics() override {
1632df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));
16336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &Diag : Warnings) {
16346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      S.Diag(Diag.first.first, Diag.first.second);
16356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      for (const auto &Note : Diag.second)
16366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        S.Diag(Note.first, Note.second);
1637df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    }
1638df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  }
1639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1640651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void warnLoopStateMismatch(SourceLocation Loc,
1641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             StringRef VariableName) override {
16427385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch) <<
16437385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins      VariableName);
16447385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins
16457385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
16467385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins  }
16477385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins
1648cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins  void warnParamReturnTypestateMismatch(SourceLocation Loc,
1649cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins                                        StringRef VariableName,
1650cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins                                        StringRef ExpectedState,
1651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        StringRef ObservedState) override {
1652cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins
1653cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(
1654cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins      diag::warn_param_return_typestate_mismatch) << VariableName <<
1655cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins        ExpectedState << ObservedState);
1656cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins
1657cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1658cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins  }
1659cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins
1660d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins  void warnParamTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
1661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                  StringRef ObservedState) override {
1662d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins
1663d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(
1664d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins      diag::warn_param_typestate_mismatch) << ExpectedState << ObservedState);
1665d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins
1666d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1667d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins  }
1668d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins
16690e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins  void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
1670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                              StringRef TypeName) override {
16710e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(
16720e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins      diag::warn_return_typestate_for_unconsumable_type) << TypeName);
16730e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins
16740e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
16750e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins  }
16760e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins
16770e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins  void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
1678651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   StringRef ObservedState) override {
16790e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins
16800e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(
16810e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins      diag::warn_return_typestate_mismatch) << ExpectedState << ObservedState);
16820e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins
16830e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
16840e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins  }
16850e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins
168666540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins  void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State,
1687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   SourceLocation Loc) override {
1688df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1689df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(
169066540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins      diag::warn_use_of_temp_in_invalid_state) << MethodName << State);
1691df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1692df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1693df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  }
1694df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
169566540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins  void warnUseInInvalidState(StringRef MethodName, StringRef VariableName,
1696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             StringRef State, SourceLocation Loc) override {
1697df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
169866540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state) <<
169966540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins                                MethodName << VariableName << State);
1700df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1701df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1702df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  }
1703df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins};
1704df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins}}}
1705df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1706df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===//
1707dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based
1708dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//  warnings on a function, method, or block.
1709dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
1710dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
1711d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekclang::sema::AnalysisBasedWarnings::Policy::Policy() {
1712dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  enableCheckFallThrough = 1;
1713d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  enableCheckUnreachable = 0;
17143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  enableThreadSafetyAnalysis = 0;
1715df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  enableConsumedAnalysis = 0;
1716d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek}
1717dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
1718651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic unsigned isEnabled(DiagnosticsEngine &D, unsigned diag) {
1719ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return (unsigned)!D.isIgnored(diag, SourceLocation());
1720651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
1721651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
17225d98994c7749312a43ce6adf45537979a98e7afdChandler Carruthclang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
17235d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  : S(s),
17245d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    NumFunctionsAnalyzed(0),
172554cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumFunctionsWithBadCFGs(0),
17265d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    NumCFGBlocks(0),
172754cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    MaxCFGBlocksPerFunction(0),
172854cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumUninitAnalysisFunctions(0),
172954cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumUninitAnalysisVariables(0),
173054cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    MaxUninitAnalysisVariablesPerFunction(0),
173154cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumUninitAnalysisBlockVisits(0),
173254cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    MaxUninitAnalysisBlockVisitsPerFunction(0) {
1733651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1734651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  using namespace diag;
1735d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &D = S.getDiagnostics();
1736651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1737651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  DefaultPolicy.enableCheckUnreachable =
1738651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_unreachable) ||
1739651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_unreachable_break) ||
1740651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_unreachable_return) ||
1741651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_unreachable_loop_increment);
1742651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1743651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  DefaultPolicy.enableThreadSafetyAnalysis =
1744651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_double_lock);
1745651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1746651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  DefaultPolicy.enableConsumedAnalysis =
1747651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    isEnabled(D, warn_use_in_invalid_state);
1748dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
1749dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
17506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstatic void flushDiagnostics(Sema &S, const sema::FunctionScopeInfo *fscope) {
17516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  for (const auto &D : fscope->PossiblyUnreachableDiags)
1752351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    S.Diag(D.Loc, D.PD);
1753351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek}
1754351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
1755d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekvoid clang::sema::
1756d064fdc4b7b64ca55b40b70490c79d6f569df78eTed KremenekAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
1757283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek                                     sema::FunctionScopeInfo *fscope,
17583ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek                                     const Decl *D, const BlockExpr *blkExpr) {
1759d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek
1760dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // We avoid doing analysis-based warnings when there are errors for
1761dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // two reasons:
1762dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // (1) The CFGs often can't be constructed (if the body is invalid), so
1763dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  //     don't bother trying.
1764dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // (2) The code already has problems; running the analysis just takes more
1765dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  //     time.
1766d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &Diags = S.getDiagnostics();
176799e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek
1768d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  // Do not do any analysis for declarations in system headers if we are
1769d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  // going to just ignore them.
177099e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek  if (Diags.getSuppressSystemWarnings() &&
1771d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek      S.SourceMgr.isInSystemHeader(D->getLocation()))
1772d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek    return;
1773d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
1774e0054f61fd84133eb0d19c19ae9afaf117933274John McCall  // For code in dependent contexts, we'll do this at instantiation time.
177523661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie  if (cast<DeclContext>(D)->isDependentContext())
177623661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie    return;
1777dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
177812f37e411462b8388eb1309357bd62257debacacDeLesley Hutchins  if (Diags.hasUncompilableErrorOccurred() || Diags.hasFatalErrorOccurred()) {
1779351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    // Flush out any possibly unreachable diagnostics.
1780351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    flushDiagnostics(S, fscope);
1781351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    return;
1782351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  }
1783351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
1784dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  const Stmt *Body = D->getBody();
1785dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  assert(Body);
1786dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
17870cd72319e74899c4e5561cc70b7c4939d3767bd9Ted Kremenek  // Construct the analysis context with the specified CFG build options.
17886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  AnalysisDeclContext AC(/* AnalysisDeclContextManager */ nullptr, D);
1789bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek
1790dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
1791e575359c34a9248c55ec0c03a8fc945f1ee4cb01Benjamin Kramer  // explosion for destructors that can result and the compile time hit.
1792bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true;
1793bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  AC.getCFGBuildOptions().AddEHEdges = false;
1794bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  AC.getCFGBuildOptions().AddInitializers = true;
1795bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  AC.getCFGBuildOptions().AddImplicitDtors = true;
1796faadf48443f8c2fc53d267485d7e0e1bd382fc75Jordan Rose  AC.getCFGBuildOptions().AddTemporaryDtors = true;
1797651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  AC.getCFGBuildOptions().AddCXXNewAllocator = false;
1798faadf48443f8c2fc53d267485d7e0e1bd382fc75Jordan Rose
17990c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // Force that certain expressions appear as CFGElements in the CFG.  This
18000c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // is used to speed up various analyses.
18010c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // FIXME: This isn't the right factoring.  This is here for initial
18020c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // prototyping, but we need a way for analyses to say what expressions they
18030c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // expect to always be CFGElements and then fill in the BuildOptions
18040c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek  // appropriately.  This is essentially a layering violation.
1805df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis ||
1806df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins      P.enableConsumedAnalysis) {
18071fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    // Unreachable code analysis and thread safety require a linearized CFG.
18080f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek    AC.getCFGBuildOptions().setAllAlwaysAdd();
18090f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek  }
18100f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek  else {
18110f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek    AC.getCFGBuildOptions()
18120f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek      .setAlwaysAdd(Stmt::BinaryOperatorClass)
18136cfa78f6bd4e7d5e23366a0907f8f8792366bc4cRichard Smith      .setAlwaysAdd(Stmt::CompoundAssignOperatorClass)
18140f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek      .setAlwaysAdd(Stmt::BlockExprClass)
18150f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek      .setAlwaysAdd(Stmt::CStyleCastExprClass)
18160f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek      .setAlwaysAdd(Stmt::DeclRefExprClass)
18170f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek      .setAlwaysAdd(Stmt::ImplicitCastExprClass)
1818e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      .setAlwaysAdd(Stmt::UnaryOperatorClass)
1819e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      .setAlwaysAdd(Stmt::AttributedStmtClass);
18200f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek  }
1821bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek
18226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // Install the logical handler for -Wtautological-overlap-compare
18236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  std::unique_ptr<LogicalErrorHandler> LEH;
1824ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
1825ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                       D->getLocStart())) {
18266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    LEH.reset(new LogicalErrorHandler(S));
18276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AC.getCFGBuildOptions().Observer = LEH.get();
18286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
18290cd72319e74899c4e5561cc70b7c4939d3767bd9Ted Kremenek
1830351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  // Emit delayed diagnostics.
183123661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie  if (!fscope->PossiblyUnreachableDiags.empty()) {
1832351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    bool analyzed = false;
18330d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
18340d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    // Register the expressions with the CFGBuilder.
18356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto &D : fscope->PossiblyUnreachableDiags) {
18366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (D.stmt)
18376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        AC.registerForcedBlockExpression(D.stmt);
18380d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    }
18390d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
18400d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    if (AC.getCFG()) {
18410d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek      analyzed = true;
18426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      for (const auto &D : fscope->PossiblyUnreachableDiags) {
18430d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        bool processed = false;
18446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        if (D.stmt) {
18456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          const CFGBlock *block = AC.getBlockForRegisteredExpression(D.stmt);
184671b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman          CFGReverseBlockReachabilityAnalysis *cra =
184771b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman              AC.getCFGReachablityAnalysis();
184871b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman          // FIXME: We should be able to assert that block is non-null, but
184971b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman          // the CFG analysis can skip potentially-evaluated expressions in
185071b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman          // edge cases; see test/Sema/vla-2.c.
185171b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman          if (block && cra) {
1852351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek            // Can this block be reached from the entrance?
18530d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek            if (cra->isReachable(&AC.getCFG()->getEntry(), block))
1854351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek              S.Diag(D.Loc, D.PD);
18550d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek            processed = true;
1856351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek          }
18570d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        }
18580d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        if (!processed) {
18590d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek          // Emit the warning anyway if we cannot map to a basic block.
18600d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek          S.Diag(D.Loc, D.PD);
1861351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek        }
1862351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek      }
18630d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    }
1864351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
1865351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    if (!analyzed)
1866351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek      flushDiagnostics(S, fscope);
1867351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  }
1868351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
1869351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
1870dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Warning: check missing 'return'
187123661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie  if (P.enableCheckFallThrough) {
1872dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    const CheckFallThroughDiagnostics &CD =
1873dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
1874793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor       : (isa<CXXMethodDecl>(D) &&
1875793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor          cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call &&
1876793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor          cast<CXXMethodDecl>(D)->getParent()->isLambda())
1877793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor            ? CheckFallThroughDiagnostics::MakeForLambda()
1878793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor            : CheckFallThroughDiagnostics::MakeForFunction(D));
18793ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek    CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC);
1880dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
1881dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
1882dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Warning: check for unreachable code
18835dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek  if (P.enableCheckUnreachable) {
18845dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek    // Only check for unreachable code on non-template instantiations.
18855dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek    // Different template instantiations can effectively change the control-flow
18865dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek    // and it is very difficult to prove that a snippet of code in a template
18875dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek    // is unreachable for all instantiations.
188875df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek    bool isTemplateInstantiation = false;
188975df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
189075df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek      isTemplateInstantiation = Function->isTemplateInstantiation();
189175df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek    if (!isTemplateInstantiation)
18925dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek      CheckUnreachable(S, AC);
18935dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek  }
189475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski
18953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // Check for thread safety violations
189623661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie  if (P.enableThreadSafetyAnalysis) {
1897f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    SourceLocation FL = AC.getDecl()->getLocation();
18982e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    SourceLocation FEL = AC.getDecl()->getLocEnd();
18992e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    thread_safety::ThreadSafetyReporter Reporter(S, FL, FEL);
1900ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if (!Diags.isIgnored(diag::warn_thread_safety_beta, D->getLocStart()))
1901fb4afc2fc659faff43a6df4c1d0e07df9c90479dDeLesley Hutchins      Reporter.setIssueBetaWarnings(true);
1902fb4afc2fc659faff43a6df4c1d0e07df9c90479dDeLesley Hutchins
190375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski    thread_safety::runThreadSafetyAnalysis(AC, Reporter);
190475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski    Reporter.emitDiagnostics();
190575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski  }
19063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1907df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  // Check for violations of consumed properties.
1908df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  if (P.enableConsumedAnalysis) {
1909df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    consumed::ConsumedWarningsHandler WarningHandler(S);
19102d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner    consumed::ConsumedAnalyzer Analyzer(WarningHandler);
1911df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins    Analyzer.run(AC);
1912df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins  }
1913df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins
1914ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (!Diags.isIgnored(diag::warn_uninit_var, D->getLocStart()) ||
1915ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      !Diags.isIgnored(diag::warn_sometimes_uninit_var, D->getLocStart()) ||
1916ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      !Diags.isIgnored(diag::warn_maybe_uninit_var, D->getLocStart())) {
1917c5e43c19ddb40b8a1371291f73ae66fe54951ca5Ted Kremenek    if (CFG *cfg = AC.getCFG()) {
1918c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek      UninitValsDiagReporter reporter(S);
191957080fbac1ccce702255423335d52e81bcf17b6bFariborz Jahanian      UninitVariablesAnalysisStats stats;
192012efd57ee474c06880a7434ece21a39ac3f34e24Benjamin Kramer      std::memset(&stats, 0, sizeof(UninitVariablesAnalysisStats));
1921a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek      runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC,
19225d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth                                        reporter, stats);
19235d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
19245d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      if (S.CollectStats && stats.NumVariablesAnalyzed > 0) {
19255d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        ++NumUninitAnalysisFunctions;
19265d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        NumUninitAnalysisVariables += stats.NumVariablesAnalyzed;
19275d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        NumUninitAnalysisBlockVisits += stats.NumBlockVisits;
19285d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        MaxUninitAnalysisVariablesPerFunction =
19295d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth            std::max(MaxUninitAnalysisVariablesPerFunction,
19305d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth                     stats.NumVariablesAnalyzed);
19315d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        MaxUninitAnalysisBlockVisitsPerFunction =
19325d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth            std::max(MaxUninitAnalysisBlockVisitsPerFunction,
19335d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth                     stats.NumBlockVisits);
19345d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      }
19355d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    }
19365d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  }
19375d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
19381973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko  bool FallThroughDiagFull =
1939ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      !Diags.isIgnored(diag::warn_unannotated_fallthrough, D->getLocStart());
1940ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  bool FallThroughDiagPerFunction = !Diags.isIgnored(
1941ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      diag::warn_unannotated_fallthrough_per_function, D->getLocStart());
1942c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt  if (FallThroughDiagFull || FallThroughDiagPerFunction) {
19431973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko    DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull);
1944e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith  }
1945e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith
194658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  if (S.getLangOpts().ObjCARCWeak &&
1947ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, D->getLocStart()))
1948b5cd1220dd650a358622241237aa595c5d675506Jordan Rose    diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap());
194958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
1950651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1951651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Check for infinite self-recursion in functions
1952ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (!Diags.isIgnored(diag::warn_infinite_recursive_function,
1953ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                       D->getLocStart())) {
1954651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1955651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      checkRecursiveFunction(S, FD, Body, AC);
1956651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
1957651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1958651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
19596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // If none of the previous checks caused a CFG build, trigger one here
19606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // for -Wtautological-overlap-compare
1961ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
19626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                               D->getLocStart())) {
19636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AC.getCFG();
19646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
19656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
19665d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  // Collect statistics about the CFG if it was built.
19675d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  if (S.CollectStats && AC.isCFGBuilt()) {
19685d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    ++NumFunctionsAnalyzed;
19695d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    if (CFG *cfg = AC.getCFG()) {
19705d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      // If we successfully built a CFG for this context, record some more
19715d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      // detail information about it.
19723ea4c49709c5bba5f8b16c6ceb725d9b9a1c48c6Chandler Carruth      NumCFGBlocks += cfg->getNumBlockIDs();
19735d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction,
19743ea4c49709c5bba5f8b16c6ceb725d9b9a1c48c6Chandler Carruth                                         cfg->getNumBlockIDs());
19755d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    } else {
19765d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      ++NumFunctionsWithBadCFGs;
1977610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek    }
1978610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek  }
1979dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
19805d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
19815d98994c7749312a43ce6adf45537979a98e7afdChandler Carruthvoid clang::sema::AnalysisBasedWarnings::PrintStats() const {
19825d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  llvm::errs() << "\n*** Analysis Based Warnings Stats:\n";
19835d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
19845d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs;
19855d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned AvgCFGBlocksPerFunction =
19865d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt;
19875d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  llvm::errs() << NumFunctionsAnalyzed << " functions analyzed ("
19885d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << NumFunctionsWithBadCFGs << " w/o CFGs).\n"
19895d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << NumCFGBlocks << " CFG blocks built.\n"
19905d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << AvgCFGBlocksPerFunction
19915d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " average CFG blocks per function.\n"
19925d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << MaxCFGBlocksPerFunction
19935d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " max CFG blocks per function.\n";
19945d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
19955d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0
19965d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      : NumUninitAnalysisVariables/NumUninitAnalysisFunctions;
19975d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0
19985d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions;
19995d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  llvm::errs() << NumUninitAnalysisFunctions
20005d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " functions analyzed for uninitialiazed variables\n"
20015d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << NumUninitAnalysisVariables << " variables analyzed.\n"
20025d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << AvgUninitVariablesPerFunction
20035d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " average variables per function.\n"
20045d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << MaxUninitAnalysisVariablesPerFunction
20055d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " max variables per function.\n"
20065d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << NumUninitAnalysisBlockVisits << " block visits.\n"
20075d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << AvgUninitBlockVisitsPerFunction
20085d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " average block visits per function.\n"
20095d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << MaxUninitAnalysisBlockVisitsPerFunction
20105d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " max block visits per function.\n";
20115d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth}
2012