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