AnalysisBasedWarnings.cpp revision a8c17a5babab35f2db26bf218e7571d1af4afedf
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 16e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "clang/Sema/AnalysisBasedWarnings.h" 172d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h" 18d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek#include "clang/Basic/SourceManager.h" 19fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek#include "clang/Lex/Preprocessor.h" 207cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCall#include "clang/AST/DeclObjC.h" 21384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h" 22dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/ExprObjC.h" 23dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/ExprCXX.h" 24dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/StmtObjC.h" 25dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/StmtCXX.h" 26dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/AnalysisContext.h" 27dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/CFG.h" 28dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/Analyses/ReachableCode.h" 29610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek#include "clang/Analysis/Analyses/UninitializedValuesV2.h" 30dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/ADT/BitVector.h" 31dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/Support/Casting.h" 32dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 33dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekusing namespace clang; 34dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 35dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 36dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Unreachable code analysis. 37dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 38dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 39dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremeneknamespace { 40dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek class UnreachableCodeHandler : public reachable_code::Callback { 41dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Sema &S; 42dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek public: 43dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek UnreachableCodeHandler(Sema &s) : S(s) {} 44dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 45dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) { 46dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(L, diag::warn_unreachable) << R1 << R2; 47dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 48dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek }; 49dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 50dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 51dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckUnreachable - Check for unreachable code. 52dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckUnreachable(Sema &S, AnalysisContext &AC) { 53dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek UnreachableCodeHandler UC(S); 54dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek reachable_code::FindUnreachableCode(AC, UC); 55dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 56dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 57dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 58dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Check for missing return value. 59dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 60dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 6116565aa95b086fb239baf82335dccc1b1ec93942John McCallenum ControlFlowKind { 6216565aa95b086fb239baf82335dccc1b1ec93942John McCall UnknownFallThrough, 6316565aa95b086fb239baf82335dccc1b1ec93942John McCall NeverFallThrough, 6416565aa95b086fb239baf82335dccc1b1ec93942John McCall MaybeFallThrough, 6516565aa95b086fb239baf82335dccc1b1ec93942John McCall AlwaysFallThrough, 6616565aa95b086fb239baf82335dccc1b1ec93942John McCall NeverFallThroughOrReturn 6716565aa95b086fb239baf82335dccc1b1ec93942John McCall}; 68dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 69dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThrough - Check that we don't fall off the end of a 70dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// Statement that should return a value. 71dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// 72dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// \returns AlwaysFallThrough iff we always fall off the end of the statement, 73dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// MaybeFallThrough iff we might or might not fall off the end, 74dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// NeverFallThroughOrReturn iff we never fall off the end of the statement or 75dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// return. We assume NeverFallThrough iff we never fall off the end of the 76dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// statement but we may return. We assume that functions not marked noreturn 77dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// will return. 78dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic ControlFlowKind CheckFallThrough(AnalysisContext &AC) { 79dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CFG *cfg = AC.getCFG(); 8016565aa95b086fb239baf82335dccc1b1ec93942John McCall if (cfg == 0) return UnknownFallThrough; 81dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 82dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // The CFG leaves in dead things, and we don't want the dead code paths to 83dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // confuse us, so we mark all live things first. 84dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek llvm::BitVector live(cfg->getNumBlockIDs()); 85dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned count = reachable_code::ScanReachableFromBlock(cfg->getEntry(), 86dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek live); 87dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 88dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool AddEHEdges = AC.getAddEHEdges(); 89dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!AddEHEdges && count != cfg->getNumBlockIDs()) 90dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // When there are things remaining dead, and we didn't add EH edges 91dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // from CallExprs to the catch clauses, we have to go back and 92dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // mark them as live. 93dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) { 94dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CFGBlock &b = **I; 95dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!live[b.getBlockID()]) { 96dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (b.pred_begin() == b.pred_end()) { 97dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator())) 98dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // When not adding EH edges from calls, catch clauses 99dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // can otherwise seem dead. Avoid noting them as dead. 100dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek count += reachable_code::ScanReachableFromBlock(b, live); 101dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 102dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 103dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 104dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 105dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 106dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Now we know what is live, we check the live precessors of the exit block 107dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // and look for fall through paths, being careful to ignore normal returns, 108dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // and exceptional paths. 109dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasLiveReturn = false; 110dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasFakeEdge = false; 111dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasPlainEdge = false; 112dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasAbnormalEdge = false; 11390b828aa279542559f655d1af666580288cb1841Ted Kremenek 11490b828aa279542559f655d1af666580288cb1841Ted Kremenek // Ignore default cases that aren't likely to be reachable because all 11590b828aa279542559f655d1af666580288cb1841Ted Kremenek // enums in a switch(X) have explicit case statements. 11690b828aa279542559f655d1af666580288cb1841Ted Kremenek CFGBlock::FilterOptions FO; 11790b828aa279542559f655d1af666580288cb1841Ted Kremenek FO.IgnoreDefaultsWithCoveredEnums = 1; 11890b828aa279542559f655d1af666580288cb1841Ted Kremenek 11990b828aa279542559f655d1af666580288cb1841Ted Kremenek for (CFGBlock::filtered_pred_iterator 12090b828aa279542559f655d1af666580288cb1841Ted Kremenek I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) { 12190b828aa279542559f655d1af666580288cb1841Ted Kremenek const CFGBlock& B = **I; 122dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!live[B.getBlockID()]) 123dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 124dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (B.size() == 0) { 125dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) { 126dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 127dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 128dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 129dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 130dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // A labeled empty statement, or the entry block... 131dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasPlainEdge = true; 132dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 133dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 134b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu CFGElement CE = B[B.size()-1]; 1350dc5f9aea3597f2ed400dd0c1bf45ebbb4a051f3Anders Carlsson if (CFGInitializer CI = CE.getAs<CFGInitializer>()) { 1360dc5f9aea3597f2ed400dd0c1bf45ebbb4a051f3Anders Carlsson // A base or member initializer. 1370dc5f9aea3597f2ed400dd0c1bf45ebbb4a051f3Anders Carlsson HasPlainEdge = true; 1380dc5f9aea3597f2ed400dd0c1bf45ebbb4a051f3Anders Carlsson continue; 1390dc5f9aea3597f2ed400dd0c1bf45ebbb4a051f3Anders Carlsson } 14022c412060e82dbe577dd8374677219dc68baec87Anders Carlsson if (CFGMemberDtor MD = CE.getAs<CFGMemberDtor>()) { 14122c412060e82dbe577dd8374677219dc68baec87Anders Carlsson // A member destructor. 14222c412060e82dbe577dd8374677219dc68baec87Anders Carlsson HasPlainEdge = true; 14322c412060e82dbe577dd8374677219dc68baec87Anders Carlsson continue; 14422c412060e82dbe577dd8374677219dc68baec87Anders Carlsson } 14522c412060e82dbe577dd8374677219dc68baec87Anders Carlsson if (CFGBaseDtor BD = CE.getAs<CFGBaseDtor>()) { 14622c412060e82dbe577dd8374677219dc68baec87Anders Carlsson // A base destructor. 14722c412060e82dbe577dd8374677219dc68baec87Anders Carlsson HasPlainEdge = true; 14822c412060e82dbe577dd8374677219dc68baec87Anders Carlsson continue; 14922c412060e82dbe577dd8374677219dc68baec87Anders Carlsson } 150b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu CFGStmt CS = CE.getAs<CFGStmt>(); 151b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu if (!CS.isValid()) 152b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu continue; 153b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu Stmt *S = CS.getStmt(); 154dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<ReturnStmt>(S)) { 155dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasLiveReturn = true; 156dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 157dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 158dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<ObjCAtThrowStmt>(S)) { 159dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 160dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 161dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 162dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<CXXThrowExpr>(S)) { 163dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 164dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 165dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 166dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) { 167dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (AS->isMSAsm()) { 168dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 169dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasLiveReturn = true; 170dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 171dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 172dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 173dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<CXXTryStmt>(S)) { 174dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 175dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 176dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 177dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 178dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool NoReturnEdge = false; 179dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (CallExpr *C = dyn_cast<CallExpr>(S)) { 180259d48e1486044093131c8c078f70a28b1503e70John McCall if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit()) 181259d48e1486044093131c8c078f70a28b1503e70John McCall == B.succ_end()) { 182dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 183dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 184dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 185dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Expr *CEE = C->getCallee()->IgnoreParenCasts(); 186264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola if (getFunctionExtInfo(CEE->getType()).getNoReturn()) { 187dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek NoReturnEdge = true; 188dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 189dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) { 190dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ValueDecl *VD = DRE->getDecl(); 191dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (VD->hasAttr<NoReturnAttr>()) { 192dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek NoReturnEdge = true; 193dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 194dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 195dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 196dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 197dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // FIXME: Add noreturn message sends. 198dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (NoReturnEdge == false) 199dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasPlainEdge = true; 200dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 201dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!HasPlainEdge) { 202dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasLiveReturn) 203dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return NeverFallThrough; 204dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return NeverFallThroughOrReturn; 205dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 206dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn) 207dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return MaybeFallThrough; 208dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // This says AlwaysFallThrough for calls to functions that are not marked 209dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // noreturn, that don't return. If people would like this warning to be more 210dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // accurate, such functions should be marked as noreturn. 211dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return AlwaysFallThrough; 212dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 213dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 2143c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohmannamespace { 2153c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 216dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstruct CheckFallThroughDiagnostics { 217dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_MaybeFallThrough_HasNoReturn; 218dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_MaybeFallThrough_ReturnsNonVoid; 219dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_AlwaysFallThrough_HasNoReturn; 220dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_AlwaysFallThrough_ReturnsNonVoid; 221dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_NeverFallThroughOrReturn; 222dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool funMode; 2230827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis SourceLocation FuncLoc; 224d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 225ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { 226dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughDiagnostics D; 2270827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.FuncLoc = Func->getLocation(); 228dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_HasNoReturn = 229dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_noreturn_function; 230dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_ReturnsNonVoid = 231dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_maybe_falloff_nonvoid_function; 232dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_HasNoReturn = 233dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_noreturn_function; 234dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_ReturnsNonVoid = 235dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_nonvoid_function; 236ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 237ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor // Don't suggest that virtual functions be marked "noreturn", since they 238ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor // might be overridden by non-noreturn functions. 239ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor bool isVirtualMethod = false; 240ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func)) 241ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor isVirtualMethod = Method->isVirtual(); 242ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 243ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor if (!isVirtualMethod) 244ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor D.diag_NeverFallThroughOrReturn = 245ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor diag::warn_suggest_noreturn_function; 246ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor else 247ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor D.diag_NeverFallThroughOrReturn = 0; 248ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 249dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.funMode = true; 250dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return D; 251dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 252d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 253dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek static CheckFallThroughDiagnostics MakeForBlock() { 254dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughDiagnostics D; 255dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_HasNoReturn = 256dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_noreturn_block_has_return_expr; 257dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_ReturnsNonVoid = 258dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_maybe_falloff_nonvoid_block; 259dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_HasNoReturn = 260dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_noreturn_block_has_return_expr; 261dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_ReturnsNonVoid = 262dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_falloff_nonvoid_block; 263dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_NeverFallThroughOrReturn = 264dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_suggest_noreturn_block; 265dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.funMode = false; 266dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return D; 267dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 268d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 269dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool checkDiagnostics(Diagnostic &D, bool ReturnsVoid, 270dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasNoReturn) const { 271dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (funMode) { 2720827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis return (ReturnsVoid || 2730827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function, 2740827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis FuncLoc) == Diagnostic::Ignored) 2750827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis && (!HasNoReturn || 2760827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr, 2770827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis FuncLoc) == Diagnostic::Ignored) 2780827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis && (!ReturnsVoid || 2790827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 2800827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis == Diagnostic::Ignored); 281dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 282d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 283dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // For blocks. 284dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return ReturnsVoid && !HasNoReturn 2850827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis && (!ReturnsVoid || 2860827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 2870827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis == Diagnostic::Ignored); 288dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 289dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}; 290dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 2913c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman} 2923c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 293dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a 294dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// function that should return a value. Check that we don't fall off the end 295dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// of a noreturn function. We assume that functions and blocks not marked 296dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// noreturn will return. 297dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, 298dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek QualType BlockTy, 299dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const CheckFallThroughDiagnostics& CD, 300dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek AnalysisContext &AC) { 301dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 302dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool ReturnsVoid = false; 303dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasNoReturn = false; 304dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 305dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 306dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = FD->getResultType()->isVoidType(); 307dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = FD->hasAttr<NoReturnAttr>() || 308264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola FD->getType()->getAs<FunctionType>()->getNoReturnAttr(); 309dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 310dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 311dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = MD->getResultType()->isVoidType(); 312dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = MD->hasAttr<NoReturnAttr>(); 313dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 314dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (isa<BlockDecl>(D)) { 315d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek if (const FunctionType *FT = 316dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek BlockTy->getPointeeType()->getAs<FunctionType>()) { 317dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (FT->getResultType()->isVoidType()) 318dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = true; 319dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (FT->getNoReturnAttr()) 320dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = true; 321dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 322dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 323dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 324dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Diagnostic &Diags = S.getDiagnostics(); 325dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 326dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Short circuit for compilation speed. 327dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn)) 328dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return; 329d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 330dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // FIXME: Function try block 331dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { 332dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek switch (CheckFallThrough(AC)) { 33316565aa95b086fb239baf82335dccc1b1ec93942John McCall case UnknownFallThrough: 33416565aa95b086fb239baf82335dccc1b1ec93942John McCall break; 33516565aa95b086fb239baf82335dccc1b1ec93942John McCall 336dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case MaybeFallThrough: 337dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasNoReturn) 338dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 339dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_MaybeFallThrough_HasNoReturn); 340dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (!ReturnsVoid) 341dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 342dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_MaybeFallThrough_ReturnsNonVoid); 343dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 344dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case AlwaysFallThrough: 345dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasNoReturn) 346dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 347dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_AlwaysFallThrough_HasNoReturn); 348dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (!ReturnsVoid) 349dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 350dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_AlwaysFallThrough_ReturnsNonVoid); 351dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 352dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case NeverFallThroughOrReturn: 353ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) 354dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getLBracLoc(), 355dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_NeverFallThroughOrReturn); 356dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 357dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case NeverFallThrough: 358dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 359dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 360dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 361dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 362dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 363dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 364610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// -Wuninitialized 365610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 366610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 367610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremeneknamespace { 36894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenekstruct SLocSort { 369a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek bool operator()(const Expr *a, const Expr *b) { 37094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek SourceLocation aLoc = a->getLocStart(); 37194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek SourceLocation bLoc = b->getLocStart(); 37294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek return aLoc.getRawEncoding() < bLoc.getRawEncoding(); 37394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 37494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek}; 37594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 376610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass UninitValsDiagReporter : public UninitVariablesHandler { 377610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek Sema &S; 378a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek typedef llvm::SmallVector<const Expr *, 2> UsesVec; 37994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek typedef llvm::DenseMap<const VarDecl *, UsesVec*> UsesMap; 38094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek UsesMap *uses; 38194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 382610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic: 38394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek UninitValsDiagReporter(Sema &S) : S(S), uses(0) {} 38494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek ~UninitValsDiagReporter() { 38594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek flushDiagnostics(); 38694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 387610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 388a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek void handleUseOfUninitVariable(const Expr *ex, const VarDecl *vd) { 38994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek if (!uses) 39094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek uses = new UsesMap(); 39194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 39294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek UsesVec *&vec = (*uses)[vd]; 39394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek if (!vec) 39494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek vec = new UsesVec(); 39594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 396a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek vec->push_back(ex); 39794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 39894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 39994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek void flushDiagnostics() { 40094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek if (!uses) 40194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek return; 40294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 40394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) { 40494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek const VarDecl *vd = i->first; 40594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek UsesVec *vec = i->second; 40694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 407a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek S.Diag(vd->getLocStart(), diag::warn_uninit_var) 40894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek << vd->getDeclName() << vd->getSourceRange(); 409fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek 41094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek // Sort the uses by their SourceLocations. While not strictly 41194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek // guaranteed to produce them in line/column order, this will provide 41294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek // a stable ordering. 41394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek std::sort(vec->begin(), vec->end(), SLocSort()); 41494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 41594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi) 41694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek { 417a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek if (const DeclRefExpr *dr = dyn_cast<DeclRefExpr>(*vi)) { 418a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek S.Diag(dr->getLocStart(), diag::note_uninit_var) 419a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek << vd->getDeclName() << dr->getSourceRange(); 420a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek } 421a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek else { 422a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek const BlockExpr *be = cast<BlockExpr>(*vi); 423a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek S.Diag(be->getLocStart(), diag::note_uninit_var_captured_by_block) 424a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek << vd->getDeclName(); 425a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek } 42694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 427fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek 428fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek // Suggest possible initialization (if any). 429fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek const char *initialization = 0; 430dcfb360f6e1aaab0754a98e1e245c2607c46058aTed Kremenek QualType vdTy = vd->getType().getCanonicalType(); 431fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek 432fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek if (vdTy->getAs<ObjCObjectPointerType>()) { 433dcfb360f6e1aaab0754a98e1e245c2607c46058aTed Kremenek // Check if 'nil' is defined. 434dcfb360f6e1aaab0754a98e1e245c2607c46058aTed Kremenek if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil"))) 435dcfb360f6e1aaab0754a98e1e245c2607c46058aTed Kremenek initialization = " = nil"; 436dcfb360f6e1aaab0754a98e1e245c2607c46058aTed Kremenek else 437dcfb360f6e1aaab0754a98e1e245c2607c46058aTed Kremenek initialization = " = 0"; 438fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek } 439dcfb360f6e1aaab0754a98e1e245c2607c46058aTed Kremenek else if (vdTy->isRealFloatingType()) { 440dcfb360f6e1aaab0754a98e1e245c2607c46058aTed Kremenek initialization = " = 0.0"; 441dcfb360f6e1aaab0754a98e1e245c2607c46058aTed Kremenek } 442dcfb360f6e1aaab0754a98e1e245c2607c46058aTed Kremenek else if (vdTy->isScalarType()) { 443fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek initialization = " = 0"; 444fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek } 445fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek 446fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek if (initialization) { 447fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek SourceLocation loc = S.PP.getLocForEndOfToken(vd->getLocEnd()); 448fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek S.Diag(loc, diag::note_var_fixit_add_initialization) 449fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek << FixItHint::CreateInsertion(loc, initialization); 450fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek } 451fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek 45294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek delete vec; 45394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 45494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek delete uses; 455610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 456610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}; 457610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 458610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 459610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 460dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based 461dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// warnings on a function, method, or block. 462dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 463dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 464d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekclang::sema::AnalysisBasedWarnings::Policy::Policy() { 465dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek enableCheckFallThrough = 1; 466d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek enableCheckUnreachable = 0; 467d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek} 468dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 469d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekclang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s) { 470d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek Diagnostic &D = S.getDiagnostics(); 471d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek DefaultPolicy.enableCheckUnreachable = (unsigned) 4720827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis (D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) != 4730827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis Diagnostic::Ignored); 474dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 475dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 476d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekvoid clang::sema:: 477d064fdc4b7b64ca55b40b70490c79d6f569df78eTed KremenekAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 478b7e5f145f47b6ec1db1ba6fe9db9c0ed2fe38db3Ted Kremenek const Decl *D, QualType BlockTy) { 479d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 480dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek assert(BlockTy.isNull() || isa<BlockDecl>(D)); 481d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek 482dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // We avoid doing analysis-based warnings when there are errors for 483dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // two reasons: 484dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // (1) The CFGs often can't be constructed (if the body is invalid), so 485dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // don't bother trying. 486dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // (2) The code already has problems; running the analysis just takes more 487dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // time. 48899e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek Diagnostic &Diags = S.getDiagnostics(); 48999e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek 49099e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) 491d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek return; 492d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 493d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek // Do not do any analysis for declarations in system headers if we are 494d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek // going to just ignore them. 49599e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek if (Diags.getSuppressSystemWarnings() && 496d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek S.SourceMgr.isInSystemHeader(D->getLocation())) 497d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek return; 498d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 499e0054f61fd84133eb0d19c19ae9afaf117933274John McCall // For code in dependent contexts, we'll do this at instantiation time. 500e0054f61fd84133eb0d19c19ae9afaf117933274John McCall if (cast<DeclContext>(D)->isDependentContext()) 501e0054f61fd84133eb0d19c19ae9afaf117933274John McCall return; 502dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 503dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const Stmt *Body = D->getBody(); 504dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek assert(Body); 505dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 506dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Don't generate EH edges for CallExprs as we'd like to avoid the n^2 507dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // explosion for destrutors that can result and the compile time hit. 508eeef924c4fcb79a3bcc8782afce343e641bbcb83Chandler Carruth AnalysisContext AC(D, 0, /*useUnoptimizedCFG=*/false, /*addehedges=*/false, 509eeef924c4fcb79a3bcc8782afce343e641bbcb83Chandler Carruth /*addImplicitDtors=*/true, /*addInitializers=*/true); 510dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 511dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Warning: check missing 'return' 512d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek if (P.enableCheckFallThrough) { 513dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const CheckFallThroughDiagnostics &CD = 514dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock() 515ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor : CheckFallThroughDiagnostics::MakeForFunction(D)); 516dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughForBody(S, D, Body, BlockTy, CD, AC); 517dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 518dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 519dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Warning: check for unreachable code 520b7e5f145f47b6ec1db1ba6fe9db9c0ed2fe38db3Ted Kremenek if (P.enableCheckUnreachable) 521dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckUnreachable(S, AC); 522610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 523a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart()) 524610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek != Diagnostic::Ignored) { 525c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek if (CFG *cfg = AC.getCFG()) { 526c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek UninitValsDiagReporter reporter(S); 527a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC, 528a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek reporter); 529610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 530610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 531dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 532e0054f61fd84133eb0d19c19ae9afaf117933274John McCall 533e0054f61fd84133eb0d19c19ae9afaf117933274John McCallvoid clang::sema:: 534e0054f61fd84133eb0d19c19ae9afaf117933274John McCallAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 535e0054f61fd84133eb0d19c19ae9afaf117933274John McCall const BlockExpr *E) { 536e0054f61fd84133eb0d19c19ae9afaf117933274John McCall return IssueWarnings(P, E->getBlockDecl(), E->getType()); 537e0054f61fd84133eb0d19c19ae9afaf117933274John McCall} 538e0054f61fd84133eb0d19c19ae9afaf117933274John McCall 539e0054f61fd84133eb0d19c19ae9afaf117933274John McCallvoid clang::sema:: 540e0054f61fd84133eb0d19c19ae9afaf117933274John McCallAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 541e0054f61fd84133eb0d19c19ae9afaf117933274John McCall const ObjCMethodDecl *D) { 542e0054f61fd84133eb0d19c19ae9afaf117933274John McCall return IssueWarnings(P, D, QualType()); 543e0054f61fd84133eb0d19c19ae9afaf117933274John McCall} 544e0054f61fd84133eb0d19c19ae9afaf117933274John McCall 545e0054f61fd84133eb0d19c19ae9afaf117933274John McCallvoid clang::sema:: 546e0054f61fd84133eb0d19c19ae9afaf117933274John McCallAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 547e0054f61fd84133eb0d19c19ae9afaf117933274John McCall const FunctionDecl *D) { 548e0054f61fd84133eb0d19c19ae9afaf117933274John McCall return IssueWarnings(P, D, QualType()); 549e0054f61fd84133eb0d19c19ae9afaf117933274John McCall} 550