void DeadCodeScan::reportDeadCode(const CFGBlock *B, const Stmt *S, clang::reachable_code::Callback &CB) { // Classify the unreachable code found, or suppress it in some cases. reachable_code::UnreachableKind UK = reachable_code::UK_Other; if (isa<BreakStmt>(S)) { UK = reachable_code::UK_Break; } else if (isTrivialDoWhile(B, S)) { return; } else if (isDeadReturn(B, S)) { UK = reachable_code::UK_Return; } SourceRange SilenceableCondVal; if (UK == reachable_code::UK_Other) { // Check if the dead code is part of the "loop target" of // a for/for-range loop. This is the block that contains // the increment code. if (const Stmt *LoopTarget = B->getLoopTarget()) { SourceLocation Loc = LoopTarget->getLocStart(); SourceRange R1(Loc, Loc), R2; if (const ForStmt *FS = dyn_cast<ForStmt>(LoopTarget)) { const Expr *Inc = FS->getInc(); Loc = Inc->getLocStart(); R2 = Inc->getSourceRange(); } CB.HandleUnreachable(reachable_code::UK_Loop_Increment, Loc, SourceRange(), SourceRange(Loc, Loc), R2); return; } // Check if the dead block has a predecessor whose branch has // a configuration value that *could* be modified to // silence the warning. CFGBlock::const_pred_iterator PI = B->pred_begin(); if (PI != B->pred_end()) { if (const CFGBlock *PredBlock = PI->getPossiblyUnreachableBlock()) { const Stmt *TermCond = PredBlock->getTerminatorCondition(/* strip parens */ false); isConfigurationValue(TermCond, PP, &SilenceableCondVal); } } } SourceRange R1, R2; SourceLocation Loc = GetUnreachableLoc(S, R1, R2); CB.HandleUnreachable(UK, Loc, SilenceableCondVal, R1, R2); }
void DeadCodeScan::reportDeadCode(const CFGBlock *B, const Stmt *S, clang::reachable_code::Callback &CB) { // Classify the unreachable code found, or suppress it in some cases. reachable_code::UnreachableKind UK = reachable_code::UK_Other; if (isa<BreakStmt>(S)) { UK = reachable_code::UK_Break; } else if (isTrivialDoWhile(B, S)) { return; } else if (isDeadReturn(B, S)) { UK = reachable_code::UK_Return; } if (UK == reachable_code::UK_Other) { // Check if the dead code is part of the "loop target" of // a for/for-range loop. This is the block that contains // the increment code. if (const Stmt *LoopTarget = B->getLoopTarget()) { SourceLocation Loc = LoopTarget->getLocStart(); SourceRange R1(Loc, Loc), R2; if (const ForStmt *FS = dyn_cast<ForStmt>(LoopTarget)) { const Expr *Inc = FS->getInc(); Loc = Inc->getLocStart(); R2 = Inc->getSourceRange(); } CB.HandleUnreachable(reachable_code::UK_Loop_Increment, Loc, SourceRange(Loc, Loc), R2); return; } } SourceRange R1, R2; SourceLocation Loc = GetUnreachableLoc(S, R1, R2); CB.HandleUnreachable(UK, Loc, R1, R2); }
void DeadCodeScan::reportDeadCode(const CFGBlock *B, const Stmt *S, clang::reachable_code::Callback &CB) { // Suppress idiomatic cases of calling a noreturn function just // before executing a 'break'. If there is other code after the 'break' // in the block then don't suppress the warning. if (isBreakPrecededByNoReturn(B, S)) return; // Suppress trivial 'return' statements that are dead. if (isTrivialReturnOrDoWhile(B, S)) return; SourceRange R1, R2; SourceLocation Loc = GetUnreachableLoc(S, R1, R2); CB.HandleUnreachable(Loc, R1, R2); }
void DeadCodeScan::reportDeadCode(const Stmt *S, clang::reachable_code::Callback &CB) { SourceRange R1, R2; SourceLocation Loc = GetUnreachableLoc(S, R1, R2); CB.HandleUnreachable(Loc, R1, R2); }