1 //=- ReachableCodePathInsensitive.cpp ---------------------------*- 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 implements a flow-sensitive, path-insensitive analysis of
11 // determining reachable blocks within a CFG.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/Analysis/Analyses/ReachableCode.h"
16 #include "clang/AST/Expr.h"
17 #include "clang/AST/ExprCXX.h"
18 #include "clang/AST/ExprObjC.h"
19 #include "clang/AST/StmtCXX.h"
20 #include "clang/Analysis/AnalysisContext.h"
21 #include "clang/Analysis/CFG.h"
22 #include "clang/Basic/SourceManager.h"
23 #include "llvm/ADT/BitVector.h"
24 #include "llvm/ADT/SmallVector.h"
25 
26 using namespace clang;
27 
28 namespace {
29 class DeadCodeScan {
30   llvm::BitVector Visited;
31   llvm::BitVector &Reachable;
32   SmallVector<const CFGBlock *, 10> WorkList;
33 
34   typedef SmallVector<std::pair<const CFGBlock *, const Stmt *>, 12>
35       DeferredLocsTy;
36 
37   DeferredLocsTy DeferredLocs;
38 
39 public:
40   DeadCodeScan(llvm::BitVector &reachable)
41     : Visited(reachable.size()),
42       Reachable(reachable) {}
43 
44   void enqueue(const CFGBlock *block);
45   unsigned scanBackwards(const CFGBlock *Start,
46                          clang::reachable_code::Callback &CB);
47 
48   bool isDeadCodeRoot(const CFGBlock *Block);
49 
50   const Stmt *findDeadCode(const CFGBlock *Block);
51 
52   void reportDeadCode(const CFGBlock *B,
53                       const Stmt *S,
54                       clang::reachable_code::Callback &CB);
55 };
56 }
57 
58 void DeadCodeScan::enqueue(const CFGBlock *block) {
59   unsigned blockID = block->getBlockID();
60   if (Reachable[blockID] || Visited[blockID])
61     return;
62   Visited[blockID] = true;
63   WorkList.push_back(block);
64 }
65 
66 bool DeadCodeScan::isDeadCodeRoot(const clang::CFGBlock *Block) {
67   bool isDeadRoot = true;
68 
69   for (CFGBlock::const_pred_iterator I = Block->pred_begin(),
70         E = Block->pred_end(); I != E; ++I) {
71     if (const CFGBlock *PredBlock = *I) {
72       unsigned blockID = PredBlock->getBlockID();
73       if (Visited[blockID]) {
74         isDeadRoot = false;
75         continue;
76       }
77       if (!Reachable[blockID]) {
78         isDeadRoot = false;
79         Visited[blockID] = true;
80         WorkList.push_back(PredBlock);
81         continue;
82       }
83     }
84   }
85 
86   return isDeadRoot;
87 }
88 
89 static bool isValidDeadStmt(const Stmt *S) {
90   if (S->getLocStart().isInvalid())
91     return false;
92   if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(S))
93     return BO->getOpcode() != BO_Comma;
94   return true;
95 }
96 
97 const Stmt *DeadCodeScan::findDeadCode(const clang::CFGBlock *Block) {
98   for (CFGBlock::const_iterator I = Block->begin(), E = Block->end(); I!=E; ++I)
99     if (Optional<CFGStmt> CS = I->getAs<CFGStmt>()) {
100       const Stmt *S = CS->getStmt();
101       if (isValidDeadStmt(S))
102         return S;
103     }
104 
105   if (CFGTerminator T = Block->getTerminator()) {
106     const Stmt *S = T.getStmt();
107     if (isValidDeadStmt(S))
108       return S;
109   }
110 
111   return 0;
112 }
113 
114 static int SrcCmp(const std::pair<const CFGBlock *, const Stmt *> *p1,
115                   const std::pair<const CFGBlock *, const Stmt *> *p2) {
116   if (p1->second->getLocStart() < p2->second->getLocStart())
117     return -1;
118   if (p2->second->getLocStart() < p1->second->getLocStart())
119     return 1;
120   return 0;
121 }
122 
123 unsigned DeadCodeScan::scanBackwards(const clang::CFGBlock *Start,
124                                      clang::reachable_code::Callback &CB) {
125 
126   unsigned count = 0;
127   enqueue(Start);
128 
129   while (!WorkList.empty()) {
130     const CFGBlock *Block = WorkList.pop_back_val();
131 
132     // It is possible that this block has been marked reachable after
133     // it was enqueued.
134     if (Reachable[Block->getBlockID()])
135       continue;
136 
137     // Look for any dead code within the block.
138     const Stmt *S = findDeadCode(Block);
139 
140     if (!S) {
141       // No dead code.  Possibly an empty block.  Look at dead predecessors.
142       for (CFGBlock::const_pred_iterator I = Block->pred_begin(),
143            E = Block->pred_end(); I != E; ++I) {
144         if (const CFGBlock *predBlock = *I)
145           enqueue(predBlock);
146       }
147       continue;
148     }
149 
150     // Specially handle macro-expanded code.
151     if (S->getLocStart().isMacroID()) {
152       count += clang::reachable_code::ScanReachableFromBlock(Block, Reachable);
153       continue;
154     }
155 
156     if (isDeadCodeRoot(Block)) {
157       reportDeadCode(Block, S, CB);
158       count += clang::reachable_code::ScanReachableFromBlock(Block, Reachable);
159     }
160     else {
161       // Record this statement as the possibly best location in a
162       // strongly-connected component of dead code for emitting a
163       // warning.
164       DeferredLocs.push_back(std::make_pair(Block, S));
165     }
166   }
167 
168   // If we didn't find a dead root, then report the dead code with the
169   // earliest location.
170   if (!DeferredLocs.empty()) {
171     llvm::array_pod_sort(DeferredLocs.begin(), DeferredLocs.end(), SrcCmp);
172     for (DeferredLocsTy::iterator I = DeferredLocs.begin(),
173           E = DeferredLocs.end(); I != E; ++I) {
174       const CFGBlock *Block = I->first;
175       if (Reachable[Block->getBlockID()])
176         continue;
177       reportDeadCode(Block, I->second, CB);
178       count += clang::reachable_code::ScanReachableFromBlock(Block, Reachable);
179     }
180   }
181 
182   return count;
183 }
184 
185 static SourceLocation GetUnreachableLoc(const Stmt *S,
186                                         SourceRange &R1,
187                                         SourceRange &R2) {
188   R1 = R2 = SourceRange();
189 
190   if (const Expr *Ex = dyn_cast<Expr>(S))
191     S = Ex->IgnoreParenImpCasts();
192 
193   switch (S->getStmtClass()) {
194     case Expr::BinaryOperatorClass: {
195       const BinaryOperator *BO = cast<BinaryOperator>(S);
196       return BO->getOperatorLoc();
197     }
198     case Expr::UnaryOperatorClass: {
199       const UnaryOperator *UO = cast<UnaryOperator>(S);
200       R1 = UO->getSubExpr()->getSourceRange();
201       return UO->getOperatorLoc();
202     }
203     case Expr::CompoundAssignOperatorClass: {
204       const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(S);
205       R1 = CAO->getLHS()->getSourceRange();
206       R2 = CAO->getRHS()->getSourceRange();
207       return CAO->getOperatorLoc();
208     }
209     case Expr::BinaryConditionalOperatorClass:
210     case Expr::ConditionalOperatorClass: {
211       const AbstractConditionalOperator *CO =
212         cast<AbstractConditionalOperator>(S);
213       return CO->getQuestionLoc();
214     }
215     case Expr::MemberExprClass: {
216       const MemberExpr *ME = cast<MemberExpr>(S);
217       R1 = ME->getSourceRange();
218       return ME->getMemberLoc();
219     }
220     case Expr::ArraySubscriptExprClass: {
221       const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(S);
222       R1 = ASE->getLHS()->getSourceRange();
223       R2 = ASE->getRHS()->getSourceRange();
224       return ASE->getRBracketLoc();
225     }
226     case Expr::CStyleCastExprClass: {
227       const CStyleCastExpr *CSC = cast<CStyleCastExpr>(S);
228       R1 = CSC->getSubExpr()->getSourceRange();
229       return CSC->getLParenLoc();
230     }
231     case Expr::CXXFunctionalCastExprClass: {
232       const CXXFunctionalCastExpr *CE = cast <CXXFunctionalCastExpr>(S);
233       R1 = CE->getSubExpr()->getSourceRange();
234       return CE->getLocStart();
235     }
236     case Stmt::CXXTryStmtClass: {
237       return cast<CXXTryStmt>(S)->getHandler(0)->getCatchLoc();
238     }
239     case Expr::ObjCBridgedCastExprClass: {
240       const ObjCBridgedCastExpr *CSC = cast<ObjCBridgedCastExpr>(S);
241       R1 = CSC->getSubExpr()->getSourceRange();
242       return CSC->getLParenLoc();
243     }
244     default: ;
245   }
246   R1 = S->getSourceRange();
247   return S->getLocStart();
248 }
249 
250 static bool bodyEndsWithNoReturn(const CFGBlock *B) {
251   for (CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend();
252        I != E; ++I) {
253     if (Optional<CFGStmt> CS = I->getAs<CFGStmt>()) {
254       if (const CallExpr *CE = dyn_cast<CallExpr>(CS->getStmt())) {
255         QualType CalleeType = CE->getCallee()->getType();
256         if (getFunctionExtInfo(*CalleeType).getNoReturn())
257           return true;
258       }
259       break;
260     }
261   }
262   return false;
263 }
264 
265 static bool bodyEndsWithNoReturn(const CFGBlock::AdjacentBlock &AB) {
266   const CFGBlock *Pred = AB.getPossiblyUnreachableBlock();
267   assert(!AB.isReachable() && Pred);
268   return bodyEndsWithNoReturn(Pred);
269 }
270 
271 static bool isBreakPrecededByNoReturn(const CFGBlock *B,
272                                       const Stmt *S) {
273   if (!isa<BreakStmt>(S) || B->pred_empty())
274     return false;
275 
276   assert(B->empty());
277   assert(B->pred_size() == 1);
278   return bodyEndsWithNoReturn(*B->pred_begin());
279 }
280 
281 static bool isEnumConstant(const Expr *Ex) {
282   const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex);
283   if (!DR)
284     return false;
285   return isa<EnumConstantDecl>(DR->getDecl());
286 }
287 
288 static bool isTrivialExpression(const Expr *Ex) {
289   return isa<IntegerLiteral>(Ex) || isa<StringLiteral>(Ex) ||
290          isEnumConstant(Ex);
291 }
292 
293 static bool isTrivialReturnPrecededByNoReturn(const CFGBlock *B,
294                                               const Stmt *S) {
295   if (B->pred_empty())
296     return false;
297 
298   const Expr *Ex = dyn_cast<Expr>(S);
299   if (!Ex)
300     return false;
301 
302   Ex = Ex->IgnoreParenCasts();
303 
304   if (!isTrivialExpression(Ex))
305     return false;
306 
307   // Look to see if the block ends with a 'return', and see if 'S'
308   // is a substatement.  The 'return' may not be the last element in
309   // the block because of destructors.
310   assert(!B->empty());
311   for (CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend();
312        I != E; ++I) {
313     if (Optional<CFGStmt> CS = I->getAs<CFGStmt>()) {
314       if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(CS->getStmt())) {
315         const Expr *RE = RS->getRetValue();
316         if (RE && RE->IgnoreParenCasts() == Ex)
317           break;
318       }
319       return false;
320     }
321   }
322 
323   assert(B->pred_size() == 1);
324   return bodyEndsWithNoReturn(*B->pred_begin());
325 }
326 
327 void DeadCodeScan::reportDeadCode(const CFGBlock *B,
328                                   const Stmt *S,
329                                   clang::reachable_code::Callback &CB) {
330   // Suppress idiomatic cases of calling a noreturn function just
331   // before executing a 'break'.  If there is other code after the 'break'
332   // in the block then don't suppress the warning.
333   if (isBreakPrecededByNoReturn(B, S))
334     return;
335 
336   // Suppress trivial 'return' statements that are dead.
337   if (isTrivialReturnPrecededByNoReturn(B, S))
338     return;
339 
340   SourceRange R1, R2;
341   SourceLocation Loc = GetUnreachableLoc(S, R1, R2);
342   CB.HandleUnreachable(Loc, R1, R2);
343 }
344 
345 namespace clang { namespace reachable_code {
346 
347 void Callback::anchor() { }
348 
349 unsigned ScanReachableFromBlock(const CFGBlock *Start,
350                                 llvm::BitVector &Reachable) {
351   unsigned count = 0;
352 
353   // Prep work queue
354   SmallVector<const CFGBlock*, 32> WL;
355 
356   // The entry block may have already been marked reachable
357   // by the caller.
358   if (!Reachable[Start->getBlockID()]) {
359     ++count;
360     Reachable[Start->getBlockID()] = true;
361   }
362 
363   WL.push_back(Start);
364 
365   // Find the reachable blocks from 'Start'.
366   while (!WL.empty()) {
367     const CFGBlock *item = WL.pop_back_val();
368 
369     // Look at the successors and mark then reachable.
370     for (CFGBlock::const_succ_iterator I = item->succ_begin(),
371          E = item->succ_end(); I != E; ++I) {
372       const CFGBlock *B = *I;
373       if (!B) {
374         //
375         // For switch statements, treat all cases as being reachable.
376         // There are many cases where a switch can contain values that
377         // are not in an enumeration but they are still reachable because
378         // other values are possible.
379         //
380         // Note that this is quite conservative.  If one saw:
381         //
382         //  switch (1) {
383         //    case 2: ...
384         //
385         // we should be able to say that 'case 2' is unreachable.  To do
386         // this we can either put more heuristics here, or possibly retain
387         // that information in the CFG itself.
388         //
389         if (const CFGBlock *UB = I->getPossiblyUnreachableBlock()) {
390           const Stmt *Label = UB->getLabel();
391           if (Label && isa<SwitchCase>(Label)) {
392             B = UB;
393           }
394         }
395       }
396       if (B) {
397         unsigned blockID = B->getBlockID();
398         if (!Reachable[blockID]) {
399           Reachable.set(blockID);
400           WL.push_back(B);
401           ++count;
402         }
403       }
404     }
405   }
406   return count;
407 }
408 
409 void FindUnreachableCode(AnalysisDeclContext &AC, Callback &CB) {
410   CFG *cfg = AC.getCFG();
411   if (!cfg)
412     return;
413 
414   // Scan for reachable blocks from the entrance of the CFG.
415   // If there are no unreachable blocks, we're done.
416   llvm::BitVector reachable(cfg->getNumBlockIDs());
417   unsigned numReachable = ScanReachableFromBlock(&cfg->getEntry(), reachable);
418   if (numReachable == cfg->getNumBlockIDs())
419     return;
420 
421   // If there aren't explicit EH edges, we should include the 'try' dispatch
422   // blocks as roots.
423   if (!AC.getCFGBuildOptions().AddEHEdges) {
424     for (CFG::try_block_iterator I = cfg->try_blocks_begin(),
425          E = cfg->try_blocks_end() ; I != E; ++I) {
426       numReachable += ScanReachableFromBlock(*I, reachable);
427     }
428     if (numReachable == cfg->getNumBlockIDs())
429       return;
430   }
431 
432   // There are some unreachable blocks.  We need to find the root blocks that
433   // contain code that should be considered unreachable.
434   for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
435     const CFGBlock *block = *I;
436     // A block may have been marked reachable during this loop.
437     if (reachable[block->getBlockID()])
438       continue;
439 
440     DeadCodeScan DS(reachable);
441     numReachable += DS.scanBackwards(block, CB);
442 
443     if (numReachable == cfg->getNumBlockIDs())
444       return;
445   }
446 }
447 
448 }} // end namespace clang::reachable_code
449