AnalysisBasedWarnings.cpp revision 57080fbac1ccce702255423335d52e81bcf17b6b
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"
172d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h"
18351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Sema/ScopeInfo.h"
19d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek#include "clang/Basic/SourceManager.h"
20fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek#include "clang/Lex/Preprocessor.h"
217cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCall#include "clang/AST/DeclObjC.h"
22384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h"
23dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/ExprObjC.h"
24dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/ExprCXX.h"
25dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/StmtObjC.h"
26dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/StmtCXX.h"
276f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek#include "clang/AST/EvaluatedExprVisitor.h"
28dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/AnalysisContext.h"
29dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/CFG.h"
30dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/Analyses/ReachableCode.h"
31351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
32351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Analysis/CFGStmtMap.h"
336f34213f8d6ae8c77685b53664527e39bfaaca3bTed Kremenek#include "clang/Analysis/Analyses/UninitializedValues.h"
34dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/ADT/BitVector.h"
35dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/Support/Casting.h"
36dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
37dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekusing namespace clang;
38dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
39dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
40dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Unreachable code analysis.
41dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
42dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
43dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremeneknamespace {
44dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  class UnreachableCodeHandler : public reachable_code::Callback {
45dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    Sema &S;
46dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  public:
47dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    UnreachableCodeHandler(Sema &s) : S(s) {}
48dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
49dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) {
50dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      S.Diag(L, diag::warn_unreachable) << R1 << R2;
51dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
52dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  };
53dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
54dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
55dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckUnreachable - Check for unreachable code.
56dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckUnreachable(Sema &S, AnalysisContext &AC) {
57dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  UnreachableCodeHandler UC(S);
58dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  reachable_code::FindUnreachableCode(AC, UC);
59dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
60dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
61dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
62dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Check for missing return value.
63dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
64dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
6516565aa95b086fb239baf82335dccc1b1ec93942John McCallenum ControlFlowKind {
6616565aa95b086fb239baf82335dccc1b1ec93942John McCall  UnknownFallThrough,
6716565aa95b086fb239baf82335dccc1b1ec93942John McCall  NeverFallThrough,
6816565aa95b086fb239baf82335dccc1b1ec93942John McCall  MaybeFallThrough,
6916565aa95b086fb239baf82335dccc1b1ec93942John McCall  AlwaysFallThrough,
7016565aa95b086fb239baf82335dccc1b1ec93942John McCall  NeverFallThroughOrReturn
7116565aa95b086fb239baf82335dccc1b1ec93942John McCall};
72dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
73dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThrough - Check that we don't fall off the end of a
74dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// Statement that should return a value.
75dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek///
76dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// \returns AlwaysFallThrough iff we always fall off the end of the statement,
77dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// MaybeFallThrough iff we might or might not fall off the end,
78dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// NeverFallThroughOrReturn iff we never fall off the end of the statement or
79dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// return.  We assume NeverFallThrough iff we never fall off the end of the
80dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// statement but we may return.  We assume that functions not marked noreturn
81dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// will return.
82dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic ControlFlowKind CheckFallThrough(AnalysisContext &AC) {
83dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  CFG *cfg = AC.getCFG();
8416565aa95b086fb239baf82335dccc1b1ec93942John McCall  if (cfg == 0) return UnknownFallThrough;
85dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
86dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // The CFG leaves in dead things, and we don't want the dead code paths to
87dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // confuse us, so we mark all live things first.
88dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  llvm::BitVector live(cfg->getNumBlockIDs());
89dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned count = reachable_code::ScanReachableFromBlock(cfg->getEntry(),
90dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                                          live);
91dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
92dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool AddEHEdges = AC.getAddEHEdges();
93dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (!AddEHEdges && count != cfg->getNumBlockIDs())
94dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // When there are things remaining dead, and we didn't add EH edges
95dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // from CallExprs to the catch clauses, we have to go back and
96dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // mark them as live.
97dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
98dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      CFGBlock &b = **I;
99dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (!live[b.getBlockID()]) {
100dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        if (b.pred_begin() == b.pred_end()) {
101dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator()))
102dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek            // When not adding EH edges from calls, catch clauses
103dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek            // can otherwise seem dead.  Avoid noting them as dead.
104dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek            count += reachable_code::ScanReachableFromBlock(b, live);
105dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          continue;
106dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        }
107dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
108dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
109dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
110dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Now we know what is live, we check the live precessors of the exit block
111dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // and look for fall through paths, being careful to ignore normal returns,
112dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // and exceptional paths.
113dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasLiveReturn = false;
114dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasFakeEdge = false;
115dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasPlainEdge = false;
116dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasAbnormalEdge = false;
11790b828aa279542559f655d1af666580288cb1841Ted Kremenek
11890b828aa279542559f655d1af666580288cb1841Ted Kremenek  // Ignore default cases that aren't likely to be reachable because all
11990b828aa279542559f655d1af666580288cb1841Ted Kremenek  // enums in a switch(X) have explicit case statements.
12090b828aa279542559f655d1af666580288cb1841Ted Kremenek  CFGBlock::FilterOptions FO;
12190b828aa279542559f655d1af666580288cb1841Ted Kremenek  FO.IgnoreDefaultsWithCoveredEnums = 1;
12290b828aa279542559f655d1af666580288cb1841Ted Kremenek
12390b828aa279542559f655d1af666580288cb1841Ted Kremenek  for (CFGBlock::filtered_pred_iterator
12490b828aa279542559f655d1af666580288cb1841Ted Kremenek	 I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) {
12590b828aa279542559f655d1af666580288cb1841Ted Kremenek    const CFGBlock& B = **I;
126dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (!live[B.getBlockID()])
127dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
1285811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek
1295811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // Destructors can appear after the 'return' in the CFG.  This is
1305811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // normal.  We need to look pass the destructors for the return
1315811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // statement (if it exists).
1325811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend();
133c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    bool hasNoReturnDtor = false;
134c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek
1355811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    for ( ; ri != re ; ++ri) {
1365811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek      CFGElement CE = *ri;
137c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek
138c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      // FIXME: The right solution is to just sever the edges in the
139c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      // CFG itself.
140c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      if (const CFGImplicitDtor *iDtor = ri->getAs<CFGImplicitDtor>())
141c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenek        if (iDtor->isNoReturn(AC.getASTContext())) {
142c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek          hasNoReturnDtor = true;
143c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek          HasFakeEdge = true;
144c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek          break;
145c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek        }
146c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek
1475811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek      if (isa<CFGStmt>(CE))
1485811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek        break;
1495811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    }
1505811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek
151c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    if (hasNoReturnDtor)
152c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      continue;
153c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek
1545811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    // No more CFGElements in the block?
1555811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    if (ri == re) {
156dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) {
157dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasAbnormalEdge = true;
158dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        continue;
159dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
160dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      // A labeled empty statement, or the entry block...
161dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasPlainEdge = true;
162dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
163dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
164f39e6a388aaa2f155b46c61e655784b2473218ebTed Kremenek
1655811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek    CFGStmt CS = cast<CFGStmt>(*ri);
166b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu    Stmt *S = CS.getStmt();
167dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<ReturnStmt>(S)) {
168dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasLiveReturn = true;
169dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
170dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
171dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<ObjCAtThrowStmt>(S)) {
172dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasFakeEdge = true;
173dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
174dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
175dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<CXXThrowExpr>(S)) {
176dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasFakeEdge = true;
177dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
178dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
179dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) {
180dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (AS->isMSAsm()) {
181dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasFakeEdge = true;
182dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasLiveReturn = true;
183dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        continue;
184dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
185dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
186dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<CXXTryStmt>(S)) {
187dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasAbnormalEdge = true;
188dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
189dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
190dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
191dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    bool NoReturnEdge = false;
192dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (CallExpr *C = dyn_cast<CallExpr>(S)) {
193259d48e1486044093131c8c078f70a28b1503e70John McCall      if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit())
194259d48e1486044093131c8c078f70a28b1503e70John McCall            == B.succ_end()) {
195dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasAbnormalEdge = true;
196dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        continue;
197dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
198dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      Expr *CEE = C->getCallee()->IgnoreParenCasts();
1991de85338543dd6228eb518185e385d94d377f4cbJohn McCall      QualType calleeType = CEE->getType();
2001de85338543dd6228eb518185e385d94d377f4cbJohn McCall      if (calleeType == AC.getASTContext().BoundMemberTy) {
2011de85338543dd6228eb518185e385d94d377f4cbJohn McCall        calleeType = Expr::findBoundMemberType(CEE);
2021de85338543dd6228eb518185e385d94d377f4cbJohn McCall        assert(!calleeType.isNull() && "analyzing unresolved call?");
2031de85338543dd6228eb518185e385d94d377f4cbJohn McCall      }
2041de85338543dd6228eb518185e385d94d377f4cbJohn McCall      if (getFunctionExtInfo(calleeType).getNoReturn()) {
205dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        NoReturnEdge = true;
206dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasFakeEdge = true;
207dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
208dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        ValueDecl *VD = DRE->getDecl();
209dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        if (VD->hasAttr<NoReturnAttr>()) {
210dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          NoReturnEdge = true;
211dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          HasFakeEdge = true;
212dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        }
213dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
214dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
215dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // FIXME: Add noreturn message sends.
216dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (NoReturnEdge == false)
217dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasPlainEdge = true;
218dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
219dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (!HasPlainEdge) {
220dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (HasLiveReturn)
221dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      return NeverFallThrough;
222dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return NeverFallThroughOrReturn;
223dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
224dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn)
225dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return MaybeFallThrough;
226dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // This says AlwaysFallThrough for calls to functions that are not marked
227dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // noreturn, that don't return.  If people would like this warning to be more
228dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // accurate, such functions should be marked as noreturn.
229dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  return AlwaysFallThrough;
230dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
231dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
2323c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohmannamespace {
2333c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman
234dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstruct CheckFallThroughDiagnostics {
235dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_MaybeFallThrough_HasNoReturn;
236dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_MaybeFallThrough_ReturnsNonVoid;
237dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_AlwaysFallThrough_HasNoReturn;
238dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
239dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_NeverFallThroughOrReturn;
240dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool funMode;
2410827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis  SourceLocation FuncLoc;
242d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
243ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor  static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
244dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CheckFallThroughDiagnostics D;
2450827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    D.FuncLoc = Func->getLocation();
246dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_HasNoReturn =
247dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_noreturn_function;
248dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_ReturnsNonVoid =
249dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_maybe_falloff_nonvoid_function;
250dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_HasNoReturn =
251dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_noreturn_function;
252dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_ReturnsNonVoid =
253dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_nonvoid_function;
254ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor
255ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    // Don't suggest that virtual functions be marked "noreturn", since they
256ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    // might be overridden by non-noreturn functions.
257ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    bool isVirtualMethod = false;
258ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func))
259ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor      isVirtualMethod = Method->isVirtual();
260ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor
261ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    if (!isVirtualMethod)
262ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor      D.diag_NeverFallThroughOrReturn =
263ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor        diag::warn_suggest_noreturn_function;
264ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor    else
265ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor      D.diag_NeverFallThroughOrReturn = 0;
266ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor
267dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.funMode = true;
268dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return D;
269dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
270d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
271dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  static CheckFallThroughDiagnostics MakeForBlock() {
272dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CheckFallThroughDiagnostics D;
273dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_HasNoReturn =
274dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_noreturn_block_has_return_expr;
275dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_ReturnsNonVoid =
276dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_maybe_falloff_nonvoid_block;
277dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_HasNoReturn =
278dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_noreturn_block_has_return_expr;
279dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_ReturnsNonVoid =
280dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_falloff_nonvoid_block;
281dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_NeverFallThroughOrReturn =
282dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_suggest_noreturn_block;
283dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.funMode = false;
284dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return D;
285dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
286d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
287dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool checkDiagnostics(Diagnostic &D, bool ReturnsVoid,
288dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                        bool HasNoReturn) const {
289dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (funMode) {
2900827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      return (ReturnsVoid ||
2910827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis              D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function,
2920827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                                   FuncLoc) == Diagnostic::Ignored)
2930827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis        && (!HasNoReturn ||
2940827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis            D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr,
2950827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                                 FuncLoc) == Diagnostic::Ignored)
2960827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis        && (!ReturnsVoid ||
2970827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis            D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
2980827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis              == Diagnostic::Ignored);
299dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
300d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
301dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // For blocks.
302dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return  ReturnsVoid && !HasNoReturn
3030827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis            && (!ReturnsVoid ||
3040827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
3050827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                  == Diagnostic::Ignored);
306dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
307dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek};
308dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
3093c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman}
3103c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman
311dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
312dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// function that should return a value.  Check that we don't fall off the end
313dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// of a noreturn function.  We assume that functions and blocks not marked
314dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// noreturn will return.
315dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
3163ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek                                    const BlockExpr *blkExpr,
317dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                    const CheckFallThroughDiagnostics& CD,
318dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                    AnalysisContext &AC) {
319dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
320dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool ReturnsVoid = false;
321dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasNoReturn = false;
322dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
323dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
324dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    ReturnsVoid = FD->getResultType()->isVoidType();
325dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    HasNoReturn = FD->hasAttr<NoReturnAttr>() ||
326264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola       FD->getType()->getAs<FunctionType>()->getNoReturnAttr();
327dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
328dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
329dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    ReturnsVoid = MD->getResultType()->isVoidType();
330dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    HasNoReturn = MD->hasAttr<NoReturnAttr>();
331dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
332dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  else if (isa<BlockDecl>(D)) {
3333ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek    QualType BlockTy = blkExpr->getType();
334d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek    if (const FunctionType *FT =
335dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          BlockTy->getPointeeType()->getAs<FunctionType>()) {
336dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (FT->getResultType()->isVoidType())
337dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        ReturnsVoid = true;
338dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (FT->getNoReturnAttr())
339dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasNoReturn = true;
340dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
341dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
342dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
343dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  Diagnostic &Diags = S.getDiagnostics();
344dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
345dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Short circuit for compilation speed.
346dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
347dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      return;
348d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
349dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // FIXME: Function try block
350dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) {
351dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    switch (CheckFallThrough(AC)) {
35216565aa95b086fb239baf82335dccc1b1ec93942John McCall      case UnknownFallThrough:
35316565aa95b086fb239baf82335dccc1b1ec93942John McCall        break;
35416565aa95b086fb239baf82335dccc1b1ec93942John McCall
355dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case MaybeFallThrough:
356dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        if (HasNoReturn)
357dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
358dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_MaybeFallThrough_HasNoReturn);
359dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        else if (!ReturnsVoid)
360dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
361dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_MaybeFallThrough_ReturnsNonVoid);
362dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
363dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case AlwaysFallThrough:
364dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        if (HasNoReturn)
365dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
366dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_AlwaysFallThrough_HasNoReturn);
367dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        else if (!ReturnsVoid)
368dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
369dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_AlwaysFallThrough_ReturnsNonVoid);
370dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
371dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case NeverFallThroughOrReturn:
372ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor        if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn)
373dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getLBracLoc(),
374dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_NeverFallThroughOrReturn);
375dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
376dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case NeverFallThrough:
377dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
378dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
379dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
380dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
381dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
382dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
383610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// -Wuninitialized
384610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===//
385610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek
3866f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremeneknamespace {
3879f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// ContainsReference - A visitor class to search for references to
3889f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// a particular declaration (the needle) within any evaluated component of an
3899f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// expression (recursively).
3906f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenekclass ContainsReference : public EvaluatedExprVisitor<ContainsReference> {
3919f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  bool FoundReference;
3929f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  const DeclRefExpr *Needle;
3939f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
3946f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenekpublic:
3959f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  ContainsReference(ASTContext &Context, const DeclRefExpr *Needle)
3969f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    : EvaluatedExprVisitor<ContainsReference>(Context),
3979f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth      FoundReference(false), Needle(Needle) {}
3989f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
3999f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  void VisitExpr(Expr *E) {
4006f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek    // Stop evaluating if we already have a reference.
4019f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    if (FoundReference)
4026f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek      return;
4039f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
4049f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    EvaluatedExprVisitor<ContainsReference>::VisitExpr(E);
4056f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek  }
4069f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
4079f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  void VisitDeclRefExpr(DeclRefExpr *E) {
4089f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    if (E == Needle)
4099f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth      FoundReference = true;
4109f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth    else
4119f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth      EvaluatedExprVisitor<ContainsReference>::VisitDeclRefExpr(E);
4126f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek  }
4139f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth
4149f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth  bool doesContainReference() const { return FoundReference; }
4156f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek};
4166f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek}
4176f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek
418262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an
419262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// uninitialized variable. This manages the different forms of diagnostic
420262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// emitted for particular types of uses. Returns true if the use was diagnosed
421262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// as a warning. If a pariticular use is one we omit warnings for, returns
422262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// false.
423262d50e1dcf529317da193ad585c11c16281a7acChandler Carruthstatic bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
42464fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth                                     const Expr *E, bool isAlwaysUninit) {
4254c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  bool isSelfInit = false;
4264c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
4274c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
4284c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    if (isAlwaysUninit) {
4294c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      // Inspect the initializer of the variable declaration which is
4304c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      // being referenced prior to its initialization. We emit
4314c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      // specialized diagnostics for self-initialization, and we
4324c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      // specifically avoid warning about self references which take the
4334c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      // form of:
4344c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      //
4354c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      //   int x = x;
4364c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      //
4374c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      // This is used to indicate to GCC that 'x' is intentionally left
4384c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      // uninitialized. Proven code paths which access 'x' in
4394c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      // an uninitialized state after this will still warn.
4404c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      //
4414c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      // TODO: Should we suppress maybe-uninitialized warnings for
4424c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      // variables initialized in this way?
4434c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      if (const Expr *Initializer = VD->getInit()) {
4444c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth        if (DRE == Initializer->IgnoreParenImpCasts())
445262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth          return false;
4464c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
4474c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth        ContainsReference CR(S.Context, DRE);
4484c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth        CR.Visit(const_cast<Expr*>(Initializer));
4494c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth        isSelfInit = CR.doesContainReference();
4504c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      }
4514c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      if (isSelfInit) {
4524c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth        S.Diag(DRE->getLocStart(),
4534c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth               diag::warn_uninit_self_reference_in_init)
4544c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth        << VD->getDeclName() << VD->getLocation() << DRE->getSourceRange();
4554c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      } else {
4564c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth        S.Diag(DRE->getLocStart(), diag::warn_uninit_var)
4574c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth          << VD->getDeclName() << DRE->getSourceRange();
4584c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      }
4594c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    } else {
4604c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      S.Diag(DRE->getLocStart(), diag::warn_maybe_uninit_var)
4614c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth        << VD->getDeclName() << DRE->getSourceRange();
4624c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    }
4634c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  } else {
4644c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    const BlockExpr *BE = cast<BlockExpr>(E);
4654c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    S.Diag(BE->getLocStart(),
4664c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth           isAlwaysUninit ? diag::warn_uninit_var_captured_by_block
4674c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth                          : diag::warn_maybe_uninit_var_captured_by_block)
4684c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      << VD->getDeclName();
4694c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  }
4704c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
4714c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  // Report where the variable was declared when the use wasn't within
4724c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  // the initializer of that declaration.
4734c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  if (!isSelfInit)
4744c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    S.Diag(VD->getLocStart(), diag::note_uninit_var_def)
4754c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      << VD->getDeclName();
4764c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
477262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth  return true;
47864fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth}
47964fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth
480262d50e1dcf529317da193ad585c11c16281a7acChandler Carruthstatic void SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
4814c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  // Don't issue a fixit if there is already an initializer.
4824c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  if (VD->getInit())
4834c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    return;
4844c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
4854c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  // Suggest possible initialization (if any).
4864c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  const char *initialization = 0;
4874c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  QualType VariableTy = VD->getType().getCanonicalType();
4884c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
4898ba44264e05fe0012ecfb7bac28b171b5a50dde3Douglas Gregor  if (VariableTy->isObjCObjectPointerType() ||
4908ba44264e05fe0012ecfb7bac28b171b5a50dde3Douglas Gregor      VariableTy->isBlockPointerType()) {
4914c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    // Check if 'nil' is defined.
4924c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil")))
4934c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      initialization = " = nil";
4944c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    else
4954c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      initialization = " = 0";
4964c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  }
4974c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  else if (VariableTy->isRealFloatingType())
4984c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    initialization = " = 0.0";
4994c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  else if (VariableTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus)
5004c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    initialization = " = false";
5014c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  else if (VariableTy->isEnumeralType())
5024c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    return;
5038ba44264e05fe0012ecfb7bac28b171b5a50dde3Douglas Gregor  else if (VariableTy->isPointerType() || VariableTy->isMemberPointerType()) {
5048ba44264e05fe0012ecfb7bac28b171b5a50dde3Douglas Gregor    // Check if 'NULL' is defined.
5058ba44264e05fe0012ecfb7bac28b171b5a50dde3Douglas Gregor    if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("NULL")))
5068ba44264e05fe0012ecfb7bac28b171b5a50dde3Douglas Gregor      initialization = " = NULL";
5078ba44264e05fe0012ecfb7bac28b171b5a50dde3Douglas Gregor    else
5088ba44264e05fe0012ecfb7bac28b171b5a50dde3Douglas Gregor      initialization = " = 0";
5098ba44264e05fe0012ecfb7bac28b171b5a50dde3Douglas Gregor  }
5104c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  else if (VariableTy->isScalarType())
5114c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    initialization = " = 0";
5124c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
5134c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  if (initialization) {
5144c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    SourceLocation loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
5154c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth    S.Diag(loc, diag::note_var_fixit_add_initialization)
5164c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth      << FixItHint::CreateInsertion(loc, initialization);
5174c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth  }
5184c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth}
5194c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth
520f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenektypedef std::pair<const Expr*, bool> UninitUse;
521f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek
522610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremeneknamespace {
52394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenekstruct SLocSort {
524f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek  bool operator()(const UninitUse &a, const UninitUse &b) {
525f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek    SourceLocation aLoc = a.first->getLocStart();
526f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek    SourceLocation bLoc = b.first->getLocStart();
52794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    return aLoc.getRawEncoding() < bLoc.getRawEncoding();
52894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  }
52994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek};
53094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
531610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass UninitValsDiagReporter : public UninitVariablesHandler {
532610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek  Sema &S;
533f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek  typedef llvm::SmallVector<UninitUse, 2> UsesVec;
53494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  typedef llvm::DenseMap<const VarDecl *, UsesVec*> UsesMap;
53594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  UsesMap *uses;
53694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
537610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic:
53894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  UninitValsDiagReporter(Sema &S) : S(S), uses(0) {}
53994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  ~UninitValsDiagReporter() {
54094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    flushDiagnostics();
54194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  }
542610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek
543f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek  void handleUseOfUninitVariable(const Expr *ex, const VarDecl *vd,
544f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek                                 bool isAlwaysUninit) {
54594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    if (!uses)
54694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      uses = new UsesMap();
54794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
54894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    UsesVec *&vec = (*uses)[vd];
54994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    if (!vec)
55094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      vec = new UsesVec();
55194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
552f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek    vec->push_back(std::make_pair(ex, isAlwaysUninit));
55394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  }
55494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
55594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek  void flushDiagnostics() {
55694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    if (!uses)
55794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      return;
558609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek
55994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) {
56094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      const VarDecl *vd = i->first;
56194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      UsesVec *vec = i->second;
562609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek
563609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek      bool fixitIssued = false;
564609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek
56594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      // Sort the uses by their SourceLocations.  While not strictly
56694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      // guaranteed to produce them in line/column order, this will provide
56794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      // a stable ordering.
56894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      std::sort(vec->begin(), vec->end(), SLocSort());
56994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek
57064fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth      for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve;
57164fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth           ++vi) {
572262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth        if (!DiagnoseUninitializedUse(S, vd, vi->first,
573262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth                                      /*isAlwaysUninit=*/vi->second))
574262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth          continue;
575262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth
576262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth        // Suggest a fixit hint the first time we diagnose a use of a variable.
577262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth        if (!fixitIssued) {
578262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth          SuggestInitializationFixit(S, vd);
579262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth          fixitIssued = true;
580262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth        }
58164fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth      }
582fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek
58394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek      delete vec;
58494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    }
58594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek    delete uses;
586610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek  }
587610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek};
588610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}
589610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek
590610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===//
591dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based
592dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//  warnings on a function, method, or block.
593dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
594dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
595d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekclang::sema::AnalysisBasedWarnings::Policy::Policy() {
596dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  enableCheckFallThrough = 1;
597d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  enableCheckUnreachable = 0;
598d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek}
599dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
6005d98994c7749312a43ce6adf45537979a98e7afdChandler Carruthclang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
6015d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  : S(s),
6025d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    NumFunctionsAnalyzed(0),
60354cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumFunctionsWithBadCFGs(0),
6045d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    NumCFGBlocks(0),
60554cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    MaxCFGBlocksPerFunction(0),
60654cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumUninitAnalysisFunctions(0),
60754cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumUninitAnalysisVariables(0),
60854cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    MaxUninitAnalysisVariablesPerFunction(0),
60954cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    NumUninitAnalysisBlockVisits(0),
61054cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer    MaxUninitAnalysisBlockVisitsPerFunction(0) {
611d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  Diagnostic &D = S.getDiagnostics();
612d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  DefaultPolicy.enableCheckUnreachable = (unsigned)
6130827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    (D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) !=
6140827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis        Diagnostic::Ignored);
615dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
616dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
617351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekstatic void flushDiagnostics(Sema &S, sema::FunctionScopeInfo *fscope) {
618351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  for (llvm::SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
619351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek       i = fscope->PossiblyUnreachableDiags.begin(),
620351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek       e = fscope->PossiblyUnreachableDiags.end();
621351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek       i != e; ++i) {
622351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    const sema::PossiblyUnreachableDiag &D = *i;
623351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    S.Diag(D.Loc, D.PD);
624351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  }
625351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek}
626351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
627d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekvoid clang::sema::
628d064fdc4b7b64ca55b40b70490c79d6f569df78eTed KremenekAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
629283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek                                     sema::FunctionScopeInfo *fscope,
6303ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek                                     const Decl *D, const BlockExpr *blkExpr) {
631d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek
632dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // We avoid doing analysis-based warnings when there are errors for
633dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // two reasons:
634dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // (1) The CFGs often can't be constructed (if the body is invalid), so
635dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  //     don't bother trying.
636dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // (2) The code already has problems; running the analysis just takes more
637dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  //     time.
63899e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek  Diagnostic &Diags = S.getDiagnostics();
63999e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek
640d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  // Do not do any analysis for declarations in system headers if we are
641d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  // going to just ignore them.
64299e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek  if (Diags.getSuppressSystemWarnings() &&
643d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek      S.SourceMgr.isInSystemHeader(D->getLocation()))
644d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek    return;
645d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
646e0054f61fd84133eb0d19c19ae9afaf117933274John McCall  // For code in dependent contexts, we'll do this at instantiation time.
647e0054f61fd84133eb0d19c19ae9afaf117933274John McCall  if (cast<DeclContext>(D)->isDependentContext())
648e0054f61fd84133eb0d19c19ae9afaf117933274John McCall    return;
649dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
650351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) {
651351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    // Flush out any possibly unreachable diagnostics.
652351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    flushDiagnostics(S, fscope);
653351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    return;
654351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  }
655351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
656dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  const Stmt *Body = D->getBody();
657dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  assert(Body);
658dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
659dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
660dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // explosion for destrutors that can result and the compile time hit.
661eeef924c4fcb79a3bcc8782afce343e641bbcb83Chandler Carruth  AnalysisContext AC(D, 0, /*useUnoptimizedCFG=*/false, /*addehedges=*/false,
662eeef924c4fcb79a3bcc8782afce343e641bbcb83Chandler Carruth                     /*addImplicitDtors=*/true, /*addInitializers=*/true);
663dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
664351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  // Emit delayed diagnostics.
665351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  if (!fscope->PossiblyUnreachableDiags.empty()) {
666351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    bool analyzed = false;
6670d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
6680d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    // Register the expressions with the CFGBuilder.
6690d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    for (llvm::SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
6700d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek         i = fscope->PossiblyUnreachableDiags.begin(),
6710d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek         e = fscope->PossiblyUnreachableDiags.end();
6720d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek         i != e; ++i) {
6730d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek      if (const Stmt *stmt = i->stmt)
6740d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        AC.registerForcedBlockExpression(stmt);
6750d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    }
6760d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
6770d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    if (AC.getCFG()) {
6780d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek      analyzed = true;
6790d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek      for (llvm::SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
6800d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek            i = fscope->PossiblyUnreachableDiags.begin(),
6810d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek            e = fscope->PossiblyUnreachableDiags.end();
6820d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek            i != e; ++i)
6830d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek      {
6840d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        const sema::PossiblyUnreachableDiag &D = *i;
6850d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        bool processed = false;
6860d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        if (const Stmt *stmt = i->stmt) {
6870d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek          const CFGBlock *block = AC.getBlockForRegisteredExpression(stmt);
6880d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek          assert(block);
689af13d5b25b360e698cc1cf1055ad7d14e008e505Ted Kremenek          if (CFGReverseBlockReachabilityAnalysis *cra = AC.getCFGReachablityAnalysis()) {
690351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek            // Can this block be reached from the entrance?
6910d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek            if (cra->isReachable(&AC.getCFG()->getEntry(), block))
692351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek              S.Diag(D.Loc, D.PD);
6930d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek            processed = true;
694351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek          }
6950d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        }
6960d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek        if (!processed) {
6970d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek          // Emit the warning anyway if we cannot map to a basic block.
6980d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek          S.Diag(D.Loc, D.PD);
699351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek        }
700351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek      }
7010d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    }
702351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
703351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    if (!analyzed)
704351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek      flushDiagnostics(S, fscope);
705351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  }
706351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
707351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
708dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Warning: check missing 'return'
709d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  if (P.enableCheckFallThrough) {
710dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    const CheckFallThroughDiagnostics &CD =
711dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
712ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor                         : CheckFallThroughDiagnostics::MakeForFunction(D));
7133ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek    CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC);
714dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
715dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
716dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Warning: check for unreachable code
717b7e5f145f47b6ec1db1ba6fe9db9c0ed2fe38db3Ted Kremenek  if (P.enableCheckUnreachable)
718dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CheckUnreachable(S, AC);
719610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek
720a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek  if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart())
72176709bf816e5e1b70b859bb607cf3ee91db12b76Ted Kremenek      != Diagnostic::Ignored ||
72276709bf816e5e1b70b859bb607cf3ee91db12b76Ted Kremenek      Diags.getDiagnosticLevel(diag::warn_maybe_uninit_var, D->getLocStart())
723610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek      != Diagnostic::Ignored) {
724c5e43c19ddb40b8a1371291f73ae66fe54951ca5Ted Kremenek    if (CFG *cfg = AC.getCFG()) {
725c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek      UninitValsDiagReporter reporter(S);
72657080fbac1ccce702255423335d52e81bcf17b6bFariborz Jahanian      UninitVariablesAnalysisStats stats;
727a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek      runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC,
7285d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth                                        reporter, stats);
7295d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
7305d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      if (S.CollectStats && stats.NumVariablesAnalyzed > 0) {
7315d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        ++NumUninitAnalysisFunctions;
7325d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        NumUninitAnalysisVariables += stats.NumVariablesAnalyzed;
7335d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        NumUninitAnalysisBlockVisits += stats.NumBlockVisits;
7345d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        MaxUninitAnalysisVariablesPerFunction =
7355d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth            std::max(MaxUninitAnalysisVariablesPerFunction,
7365d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth                     stats.NumVariablesAnalyzed);
7375d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth        MaxUninitAnalysisBlockVisitsPerFunction =
7385d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth            std::max(MaxUninitAnalysisBlockVisitsPerFunction,
7395d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth                     stats.NumBlockVisits);
7405d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      }
7415d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    }
7425d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  }
7435d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
7445d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  // Collect statistics about the CFG if it was built.
7455d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  if (S.CollectStats && AC.isCFGBuilt()) {
7465d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    ++NumFunctionsAnalyzed;
7475d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    if (CFG *cfg = AC.getCFG()) {
7485d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      // If we successfully built a CFG for this context, record some more
7495d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      // detail information about it.
7503ea4c49709c5bba5f8b16c6ceb725d9b9a1c48c6Chandler Carruth      NumCFGBlocks += cfg->getNumBlockIDs();
7515d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction,
7523ea4c49709c5bba5f8b16c6ceb725d9b9a1c48c6Chandler Carruth                                         cfg->getNumBlockIDs());
7535d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth    } else {
7545d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      ++NumFunctionsWithBadCFGs;
755610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek    }
756610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek  }
757dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
7585d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
7595d98994c7749312a43ce6adf45537979a98e7afdChandler Carruthvoid clang::sema::AnalysisBasedWarnings::PrintStats() const {
7605d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  llvm::errs() << "\n*** Analysis Based Warnings Stats:\n";
7615d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
7625d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs;
7635d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned AvgCFGBlocksPerFunction =
7645d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt;
7655d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  llvm::errs() << NumFunctionsAnalyzed << " functions analyzed ("
7665d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << NumFunctionsWithBadCFGs << " w/o CFGs).\n"
7675d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << NumCFGBlocks << " CFG blocks built.\n"
7685d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << AvgCFGBlocksPerFunction
7695d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " average CFG blocks per function.\n"
7705d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << MaxCFGBlocksPerFunction
7715d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " max CFG blocks per function.\n";
7725d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth
7735d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0
7745d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      : NumUninitAnalysisVariables/NumUninitAnalysisFunctions;
7755d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0
7765d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth      : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions;
7775d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth  llvm::errs() << NumUninitAnalysisFunctions
7785d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " functions analyzed for uninitialiazed variables\n"
7795d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << NumUninitAnalysisVariables << " variables analyzed.\n"
7805d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << AvgUninitVariablesPerFunction
7815d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " average variables per function.\n"
7825d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << MaxUninitAnalysisVariablesPerFunction
7835d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " max variables per function.\n"
7845d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << NumUninitAnalysisBlockVisits << " block visits.\n"
7855d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << AvgUninitBlockVisitsPerFunction
7865d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " average block visits per function.\n"
7875d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << "  " << MaxUninitAnalysisBlockVisitsPerFunction
7885d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth               << " max block visits per function.\n";
7895d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth}
790