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 //===----------------------------------------------------------------------===//
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"
31 using namespace clang
;
33 //===----------------------------------------------------------------------===//
34 // Unreachable code analysis.
35 //===----------------------------------------------------------------------===//
38 class UnreachableCodeHandler
: public reachable_code::Callback
{
41 UnreachableCodeHandler(Sema
&s
) : S(s
) {}
43 void HandleUnreachable(SourceLocation L
, SourceRange R1
, SourceRange R2
) {
44 S
.Diag(L
, diag::warn_unreachable
) << R1
<< R2
;
49 /// CheckUnreachable - Check for unreachable code.
50 static void CheckUnreachable(Sema
&S
, AnalysisContext
&AC
) {
51 UnreachableCodeHandler
UC(S
);
52 reachable_code::FindUnreachableCode(AC
, UC
);
55 //===----------------------------------------------------------------------===//
56 // Check for missing return value.
57 //===----------------------------------------------------------------------===//
59 enum ControlFlowKind
{
64 NeverFallThroughOrReturn
67 /// CheckFallThrough - Check that we don't fall off the end of a
68 /// Statement that should return a value.
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
76 static ControlFlowKind
CheckFallThrough(AnalysisContext
&AC
) {
77 CFG
*cfg
= AC
.getCFG();
78 if (cfg
== 0) return UnknownFallThrough
;
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(),
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
91 for (CFG::iterator I
= cfg
->begin(), E
= cfg
->end(); I
!= E
; ++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
);
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;
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;
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()])
123 if (B
.getTerminator() && isa
<CXXTryStmt
>(B
.getTerminator())) {
124 HasAbnormalEdge
= true;
128 // A labeled empty statement, or the entry block...
132 CFGElement CE
= B
[B
.size()-1];
133 CFGStmt CS
= CE
.getAs
<CFGStmt
>();
136 Stmt
*S
= CS
.getStmt();
137 if (isa
<ReturnStmt
>(S
)) {
138 HasLiveReturn
= true;
141 if (isa
<ObjCAtThrowStmt
>(S
)) {
145 if (isa
<CXXThrowExpr
>(S
)) {
149 if (const AsmStmt
*AS
= dyn_cast
<AsmStmt
>(S
)) {
152 HasLiveReturn
= true;
156 if (isa
<CXXTryStmt
>(S
)) {
157 HasAbnormalEdge
= true;
161 bool NoReturnEdge
= false;
162 if (CallExpr
*C
= dyn_cast
<CallExpr
>(S
)) {
163 if (std::find(B
.succ_begin(), B
.succ_end(), &cfg
->getExit())
165 HasAbnormalEdge
= true;
168 Expr
*CEE
= C
->getCallee()->IgnoreParenCasts();
169 if (getFunctionExtInfo(CEE
->getType()).getNoReturn()) {
172 } else if (DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(CEE
)) {
173 ValueDecl
*VD
= DRE
->getDecl();
174 if (VD
->hasAttr
<NoReturnAttr
>()) {
180 // FIXME: Remove this hack once temporaries and their destructors are
181 // modeled correctly by the CFG.
182 if (CXXExprWithTemporaries
*E
= dyn_cast
<CXXExprWithTemporaries
>(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()) {
193 // FIXME: Add noreturn message sends.
194 if (NoReturnEdge
== false)
199 return NeverFallThrough
;
200 return NeverFallThroughOrReturn
;
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
;
212 struct 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
;
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
;
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();
237 if (!isVirtualMethod
)
238 D
.diag_NeverFallThroughOrReturn
=
239 diag::warn_suggest_noreturn_function
;
241 D
.diag_NeverFallThroughOrReturn
= 0;
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
;
263 bool checkDiagnostics(Diagnostic
&D
, bool ReturnsVoid
,
264 bool HasNoReturn
) const {
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
);
275 return ReturnsVoid
&& !HasNoReturn
276 && (D
.getDiagnosticLevel(diag::warn_suggest_noreturn_block
)
277 == Diagnostic::Ignored
|| !ReturnsVoid
);
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.
287 static void CheckFallThroughForBody(Sema
&S
, const Decl
*D
, const Stmt
*Body
,
289 const CheckFallThroughDiagnostics
& CD
,
290 AnalysisContext
&AC
) {
292 bool ReturnsVoid
= false;
293 bool HasNoReturn
= false;
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();
300 else if (const ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(D
)) {
301 ReturnsVoid
= MD
->getResultType()->isVoidType();
302 HasNoReturn
= MD
->hasAttr
<NoReturnAttr
>();
304 else if (isa
<BlockDecl
>(D
)) {
305 if (const FunctionType
*FT
=
306 BlockTy
->getPointeeType()->getAs
<FunctionType
>()) {
307 if (FT
->getResultType()->isVoidType())
309 if (FT
->getNoReturnAttr())
314 Diagnostic
&Diags
= S
.getDiagnostics();
316 // Short circuit for compilation speed.
317 if (CD
.checkDiagnostics(Diags
, ReturnsVoid
, HasNoReturn
))
320 // FIXME: Function try block
321 if (const CompoundStmt
*Compound
= dyn_cast
<CompoundStmt
>(Body
)) {
322 switch (CheckFallThrough(AC
)) {
323 case UnknownFallThrough
:
326 case MaybeFallThrough
:
328 S
.Diag(Compound
->getRBracLoc(),
329 CD
.diag_MaybeFallThrough_HasNoReturn
);
330 else if (!ReturnsVoid
)
331 S
.Diag(Compound
->getRBracLoc(),
332 CD
.diag_MaybeFallThrough_ReturnsNonVoid
);
334 case AlwaysFallThrough
:
336 S
.Diag(Compound
->getRBracLoc(),
337 CD
.diag_AlwaysFallThrough_HasNoReturn
);
338 else if (!ReturnsVoid
)
339 S
.Diag(Compound
->getRBracLoc(),
340 CD
.diag_AlwaysFallThrough_ReturnsNonVoid
);
342 case NeverFallThroughOrReturn
:
343 if (ReturnsVoid
&& !HasNoReturn
&& CD
.diag_NeverFallThroughOrReturn
)
344 S
.Diag(Compound
->getLBracLoc(),
345 CD
.diag_NeverFallThroughOrReturn
);
347 case NeverFallThrough
:
353 //===----------------------------------------------------------------------===//
354 // AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based
355 // warnings on a function, method, or block.
356 //===----------------------------------------------------------------------===//
358 clang::sema::AnalysisBasedWarnings::Policy::Policy() {
359 enableCheckFallThrough
= 1;
360 enableCheckUnreachable
= 0;
363 clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema
&s
) : S(s
) {
364 Diagnostic
&D
= S
.getDiagnostics();
365 DefaultPolicy
.enableCheckUnreachable
= (unsigned)
366 (D
.getDiagnosticLevel(diag::warn_unreachable
) != Diagnostic::Ignored
);
370 AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P
,
371 const Decl
*D
, QualType BlockTy
) {
373 assert(BlockTy
.isNull() || isa
<BlockDecl
>(D
));
375 // We avoid doing analysis-based warnings when there are errors for
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
381 Diagnostic
&Diags
= S
.getDiagnostics();
383 if (Diags
.hasErrorOccurred() || Diags
.hasFatalErrorOccurred())
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()))
392 // For code in dependent contexts, we'll do this at instantiation time.
393 if (cast
<DeclContext
>(D
)->isDependentContext())
396 const Stmt
*Body
= D
->getBody();
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);
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
);
411 // Warning: check for unreachable code
412 if (P
.enableCheckUnreachable
)
413 CheckUnreachable(S
, AC
);
417 AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P
,
418 const BlockExpr
*E
) {
419 return IssueWarnings(P
, E
->getBlockDecl(), E
->getType());
423 AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P
,
424 const ObjCMethodDecl
*D
) {
425 return IssueWarnings(P
, D
, QualType());
429 AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P
,
430 const FunctionDecl
*D
) {
431 return IssueWarnings(P
, D
, QualType());