AnalysisBasedWarnings.cpp revision d068aabc484c4009282122c6ef26e66e68cfa044
1dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis -*- C++ -*-=// 2dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// 3dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// The LLVM Compiler Infrastructure 4dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// 5dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// This file is distributed under the University of Illinois Open Source 6dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// License. See LICENSE.TXT for details. 7dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// 8dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 9dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// 10dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// This file defines analysis_warnings::[Policy,Executor]. 11dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Together they are used by Sema to issue warnings based on inexpensive 12dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// static analysis algorithms in libAnalysis. 13dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// 14dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 15dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 16dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "Sema.h" 17dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "AnalysisBasedWarnings.h" 18d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek#include "clang/Basic/SourceManager.h" 19dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/ExprObjC.h" 20dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/ExprCXX.h" 21dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/StmtObjC.h" 22dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/StmtCXX.h" 23dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/AnalysisContext.h" 24dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/CFG.h" 25dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/Analyses/ReachableCode.h" 26dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/ADT/BitVector.h" 27dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/Support/Casting.h" 28dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include <queue> 29dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 30dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekusing namespace clang; 31dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 32dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 33dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Unreachable code analysis. 34dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 35dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 36dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremeneknamespace { 37dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek class UnreachableCodeHandler : public reachable_code::Callback { 38dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Sema &S; 39dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek public: 40dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek UnreachableCodeHandler(Sema &s) : S(s) {} 41dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 42dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) { 43dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(L, diag::warn_unreachable) << R1 << R2; 44dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 45dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek }; 46dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 47dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 48dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckUnreachable - Check for unreachable code. 49dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckUnreachable(Sema &S, AnalysisContext &AC) { 50dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek UnreachableCodeHandler UC(S); 51dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek reachable_code::FindUnreachableCode(AC, UC); 52dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 53dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 54dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 55dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Check for missing return value. 56dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 57dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 58dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekenum ControlFlowKind { NeverFallThrough = 0, MaybeFallThrough = 1, 59dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek AlwaysFallThrough = 2, NeverFallThroughOrReturn = 3 }; 60dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 61dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThrough - Check that we don't fall off the end of a 62dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// Statement that should return a value. 63dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// 64dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// \returns AlwaysFallThrough iff we always fall off the end of the statement, 65dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// MaybeFallThrough iff we might or might not fall off the end, 66dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// NeverFallThroughOrReturn iff we never fall off the end of the statement or 67dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// return. We assume NeverFallThrough iff we never fall off the end of the 68dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// statement but we may return. We assume that functions not marked noreturn 69dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// will return. 70dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic ControlFlowKind CheckFallThrough(AnalysisContext &AC) { 71dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CFG *cfg = AC.getCFG(); 72dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (cfg == 0) 73dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // FIXME: This should be NeverFallThrough 74dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return NeverFallThroughOrReturn; 75dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 76dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // The CFG leaves in dead things, and we don't want the dead code paths to 77dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // confuse us, so we mark all live things first. 78dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek std::queue<CFGBlock*> workq; 79dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek llvm::BitVector live(cfg->getNumBlockIDs()); 80dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned count = reachable_code::ScanReachableFromBlock(cfg->getEntry(), 81dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek live); 82dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 83dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool AddEHEdges = AC.getAddEHEdges(); 84dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!AddEHEdges && count != cfg->getNumBlockIDs()) 85dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // When there are things remaining dead, and we didn't add EH edges 86dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // from CallExprs to the catch clauses, we have to go back and 87dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // mark them as live. 88dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) { 89dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CFGBlock &b = **I; 90dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!live[b.getBlockID()]) { 91dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (b.pred_begin() == b.pred_end()) { 92dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator())) 93dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // When not adding EH edges from calls, catch clauses 94dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // can otherwise seem dead. Avoid noting them as dead. 95dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek count += reachable_code::ScanReachableFromBlock(b, live); 96dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 97dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 98dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 99dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 100dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 101dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Now we know what is live, we check the live precessors of the exit block 102dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // and look for fall through paths, being careful to ignore normal returns, 103dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // and exceptional paths. 104dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasLiveReturn = false; 105dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasFakeEdge = false; 106dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasPlainEdge = false; 107dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasAbnormalEdge = false; 108dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek for (CFGBlock::pred_iterator I=cfg->getExit().pred_begin(), 109dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek E = cfg->getExit().pred_end(); 110dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek I != E; 111dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ++I) { 112dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CFGBlock& B = **I; 113dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!live[B.getBlockID()]) 114dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 115dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (B.size() == 0) { 116dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) { 117dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 118dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 119dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 120dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 121dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // A labeled empty statement, or the entry block... 122dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasPlainEdge = true; 123dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 124dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 125dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Stmt *S = B[B.size()-1]; 126dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<ReturnStmt>(S)) { 127dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasLiveReturn = true; 128dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 129dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 130dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<ObjCAtThrowStmt>(S)) { 131dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 132dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 133dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 134dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<CXXThrowExpr>(S)) { 135dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 136dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 137dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 138dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) { 139dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (AS->isMSAsm()) { 140dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 141dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasLiveReturn = true; 142dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 143dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 144dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 145dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<CXXTryStmt>(S)) { 146dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 147dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 148dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 149dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 150dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool NoReturnEdge = false; 151dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (CallExpr *C = dyn_cast<CallExpr>(S)) { 152dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (B.succ_begin()[0] != &cfg->getExit()) { 153dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 154dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 155dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 156dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Expr *CEE = C->getCallee()->IgnoreParenCasts(); 157dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (CEE->getType().getNoReturnAttr()) { 158dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek NoReturnEdge = true; 159dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 160dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) { 161dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ValueDecl *VD = DRE->getDecl(); 162dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (VD->hasAttr<NoReturnAttr>()) { 163dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek NoReturnEdge = true; 164dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 165dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 166dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 167dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 168dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // FIXME: Add noreturn message sends. 169dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (NoReturnEdge == false) 170dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasPlainEdge = true; 171dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 172dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!HasPlainEdge) { 173dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasLiveReturn) 174dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return NeverFallThrough; 175dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return NeverFallThroughOrReturn; 176dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 177dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn) 178dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return MaybeFallThrough; 179dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // This says AlwaysFallThrough for calls to functions that are not marked 180dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // noreturn, that don't return. If people would like this warning to be more 181dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // accurate, such functions should be marked as noreturn. 182dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return AlwaysFallThrough; 183dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 184dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 185dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstruct CheckFallThroughDiagnostics { 186dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_MaybeFallThrough_HasNoReturn; 187dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_MaybeFallThrough_ReturnsNonVoid; 188dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_AlwaysFallThrough_HasNoReturn; 189dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_AlwaysFallThrough_ReturnsNonVoid; 190dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_NeverFallThroughOrReturn; 191dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool funMode; 192dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 193dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek static CheckFallThroughDiagnostics MakeForFunction() { 194dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughDiagnostics D; 195dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_HasNoReturn = 196dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_noreturn_function; 197dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_ReturnsNonVoid = 198dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_maybe_falloff_nonvoid_function; 199dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_HasNoReturn = 200dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_noreturn_function; 201dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_ReturnsNonVoid = 202dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_nonvoid_function; 203dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_NeverFallThroughOrReturn = 204dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_suggest_noreturn_function; 205dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.funMode = true; 206dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return D; 207dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 208dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 209dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek static CheckFallThroughDiagnostics MakeForBlock() { 210dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughDiagnostics D; 211dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_HasNoReturn = 212dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_noreturn_block_has_return_expr; 213dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_ReturnsNonVoid = 214dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_maybe_falloff_nonvoid_block; 215dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_HasNoReturn = 216dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_noreturn_block_has_return_expr; 217dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_ReturnsNonVoid = 218dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_falloff_nonvoid_block; 219dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_NeverFallThroughOrReturn = 220dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_suggest_noreturn_block; 221dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.funMode = false; 222dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return D; 223dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 224dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 225dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool checkDiagnostics(Diagnostic &D, bool ReturnsVoid, 226dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasNoReturn) const { 227dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (funMode) { 228dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return (D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function) 229dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek == Diagnostic::Ignored || ReturnsVoid) 230dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek && (D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr) 231dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek == Diagnostic::Ignored || !HasNoReturn) 232dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block) 233dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek == Diagnostic::Ignored || !ReturnsVoid); 234dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 235dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 236dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // For blocks. 237dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return ReturnsVoid && !HasNoReturn 238dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek && (D.getDiagnosticLevel(diag::warn_suggest_noreturn_block) 239dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek == Diagnostic::Ignored || !ReturnsVoid); 240dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 241dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}; 242dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 243dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a 244dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// function that should return a value. Check that we don't fall off the end 245dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// of a noreturn function. We assume that functions and blocks not marked 246dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// noreturn will return. 247dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, 248dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek QualType BlockTy, 249dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const CheckFallThroughDiagnostics& CD, 250dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek AnalysisContext &AC) { 251dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 252dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool ReturnsVoid = false; 253dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasNoReturn = false; 254dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 255dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 256dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = FD->getResultType()->isVoidType(); 257dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = FD->hasAttr<NoReturnAttr>() || 258dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek FD->getType()->getAs<FunctionType>()->getNoReturnAttr(); 259dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 260dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 261dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = MD->getResultType()->isVoidType(); 262dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = MD->hasAttr<NoReturnAttr>(); 263dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 264dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (isa<BlockDecl>(D)) { 265dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const FunctionType *FT = 266dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek BlockTy->getPointeeType()->getAs<FunctionType>()) { 267dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (FT->getResultType()->isVoidType()) 268dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = true; 269dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (FT->getNoReturnAttr()) 270dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = true; 271dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 272dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 273dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 274dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Diagnostic &Diags = S.getDiagnostics(); 275dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 276dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Short circuit for compilation speed. 277dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn)) 278dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return; 279dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 280dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // FIXME: Function try block 281dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { 282dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek switch (CheckFallThrough(AC)) { 283dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case MaybeFallThrough: 284dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasNoReturn) 285dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 286dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_MaybeFallThrough_HasNoReturn); 287dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (!ReturnsVoid) 288dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 289dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_MaybeFallThrough_ReturnsNonVoid); 290dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 291dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case AlwaysFallThrough: 292dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasNoReturn) 293dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 294dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_AlwaysFallThrough_HasNoReturn); 295dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (!ReturnsVoid) 296dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 297dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_AlwaysFallThrough_ReturnsNonVoid); 298dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 299dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case NeverFallThroughOrReturn: 300dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (ReturnsVoid && !HasNoReturn) 301dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getLBracLoc(), 302dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_NeverFallThroughOrReturn); 303dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 304dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case NeverFallThrough: 305dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 306dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 307dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 308dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 309dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 310dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 311dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based 312dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// warnings on a function, method, or block. 313dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 314dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 315dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekclang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s) { 316dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Diagnostic &D = S.getDiagnostics(); 317dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 318dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek enableCheckFallThrough = 1; 319dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 320dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek enableCheckUnreachable = (unsigned) 321dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek (D.getDiagnosticLevel(diag::warn_unreachable) != Diagnostic::Ignored); 322dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 323dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 324dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekvoid clang::sema::AnalysisBasedWarnings::IssueWarnings(const Decl *D, 325dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek QualType BlockTy) { 326dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 327dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek assert(BlockTy.isNull() || isa<BlockDecl>(D)); 328dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 329d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek // Do not do any analysis for declarations in system headers if we are 330d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek // going to just ignore them. 331d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek if (S.getDiagnostics().getSuppressSystemWarnings() && 332d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek S.SourceMgr.isInSystemHeader(D->getLocation())) 333d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek return; 334d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek 335dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // We avoid doing analysis-based warnings when there are errors for 336dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // two reasons: 337dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // (1) The CFGs often can't be constructed (if the body is invalid), so 338dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // don't bother trying. 339dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // (2) The code already has problems; running the analysis just takes more 340dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // time. 341dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (S.getDiagnostics().hasErrorOccurred()) 342dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return; 343dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 344dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 345dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // For function templates, class templates and member function templates 346dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // we'll do the analysis at instantiation time. 347dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (FD->isDependentContext()) 348dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return; 349dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 350dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 351dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const Stmt *Body = D->getBody(); 352dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek assert(Body); 353dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 354dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Don't generate EH edges for CallExprs as we'd like to avoid the n^2 355dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // explosion for destrutors that can result and the compile time hit. 356dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek AnalysisContext AC(D, false); 357dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 358dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Warning: check missing 'return' 359dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (enableCheckFallThrough) { 360dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const CheckFallThroughDiagnostics &CD = 361dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock() 362dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek : CheckFallThroughDiagnostics::MakeForFunction()); 363dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughForBody(S, D, Body, BlockTy, CD, AC); 364dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 365dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 366dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Warning: check for unreachable code 367dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (enableCheckUnreachable) 368dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckUnreachable(S, AC); 369dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 370