1 //=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis -*- C++ -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
14 //===----------------------------------------------------------------------===//
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"
29 using namespace clang;
31 //===----------------------------------------------------------------------===//
32 // Unreachable code analysis.
33 //===----------------------------------------------------------------------===//
36 class UnreachableCodeHandler : public reachable_code::Callback {
39 UnreachableCodeHandler(Sema &s) : S(s) {}
41 void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) {
42 S.Diag(L, diag::warn_unreachable) << R1 << R2;
47 /// CheckUnreachable - Check for unreachable code.
48 static void CheckUnreachable(Sema &S, AnalysisContext &AC) {
49 UnreachableCodeHandler UC(S);
50 reachable_code::FindUnreachableCode(AC, UC);
53 //===----------------------------------------------------------------------===//
54 // Check for missing return value.
55 //===----------------------------------------------------------------------===//
57 enum ControlFlowKind { NeverFallThrough = 0, MaybeFallThrough = 1,
58 AlwaysFallThrough = 2, NeverFallThroughOrReturn = 3 };
60 /// CheckFallThrough - Check that we don't fall off the end of a
61 /// Statement that should return a value.
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
69 static ControlFlowKind CheckFallThrough(AnalysisContext &AC) {
70 CFG *cfg = AC.getCFG();
72 // FIXME: This should be NeverFallThrough
73 return NeverFallThroughOrReturn;
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(),
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
86 for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++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);
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();
111 if (!live[B.getBlockID()])
114 if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) {
115 HasAbnormalEdge = true;
119 // A labeled empty statement, or the entry block...
123 Stmt *S = B[B.size()-1];
124 if (isa<ReturnStmt>(S)) {
125 HasLiveReturn = true;
128 if (isa<ObjCAtThrowStmt>(S)) {
132 if (isa<CXXThrowExpr>(S)) {
136 if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) {
139 HasLiveReturn = true;
143 if (isa<CXXTryStmt>(S)) {
144 HasAbnormalEdge = true;
148 bool NoReturnEdge = false;
149 if (CallExpr *C = dyn_cast<CallExpr>(S)) {
150 if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit())
152 HasAbnormalEdge = true;
155 Expr *CEE = C->getCallee()->IgnoreParenCasts();
156 if (getFunctionExtInfo(CEE->getType()).getNoReturn()) {
159 } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
160 ValueDecl *VD = DRE->getDecl();
161 if (VD->hasAttr<NoReturnAttr>()) {
167 // FIXME: Add noreturn message sends.
168 if (NoReturnEdge == false)
173 return NeverFallThrough;
174 return NeverFallThroughOrReturn;
176 if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn)
177 return MaybeFallThrough;
178 // This says AlwaysFallThrough for calls to functions that are not marked
179 // noreturn, that don't return. If people would like this warning to be more
180 // accurate, such functions should be marked as noreturn.
181 return AlwaysFallThrough;
184 struct CheckFallThroughDiagnostics {
185 unsigned diag_MaybeFallThrough_HasNoReturn;
186 unsigned diag_MaybeFallThrough_ReturnsNonVoid;
187 unsigned diag_AlwaysFallThrough_HasNoReturn;
188 unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
189 unsigned diag_NeverFallThroughOrReturn;
192 static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
193 CheckFallThroughDiagnostics D;
194 D.diag_MaybeFallThrough_HasNoReturn =
195 diag::warn_falloff_noreturn_function;
196 D.diag_MaybeFallThrough_ReturnsNonVoid =
197 diag::warn_maybe_falloff_nonvoid_function;
198 D.diag_AlwaysFallThrough_HasNoReturn =
199 diag::warn_falloff_noreturn_function;
200 D.diag_AlwaysFallThrough_ReturnsNonVoid =
201 diag::warn_falloff_nonvoid_function;
203 // Don't suggest that virtual functions be marked "noreturn", since they
204 // might be overridden by non-noreturn functions.
205 bool isVirtualMethod = false;
206 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func))
207 isVirtualMethod = Method->isVirtual();
209 if (!isVirtualMethod)
210 D.diag_NeverFallThroughOrReturn =
211 diag::warn_suggest_noreturn_function;
213 D.diag_NeverFallThroughOrReturn = 0;
219 static CheckFallThroughDiagnostics MakeForBlock() {
220 CheckFallThroughDiagnostics D;
221 D.diag_MaybeFallThrough_HasNoReturn =
222 diag::err_noreturn_block_has_return_expr;
223 D.diag_MaybeFallThrough_ReturnsNonVoid =
224 diag::err_maybe_falloff_nonvoid_block;
225 D.diag_AlwaysFallThrough_HasNoReturn =
226 diag::err_noreturn_block_has_return_expr;
227 D.diag_AlwaysFallThrough_ReturnsNonVoid =
228 diag::err_falloff_nonvoid_block;
229 D.diag_NeverFallThroughOrReturn =
230 diag::warn_suggest_noreturn_block;
235 bool checkDiagnostics(Diagnostic &D, bool ReturnsVoid,
236 bool HasNoReturn) const {
238 return (D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function)
239 == Diagnostic::Ignored || ReturnsVoid)
240 && (D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr)
241 == Diagnostic::Ignored || !HasNoReturn)
242 && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block)
243 == Diagnostic::Ignored || !ReturnsVoid);
247 return ReturnsVoid && !HasNoReturn
248 && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block)
249 == Diagnostic::Ignored || !ReturnsVoid);
253 /// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
254 /// function that should return a value. Check that we don't fall off the end
255 /// of a noreturn function. We assume that functions and blocks not marked
256 /// noreturn will return.
257 static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
259 const CheckFallThroughDiagnostics& CD,
260 AnalysisContext &AC) {
262 bool ReturnsVoid = false;
263 bool HasNoReturn = false;
265 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
266 ReturnsVoid = FD->getResultType()->isVoidType();
267 HasNoReturn = FD->hasAttr<NoReturnAttr>() ||
268 FD->getType()->getAs<FunctionType>()->getNoReturnAttr();
270 else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
271 ReturnsVoid = MD->getResultType()->isVoidType();
272 HasNoReturn = MD->hasAttr<NoReturnAttr>();
274 else if (isa<BlockDecl>(D)) {
275 if (const FunctionType *FT =
276 BlockTy->getPointeeType()->getAs<FunctionType>()) {
277 if (FT->getResultType()->isVoidType())
279 if (FT->getNoReturnAttr())
284 Diagnostic &Diags = S.getDiagnostics();
286 // Short circuit for compilation speed.
287 if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
290 // FIXME: Function try block
291 if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) {
292 switch (CheckFallThrough(AC)) {
293 case MaybeFallThrough:
295 S.Diag(Compound->getRBracLoc(),
296 CD.diag_MaybeFallThrough_HasNoReturn);
297 else if (!ReturnsVoid)
298 S.Diag(Compound->getRBracLoc(),
299 CD.diag_MaybeFallThrough_ReturnsNonVoid);
301 case AlwaysFallThrough:
303 S.Diag(Compound->getRBracLoc(),
304 CD.diag_AlwaysFallThrough_HasNoReturn);
305 else if (!ReturnsVoid)
306 S.Diag(Compound->getRBracLoc(),
307 CD.diag_AlwaysFallThrough_ReturnsNonVoid);
309 case NeverFallThroughOrReturn:
310 if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn)
311 S.Diag(Compound->getLBracLoc(),
312 CD.diag_NeverFallThroughOrReturn);
314 case NeverFallThrough:
320 //===----------------------------------------------------------------------===//
321 // AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based
322 // warnings on a function, method, or block.
323 //===----------------------------------------------------------------------===//
325 clang::sema::AnalysisBasedWarnings::Policy::Policy() {
326 enableCheckFallThrough = 1;
327 enableCheckUnreachable = 0;
330 clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s) {
331 Diagnostic &D = S.getDiagnostics();
332 DefaultPolicy.enableCheckUnreachable = (unsigned)
333 (D.getDiagnosticLevel(diag::warn_unreachable) != Diagnostic::Ignored);
337 AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
338 const Decl *D, QualType BlockTy) {
340 assert(BlockTy.isNull() || isa<BlockDecl>(D));
342 // We avoid doing analysis-based warnings when there are errors for
344 // (1) The CFGs often can't be constructed (if the body is invalid), so
345 // don't bother trying.
346 // (2) The code already has problems; running the analysis just takes more
348 Diagnostic &Diags = S.getDiagnostics();
350 if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
353 // Do not do any analysis for declarations in system headers if we are
354 // going to just ignore them.
355 if (Diags.getSuppressSystemWarnings() &&
356 S.SourceMgr.isInSystemHeader(D->getLocation()))
359 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
360 // For function templates, class templates and member function templates
361 // we'll do the analysis at instantiation time.
362 if (FD->isDependentContext())
366 const Stmt *Body = D->getBody();
369 // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
370 // explosion for destrutors that can result and the compile time hit.
371 AnalysisContext AC(D, false);
373 // Warning: check missing 'return'
374 if (P.enableCheckFallThrough) {
375 const CheckFallThroughDiagnostics &CD =
376 (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
377 : CheckFallThroughDiagnostics::MakeForFunction(D));
378 CheckFallThroughForBody(S, D, Body, BlockTy, CD, AC);
381 // Warning: check for unreachable code
382 if (P.enableCheckUnreachable)
383 CheckUnreachable(S, AC);