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