AnalysisBasedWarnings.cpp revision d068aabc484c4009282122c6ef26e66e68cfa044
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
16dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "Sema.h"
17dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "AnalysisBasedWarnings.h"
18d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek#include "clang/Basic/SourceManager.h"
19dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/ExprObjC.h"
20dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/ExprCXX.h"
21dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/StmtObjC.h"
22dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/StmtCXX.h"
23dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/AnalysisContext.h"
24dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/CFG.h"
25dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/Analyses/ReachableCode.h"
26dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/ADT/BitVector.h"
27dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/Support/Casting.h"
28dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include <queue>
29dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
30dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekusing namespace clang;
31dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
32dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
33dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Unreachable code analysis.
34dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
35dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
36dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremeneknamespace {
37dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  class UnreachableCodeHandler : public reachable_code::Callback {
38dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    Sema &S;
39dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  public:
40dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    UnreachableCodeHandler(Sema &s) : S(s) {}
41dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
42dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) {
43dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      S.Diag(L, diag::warn_unreachable) << R1 << R2;
44dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
45dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  };
46dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
47dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
48dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckUnreachable - Check for unreachable code.
49dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckUnreachable(Sema &S, AnalysisContext &AC) {
50dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  UnreachableCodeHandler UC(S);
51dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  reachable_code::FindUnreachableCode(AC, UC);
52dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
53dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
54dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
55dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Check for missing return value.
56dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
57dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
58dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekenum ControlFlowKind { NeverFallThrough = 0, MaybeFallThrough = 1,
59dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  AlwaysFallThrough = 2, NeverFallThroughOrReturn = 3 };
60dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
61dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThrough - Check that we don't fall off the end of a
62dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// Statement that should return a value.
63dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek///
64dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// \returns AlwaysFallThrough iff we always fall off the end of the statement,
65dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// MaybeFallThrough iff we might or might not fall off the end,
66dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// NeverFallThroughOrReturn iff we never fall off the end of the statement or
67dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// return.  We assume NeverFallThrough iff we never fall off the end of the
68dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// statement but we may return.  We assume that functions not marked noreturn
69dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// will return.
70dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic ControlFlowKind CheckFallThrough(AnalysisContext &AC) {
71dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  CFG *cfg = AC.getCFG();
72dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (cfg == 0)
73dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // FIXME: This should be NeverFallThrough
74dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return NeverFallThroughOrReturn;
75dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
76dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // The CFG leaves in dead things, and we don't want the dead code paths to
77dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // confuse us, so we mark all live things first.
78dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  std::queue<CFGBlock*> workq;
79dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  llvm::BitVector live(cfg->getNumBlockIDs());
80dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned count = reachable_code::ScanReachableFromBlock(cfg->getEntry(),
81dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                                          live);
82dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
83dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool AddEHEdges = AC.getAddEHEdges();
84dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (!AddEHEdges && count != cfg->getNumBlockIDs())
85dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // When there are things remaining dead, and we didn't add EH edges
86dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // from CallExprs to the catch clauses, we have to go back and
87dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // mark them as live.
88dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
89dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      CFGBlock &b = **I;
90dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (!live[b.getBlockID()]) {
91dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        if (b.pred_begin() == b.pred_end()) {
92dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator()))
93dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek            // When not adding EH edges from calls, catch clauses
94dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek            // can otherwise seem dead.  Avoid noting them as dead.
95dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek            count += reachable_code::ScanReachableFromBlock(b, live);
96dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          continue;
97dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        }
98dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
99dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
100dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
101dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Now we know what is live, we check the live precessors of the exit block
102dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // and look for fall through paths, being careful to ignore normal returns,
103dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // and exceptional paths.
104dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasLiveReturn = false;
105dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasFakeEdge = false;
106dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasPlainEdge = false;
107dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasAbnormalEdge = false;
108dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  for (CFGBlock::pred_iterator I=cfg->getExit().pred_begin(),
109dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek       E = cfg->getExit().pred_end();
110dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek       I != E;
111dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek       ++I) {
112dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CFGBlock& B = **I;
113dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (!live[B.getBlockID()])
114dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
115dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (B.size() == 0) {
116dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) {
117dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasAbnormalEdge = true;
118dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        continue;
119dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
120dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
121dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      // A labeled empty statement, or the entry block...
122dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasPlainEdge = true;
123dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
124dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
125dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    Stmt *S = B[B.size()-1];
126dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<ReturnStmt>(S)) {
127dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasLiveReturn = true;
128dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
129dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
130dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<ObjCAtThrowStmt>(S)) {
131dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasFakeEdge = true;
132dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
133dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
134dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<CXXThrowExpr>(S)) {
135dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasFakeEdge = true;
136dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
137dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
138dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) {
139dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (AS->isMSAsm()) {
140dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasFakeEdge = true;
141dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasLiveReturn = true;
142dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        continue;
143dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
144dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
145dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (isa<CXXTryStmt>(S)) {
146dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasAbnormalEdge = true;
147dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      continue;
148dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
149dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
150dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    bool NoReturnEdge = false;
151dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (CallExpr *C = dyn_cast<CallExpr>(S)) {
152dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (B.succ_begin()[0] != &cfg->getExit()) {
153dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasAbnormalEdge = true;
154dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        continue;
155dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
156dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      Expr *CEE = C->getCallee()->IgnoreParenCasts();
157dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (CEE->getType().getNoReturnAttr()) {
158dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        NoReturnEdge = true;
159dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasFakeEdge = true;
160dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
161dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        ValueDecl *VD = DRE->getDecl();
162dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        if (VD->hasAttr<NoReturnAttr>()) {
163dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          NoReturnEdge = true;
164dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          HasFakeEdge = true;
165dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        }
166dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      }
167dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
168dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // FIXME: Add noreturn message sends.
169dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (NoReturnEdge == false)
170dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      HasPlainEdge = true;
171dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
172dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (!HasPlainEdge) {
173dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (HasLiveReturn)
174dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      return NeverFallThrough;
175dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return NeverFallThroughOrReturn;
176dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
177dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn)
178dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return MaybeFallThrough;
179dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // This says AlwaysFallThrough for calls to functions that are not marked
180dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // noreturn, that don't return.  If people would like this warning to be more
181dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // accurate, such functions should be marked as noreturn.
182dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  return AlwaysFallThrough;
183dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
184dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
185dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstruct CheckFallThroughDiagnostics {
186dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_MaybeFallThrough_HasNoReturn;
187dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_MaybeFallThrough_ReturnsNonVoid;
188dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_AlwaysFallThrough_HasNoReturn;
189dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
190dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  unsigned diag_NeverFallThroughOrReturn;
191dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool funMode;
192dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
193dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  static CheckFallThroughDiagnostics MakeForFunction() {
194dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CheckFallThroughDiagnostics D;
195dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_HasNoReturn =
196dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_noreturn_function;
197dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_ReturnsNonVoid =
198dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_maybe_falloff_nonvoid_function;
199dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_HasNoReturn =
200dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_noreturn_function;
201dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_ReturnsNonVoid =
202dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_falloff_nonvoid_function;
203dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_NeverFallThroughOrReturn =
204dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_suggest_noreturn_function;
205dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.funMode = true;
206dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return D;
207dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
208dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
209dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  static CheckFallThroughDiagnostics MakeForBlock() {
210dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CheckFallThroughDiagnostics D;
211dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_HasNoReturn =
212dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_noreturn_block_has_return_expr;
213dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_MaybeFallThrough_ReturnsNonVoid =
214dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_maybe_falloff_nonvoid_block;
215dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_HasNoReturn =
216dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_noreturn_block_has_return_expr;
217dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_AlwaysFallThrough_ReturnsNonVoid =
218dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::err_falloff_nonvoid_block;
219dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.diag_NeverFallThroughOrReturn =
220dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      diag::warn_suggest_noreturn_block;
221dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    D.funMode = false;
222dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return D;
223dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
224dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
225dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool checkDiagnostics(Diagnostic &D, bool ReturnsVoid,
226dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                        bool HasNoReturn) const {
227dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (funMode) {
228dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      return (D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function)
229dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek              == Diagnostic::Ignored || ReturnsVoid)
230dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        && (D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr)
231dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek              == Diagnostic::Ignored || !HasNoReturn)
232dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block)
233dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek              == Diagnostic::Ignored || !ReturnsVoid);
234dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
235dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
236dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // For blocks.
237dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    return  ReturnsVoid && !HasNoReturn
238dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek            && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block)
239dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                == Diagnostic::Ignored || !ReturnsVoid);
240dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
241dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek};
242dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
243dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
244dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// function that should return a value.  Check that we don't fall off the end
245dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// of a noreturn function.  We assume that functions and blocks not marked
246dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// noreturn will return.
247dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
248dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                    QualType BlockTy,
249dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                    const CheckFallThroughDiagnostics& CD,
250dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                    AnalysisContext &AC) {
251dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
252dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool ReturnsVoid = false;
253dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  bool HasNoReturn = false;
254dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
255dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
256dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    ReturnsVoid = FD->getResultType()->isVoidType();
257dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    HasNoReturn = FD->hasAttr<NoReturnAttr>() ||
258dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                  FD->getType()->getAs<FunctionType>()->getNoReturnAttr();
259dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
260dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
261dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    ReturnsVoid = MD->getResultType()->isVoidType();
262dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    HasNoReturn = MD->hasAttr<NoReturnAttr>();
263dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
264dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  else if (isa<BlockDecl>(D)) {
265dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (const FunctionType *FT =
266dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          BlockTy->getPointeeType()->getAs<FunctionType>()) {
267dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (FT->getResultType()->isVoidType())
268dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        ReturnsVoid = true;
269dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      if (FT->getNoReturnAttr())
270dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        HasNoReturn = true;
271dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
272dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
273dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
274dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  Diagnostic &Diags = S.getDiagnostics();
275dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
276dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Short circuit for compilation speed.
277dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
278dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      return;
279dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
280dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // FIXME: Function try block
281dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) {
282dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    switch (CheckFallThrough(AC)) {
283dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case MaybeFallThrough:
284dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        if (HasNoReturn)
285dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
286dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_MaybeFallThrough_HasNoReturn);
287dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        else if (!ReturnsVoid)
288dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
289dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_MaybeFallThrough_ReturnsNonVoid);
290dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
291dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case AlwaysFallThrough:
292dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        if (HasNoReturn)
293dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
294dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_AlwaysFallThrough_HasNoReturn);
295dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        else if (!ReturnsVoid)
296dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getRBracLoc(),
297dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_AlwaysFallThrough_ReturnsNonVoid);
298dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
299dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case NeverFallThroughOrReturn:
300dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        if (ReturnsVoid && !HasNoReturn)
301dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek          S.Diag(Compound->getLBracLoc(),
302dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                 CD.diag_NeverFallThroughOrReturn);
303dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
304dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      case NeverFallThrough:
305dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek        break;
306dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    }
307dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
308dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
309dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
310dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
311dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based
312dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//  warnings on a function, method, or block.
313dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===//
314dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
315dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekclang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s) {
316dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  Diagnostic &D = S.getDiagnostics();
317dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
318dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  enableCheckFallThrough = 1;
319dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
320dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  enableCheckUnreachable = (unsigned)
321dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    (D.getDiagnosticLevel(diag::warn_unreachable) != Diagnostic::Ignored);
322dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
323dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
324dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekvoid clang::sema::AnalysisBasedWarnings::IssueWarnings(const Decl *D,
325dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                                                       QualType BlockTy) {
326dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
327dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  assert(BlockTy.isNull() || isa<BlockDecl>(D));
328dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
329d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek  // Do not do any analysis for declarations in system headers if we are
330d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek  // going to just ignore them.
331d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek  if (S.getDiagnostics().getSuppressSystemWarnings() &&
332d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek      S.SourceMgr.isInSystemHeader(D->getLocation()))
333d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek    return;
334d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek
335dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // We avoid doing analysis-based warnings when there are errors for
336dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // two reasons:
337dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // (1) The CFGs often can't be constructed (if the body is invalid), so
338dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  //     don't bother trying.
339dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // (2) The code already has problems; running the analysis just takes more
340dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  //     time.
341dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (S.getDiagnostics().hasErrorOccurred())
342dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      return;
343dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
344dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
345dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // For function templates, class templates and member function templates
346dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    // we'll do the analysis at instantiation time.
347dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    if (FD->isDependentContext())
348dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      return;
349dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
350dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
351dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  const Stmt *Body = D->getBody();
352dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  assert(Body);
353dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
354dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
355dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // explosion for destrutors that can result and the compile time hit.
356dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  AnalysisContext AC(D, false);
357dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
358dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Warning: check missing 'return'
359dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (enableCheckFallThrough) {
360dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    const CheckFallThroughDiagnostics &CD =
361dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek      (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
362dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek                         : CheckFallThroughDiagnostics::MakeForFunction());
363dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CheckFallThroughForBody(S, D, Body, BlockTy, CD, AC);
364dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  }
365dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek
366dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  // Warning: check for unreachable code
367dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek  if (enableCheckUnreachable)
368dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek    CheckUnreachable(S, AC);
369dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}
370