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;
111 for (CFGBlock::pred_iterator I
=cfg
->getExit().pred_begin(),
112 E
= cfg
->getExit().pred_end();
116 if (!live
[B
.getBlockID()])
119 if (B
.getTerminator() && isa
<CXXTryStmt
>(B
.getTerminator())) {
120 HasAbnormalEdge
= true;
124 // A labeled empty statement, or the entry block...
128 Stmt
*S
= B
[B
.size()-1];
129 if (isa
<ReturnStmt
>(S
)) {
130 HasLiveReturn
= true;
133 if (isa
<ObjCAtThrowStmt
>(S
)) {
137 if (isa
<CXXThrowExpr
>(S
)) {
141 if (const AsmStmt
*AS
= dyn_cast
<AsmStmt
>(S
)) {
144 HasLiveReturn
= true;
148 if (isa
<CXXTryStmt
>(S
)) {
149 HasAbnormalEdge
= true;
153 bool NoReturnEdge
= false;
154 if (CallExpr
*C
= dyn_cast
<CallExpr
>(S
)) {
155 if (std::find(B
.succ_begin(), B
.succ_end(), &cfg
->getExit())
157 HasAbnormalEdge
= true;
160 Expr
*CEE
= C
->getCallee()->IgnoreParenCasts();
161 if (getFunctionExtInfo(CEE
->getType()).getNoReturn()) {
164 } else if (DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(CEE
)) {
165 ValueDecl
*VD
= DRE
->getDecl();
166 if (VD
->hasAttr
<NoReturnAttr
>()) {
172 // FIXME: Remove this hack once temporaries and their destructors are
173 // modeled correctly by the CFG.
174 if (CXXExprWithTemporaries
*E
= dyn_cast
<CXXExprWithTemporaries
>(S
)) {
175 for (unsigned I
= 0, N
= E
->getNumTemporaries(); I
!= N
; ++I
) {
176 const FunctionDecl
*FD
= E
->getTemporary(I
)->getDestructor();
177 if (FD
->hasAttr
<NoReturnAttr
>() ||
178 FD
->getType()->getAs
<FunctionType
>()->getNoReturnAttr()) {
185 // FIXME: Add noreturn message sends.
186 if (NoReturnEdge
== false)
191 return NeverFallThrough
;
192 return NeverFallThroughOrReturn
;
194 if (HasAbnormalEdge
|| HasFakeEdge
|| HasLiveReturn
)
195 return MaybeFallThrough
;
196 // This says AlwaysFallThrough for calls to functions that are not marked
197 // noreturn, that don't return. If people would like this warning to be more
198 // accurate, such functions should be marked as noreturn.
199 return AlwaysFallThrough
;
204 struct CheckFallThroughDiagnostics
{
205 unsigned diag_MaybeFallThrough_HasNoReturn
;
206 unsigned diag_MaybeFallThrough_ReturnsNonVoid
;
207 unsigned diag_AlwaysFallThrough_HasNoReturn
;
208 unsigned diag_AlwaysFallThrough_ReturnsNonVoid
;
209 unsigned diag_NeverFallThroughOrReturn
;
212 static CheckFallThroughDiagnostics
MakeForFunction(const Decl
*Func
) {
213 CheckFallThroughDiagnostics D
;
214 D
.diag_MaybeFallThrough_HasNoReturn
=
215 diag::warn_falloff_noreturn_function
;
216 D
.diag_MaybeFallThrough_ReturnsNonVoid
=
217 diag::warn_maybe_falloff_nonvoid_function
;
218 D
.diag_AlwaysFallThrough_HasNoReturn
=
219 diag::warn_falloff_noreturn_function
;
220 D
.diag_AlwaysFallThrough_ReturnsNonVoid
=
221 diag::warn_falloff_nonvoid_function
;
223 // Don't suggest that virtual functions be marked "noreturn", since they
224 // might be overridden by non-noreturn functions.
225 bool isVirtualMethod
= false;
226 if (const CXXMethodDecl
*Method
= dyn_cast
<CXXMethodDecl
>(Func
))
227 isVirtualMethod
= Method
->isVirtual();
229 if (!isVirtualMethod
)
230 D
.diag_NeverFallThroughOrReturn
=
231 diag::warn_suggest_noreturn_function
;
233 D
.diag_NeverFallThroughOrReturn
= 0;
239 static CheckFallThroughDiagnostics
MakeForBlock() {
240 CheckFallThroughDiagnostics D
;
241 D
.diag_MaybeFallThrough_HasNoReturn
=
242 diag::err_noreturn_block_has_return_expr
;
243 D
.diag_MaybeFallThrough_ReturnsNonVoid
=
244 diag::err_maybe_falloff_nonvoid_block
;
245 D
.diag_AlwaysFallThrough_HasNoReturn
=
246 diag::err_noreturn_block_has_return_expr
;
247 D
.diag_AlwaysFallThrough_ReturnsNonVoid
=
248 diag::err_falloff_nonvoid_block
;
249 D
.diag_NeverFallThroughOrReturn
=
250 diag::warn_suggest_noreturn_block
;
255 bool checkDiagnostics(Diagnostic
&D
, bool ReturnsVoid
,
256 bool HasNoReturn
) const {
258 return (D
.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function
)
259 == Diagnostic::Ignored
|| ReturnsVoid
)
260 && (D
.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr
)
261 == Diagnostic::Ignored
|| !HasNoReturn
)
262 && (D
.getDiagnosticLevel(diag::warn_suggest_noreturn_block
)
263 == Diagnostic::Ignored
|| !ReturnsVoid
);
267 return ReturnsVoid
&& !HasNoReturn
268 && (D
.getDiagnosticLevel(diag::warn_suggest_noreturn_block
)
269 == Diagnostic::Ignored
|| !ReturnsVoid
);
275 /// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
276 /// function that should return a value. Check that we don't fall off the end
277 /// of a noreturn function. We assume that functions and blocks not marked
278 /// noreturn will return.
279 static void CheckFallThroughForBody(Sema
&S
, const Decl
*D
, const Stmt
*Body
,
281 const CheckFallThroughDiagnostics
& CD
,
282 AnalysisContext
&AC
) {
284 bool ReturnsVoid
= false;
285 bool HasNoReturn
= false;
287 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
288 ReturnsVoid
= FD
->getResultType()->isVoidType();
289 HasNoReturn
= FD
->hasAttr
<NoReturnAttr
>() ||
290 FD
->getType()->getAs
<FunctionType
>()->getNoReturnAttr();
292 else if (const ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(D
)) {
293 ReturnsVoid
= MD
->getResultType()->isVoidType();
294 HasNoReturn
= MD
->hasAttr
<NoReturnAttr
>();
296 else if (isa
<BlockDecl
>(D
)) {
297 if (const FunctionType
*FT
=
298 BlockTy
->getPointeeType()->getAs
<FunctionType
>()) {
299 if (FT
->getResultType()->isVoidType())
301 if (FT
->getNoReturnAttr())
306 Diagnostic
&Diags
= S
.getDiagnostics();
308 // Short circuit for compilation speed.
309 if (CD
.checkDiagnostics(Diags
, ReturnsVoid
, HasNoReturn
))
312 // FIXME: Function try block
313 if (const CompoundStmt
*Compound
= dyn_cast
<CompoundStmt
>(Body
)) {
314 switch (CheckFallThrough(AC
)) {
315 case UnknownFallThrough
:
318 case MaybeFallThrough
:
320 S
.Diag(Compound
->getRBracLoc(),
321 CD
.diag_MaybeFallThrough_HasNoReturn
);
322 else if (!ReturnsVoid
)
323 S
.Diag(Compound
->getRBracLoc(),
324 CD
.diag_MaybeFallThrough_ReturnsNonVoid
);
326 case AlwaysFallThrough
:
328 S
.Diag(Compound
->getRBracLoc(),
329 CD
.diag_AlwaysFallThrough_HasNoReturn
);
330 else if (!ReturnsVoid
)
331 S
.Diag(Compound
->getRBracLoc(),
332 CD
.diag_AlwaysFallThrough_ReturnsNonVoid
);
334 case NeverFallThroughOrReturn
:
335 if (ReturnsVoid
&& !HasNoReturn
&& CD
.diag_NeverFallThroughOrReturn
)
336 S
.Diag(Compound
->getLBracLoc(),
337 CD
.diag_NeverFallThroughOrReturn
);
339 case NeverFallThrough
:
345 //===----------------------------------------------------------------------===//
346 // AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based
347 // warnings on a function, method, or block.
348 //===----------------------------------------------------------------------===//
350 clang::sema::AnalysisBasedWarnings::Policy::Policy() {
351 enableCheckFallThrough
= 1;
352 enableCheckUnreachable
= 0;
355 clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema
&s
) : S(s
) {
356 Diagnostic
&D
= S
.getDiagnostics();
357 DefaultPolicy
.enableCheckUnreachable
= (unsigned)
358 (D
.getDiagnosticLevel(diag::warn_unreachable
) != Diagnostic::Ignored
);
362 AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P
,
363 const Decl
*D
, QualType BlockTy
) {
365 assert(BlockTy
.isNull() || isa
<BlockDecl
>(D
));
367 // We avoid doing analysis-based warnings when there are errors for
369 // (1) The CFGs often can't be constructed (if the body is invalid), so
370 // don't bother trying.
371 // (2) The code already has problems; running the analysis just takes more
373 Diagnostic
&Diags
= S
.getDiagnostics();
375 if (Diags
.hasErrorOccurred() || Diags
.hasFatalErrorOccurred())
378 // Do not do any analysis for declarations in system headers if we are
379 // going to just ignore them.
380 if (Diags
.getSuppressSystemWarnings() &&
381 S
.SourceMgr
.isInSystemHeader(D
->getLocation()))
384 // For code in dependent contexts, we'll do this at instantiation time.
385 if (cast
<DeclContext
>(D
)->isDependentContext())
388 const Stmt
*Body
= D
->getBody();
391 // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
392 // explosion for destrutors that can result and the compile time hit.
393 AnalysisContext
AC(D
, 0, false);
395 // Warning: check missing 'return'
396 if (P
.enableCheckFallThrough
) {
397 const CheckFallThroughDiagnostics
&CD
=
398 (isa
<BlockDecl
>(D
) ? CheckFallThroughDiagnostics::MakeForBlock()
399 : CheckFallThroughDiagnostics::MakeForFunction(D
));
400 CheckFallThroughForBody(S
, D
, Body
, BlockTy
, CD
, AC
);
403 // Warning: check for unreachable code
404 if (P
.enableCheckUnreachable
)
405 CheckUnreachable(S
, AC
);
409 AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P
,
410 const BlockExpr
*E
) {
411 return IssueWarnings(P
, E
->getBlockDecl(), E
->getType());
415 AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P
,
416 const ObjCMethodDecl
*D
) {
417 return IssueWarnings(P
, D
, QualType());
421 AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P
,
422 const FunctionDecl
*D
) {
423 return IssueWarnings(P
, D
, QualType());