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