blob: 7c1d8cbae9ee9ea47dc2f92babcab5570e68a9e1 [file] [log] [blame]
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +00001//=- 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"
Ted Kremenekd068aab2010-03-20 21:11:09 +000018#include "clang/Basic/SourceManager.h"
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000019#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"
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000028
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.
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +000077 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();
Rafael Espindola264ba482010-03-30 20:24:48 +0000155 if (getFunctionExtInfo(CEE->getType()).getNoReturn()) {
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000156 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;
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000190
Douglas Gregorca7eaee2010-04-16 23:28:44 +0000191 static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000192 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;
Douglas Gregorca7eaee2010-04-16 23:28:44 +0000201
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
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000214 D.funMode = true;
215 return D;
216 }
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000217
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000218 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 }
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000233
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000234 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 }
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000244
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000245 // 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>() ||
Rafael Espindola264ba482010-03-30 20:24:48 +0000267 FD->getType()->getAs<FunctionType>()->getNoReturnAttr();
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000268 }
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)) {
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000274 if (const FunctionType *FT =
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000275 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;
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000288
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000289 // 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:
Douglas Gregorca7eaee2010-04-16 23:28:44 +0000309 if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn)
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000310 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
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000324clang::sema::AnalysisBasedWarnings::Policy::Policy() {
325 enableCheckFallThrough = 1;
326 enableCheckUnreachable = 0;
327}
328
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000329clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s) {
330 Diagnostic &D = S.getDiagnostics();
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000331 DefaultPolicy.enableCheckUnreachable = (unsigned)
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000332 (D.getDiagnosticLevel(diag::warn_unreachable) != Diagnostic::Ignored);
333}
334
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000335void clang::sema::
336AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
Ted Kremenekb7e5f142010-04-08 18:51:44 +0000337 const Decl *D, QualType BlockTy) {
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000338
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000339 assert(BlockTy.isNull() || isa<BlockDecl>(D));
Ted Kremenekd068aab2010-03-20 21:11:09 +0000340
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000341 // 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())
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000348 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
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000356 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'
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000371 if (P.enableCheckFallThrough) {
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000372 const CheckFallThroughDiagnostics &CD =
373 (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
Douglas Gregorca7eaee2010-04-16 23:28:44 +0000374 : CheckFallThroughDiagnostics::MakeForFunction(D));
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000375 CheckFallThroughForBody(S, D, Body, BlockTy, CD, AC);
376 }
377
378 // Warning: check for unreachable code
Ted Kremenekb7e5f142010-04-08 18:51:44 +0000379 if (P.enableCheckUnreachable)
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000380 CheckUnreachable(S, AC);
Ted Kremenekdbdbaaf2010-03-20 21:06:02 +0000381}