AnalysisBasedWarnings.cpp revision 609e3170841dac81c3b7b6b9eccb9c520e42c9b2
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; 1245811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek 1255811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // Destructors can appear after the 'return' in the CFG. This is 1265811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // normal. We need to look pass the destructors for the return 1275811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // statement (if it exists). 1285811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend(); 1295811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek for ( ; ri != re ; ++ri) { 1305811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek CFGElement CE = *ri; 1315811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek if (isa<CFGStmt>(CE)) 1325811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek break; 1335811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek } 1345811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek 1355811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // No more CFGElements in the block? 1365811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek if (ri == re) { 137dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) { 138dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 139dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 140dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 141dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // A labeled empty statement, or the entry block... 142dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasPlainEdge = true; 143dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 144dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 145f39e6a388aaa2f155b46c61e655784b2473218ebTed Kremenek 1465811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek CFGStmt CS = cast<CFGStmt>(*ri); 147b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu Stmt *S = CS.getStmt(); 148dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<ReturnStmt>(S)) { 149dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasLiveReturn = true; 150dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 151dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 152dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<ObjCAtThrowStmt>(S)) { 153dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 154dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 155dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 156dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<CXXThrowExpr>(S)) { 157dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 158dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 159dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 160dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) { 161dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (AS->isMSAsm()) { 162dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 163dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasLiveReturn = true; 164dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 165dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 166dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 167dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<CXXTryStmt>(S)) { 168dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 169dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 170dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 171dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 172dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool NoReturnEdge = false; 173dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (CallExpr *C = dyn_cast<CallExpr>(S)) { 174259d48e1486044093131c8c078f70a28b1503e70John McCall if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit()) 175259d48e1486044093131c8c078f70a28b1503e70John McCall == B.succ_end()) { 176dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 177dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 178dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 179dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Expr *CEE = C->getCallee()->IgnoreParenCasts(); 180264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola if (getFunctionExtInfo(CEE->getType()).getNoReturn()) { 181dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek NoReturnEdge = true; 182dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 183dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) { 184dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ValueDecl *VD = DRE->getDecl(); 185dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (VD->hasAttr<NoReturnAttr>()) { 186dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek NoReturnEdge = true; 187dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 188dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 189dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 190dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 191dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // FIXME: Add noreturn message sends. 192dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (NoReturnEdge == false) 193dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasPlainEdge = true; 194dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 195dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!HasPlainEdge) { 196dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasLiveReturn) 197dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return NeverFallThrough; 198dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return NeverFallThroughOrReturn; 199dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 200dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn) 201dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return MaybeFallThrough; 202dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // This says AlwaysFallThrough for calls to functions that are not marked 203dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // noreturn, that don't return. If people would like this warning to be more 204dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // accurate, such functions should be marked as noreturn. 205dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return AlwaysFallThrough; 206dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 207dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 2083c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohmannamespace { 2093c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 210dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstruct CheckFallThroughDiagnostics { 211dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_MaybeFallThrough_HasNoReturn; 212dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_MaybeFallThrough_ReturnsNonVoid; 213dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_AlwaysFallThrough_HasNoReturn; 214dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_AlwaysFallThrough_ReturnsNonVoid; 215dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_NeverFallThroughOrReturn; 216dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool funMode; 2170827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis SourceLocation FuncLoc; 218d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 219ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { 220dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughDiagnostics D; 2210827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.FuncLoc = Func->getLocation(); 222dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_HasNoReturn = 223dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_noreturn_function; 224dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_ReturnsNonVoid = 225dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_maybe_falloff_nonvoid_function; 226dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_HasNoReturn = 227dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_noreturn_function; 228dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_ReturnsNonVoid = 229dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_nonvoid_function; 230ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 231ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor // Don't suggest that virtual functions be marked "noreturn", since they 232ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor // might be overridden by non-noreturn functions. 233ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor bool isVirtualMethod = false; 234ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func)) 235ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor isVirtualMethod = Method->isVirtual(); 236ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 237ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor if (!isVirtualMethod) 238ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor D.diag_NeverFallThroughOrReturn = 239ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor diag::warn_suggest_noreturn_function; 240ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor else 241ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor D.diag_NeverFallThroughOrReturn = 0; 242ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 243dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.funMode = true; 244dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return D; 245dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 246d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 247dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek static CheckFallThroughDiagnostics MakeForBlock() { 248dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughDiagnostics D; 249dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_HasNoReturn = 250dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_noreturn_block_has_return_expr; 251dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_ReturnsNonVoid = 252dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_maybe_falloff_nonvoid_block; 253dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_HasNoReturn = 254dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_noreturn_block_has_return_expr; 255dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_ReturnsNonVoid = 256dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_falloff_nonvoid_block; 257dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_NeverFallThroughOrReturn = 258dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_suggest_noreturn_block; 259dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.funMode = false; 260dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return D; 261dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 262d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 263dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool checkDiagnostics(Diagnostic &D, bool ReturnsVoid, 264dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasNoReturn) const { 265dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (funMode) { 2660827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis return (ReturnsVoid || 2670827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function, 2680827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis FuncLoc) == Diagnostic::Ignored) 2690827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis && (!HasNoReturn || 2700827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr, 2710827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis FuncLoc) == Diagnostic::Ignored) 2720827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis && (!ReturnsVoid || 2730827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 2740827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis == Diagnostic::Ignored); 275dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 276d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 277dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // For blocks. 278dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return ReturnsVoid && !HasNoReturn 2790827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis && (!ReturnsVoid || 2800827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 2810827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis == Diagnostic::Ignored); 282dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 283dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}; 284dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 2853c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman} 2863c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 287dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a 288dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// function that should return a value. Check that we don't fall off the end 289dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// of a noreturn function. We assume that functions and blocks not marked 290dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// noreturn will return. 291dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, 292dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek QualType BlockTy, 293dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const CheckFallThroughDiagnostics& CD, 294dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek AnalysisContext &AC) { 295dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 296dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool ReturnsVoid = false; 297dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasNoReturn = false; 298dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 299dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 300dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = FD->getResultType()->isVoidType(); 301dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = FD->hasAttr<NoReturnAttr>() || 302264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola FD->getType()->getAs<FunctionType>()->getNoReturnAttr(); 303dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 304dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 305dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = MD->getResultType()->isVoidType(); 306dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = MD->hasAttr<NoReturnAttr>(); 307dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 308dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (isa<BlockDecl>(D)) { 309d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek if (const FunctionType *FT = 310dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek BlockTy->getPointeeType()->getAs<FunctionType>()) { 311dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (FT->getResultType()->isVoidType()) 312dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = true; 313dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (FT->getNoReturnAttr()) 314dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = true; 315dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 316dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 317dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 318dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Diagnostic &Diags = S.getDiagnostics(); 319dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 320dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Short circuit for compilation speed. 321dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn)) 322dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return; 323d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 324dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // FIXME: Function try block 325dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { 326dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek switch (CheckFallThrough(AC)) { 32716565aa95b086fb239baf82335dccc1b1ec93942John McCall case UnknownFallThrough: 32816565aa95b086fb239baf82335dccc1b1ec93942John McCall break; 32916565aa95b086fb239baf82335dccc1b1ec93942John McCall 330dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case MaybeFallThrough: 331dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasNoReturn) 332dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 333dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_MaybeFallThrough_HasNoReturn); 334dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (!ReturnsVoid) 335dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 336dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_MaybeFallThrough_ReturnsNonVoid); 337dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 338dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case AlwaysFallThrough: 339dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasNoReturn) 340dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 341dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_AlwaysFallThrough_HasNoReturn); 342dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (!ReturnsVoid) 343dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 344dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_AlwaysFallThrough_ReturnsNonVoid); 345dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 346dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case NeverFallThroughOrReturn: 347ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) 348dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getLBracLoc(), 349dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_NeverFallThroughOrReturn); 350dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 351dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case NeverFallThrough: 352dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 353dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 354dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 355dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 356dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 357dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 358610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// -Wuninitialized 359610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 360610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 361610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremeneknamespace { 36294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenekstruct SLocSort { 363a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek bool operator()(const Expr *a, const Expr *b) { 36494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek SourceLocation aLoc = a->getLocStart(); 36594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek SourceLocation bLoc = b->getLocStart(); 36694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek return aLoc.getRawEncoding() < bLoc.getRawEncoding(); 36794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 36894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek}; 36994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 370610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass UninitValsDiagReporter : public UninitVariablesHandler { 371610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek Sema &S; 372a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek typedef llvm::SmallVector<const Expr *, 2> UsesVec; 37394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek typedef llvm::DenseMap<const VarDecl *, UsesVec*> UsesMap; 37494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek UsesMap *uses; 37594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 376610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic: 37794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek UninitValsDiagReporter(Sema &S) : S(S), uses(0) {} 37894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek ~UninitValsDiagReporter() { 37994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek flushDiagnostics(); 38094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 381610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 382a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek void handleUseOfUninitVariable(const Expr *ex, const VarDecl *vd) { 38394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek if (!uses) 38494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek uses = new UsesMap(); 38594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 38694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek UsesVec *&vec = (*uses)[vd]; 38794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek if (!vec) 38894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek vec = new UsesVec(); 38994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 390a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek vec->push_back(ex); 39194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 39294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 39394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek void flushDiagnostics() { 39494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek if (!uses) 39594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek return; 396609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek 39794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) { 39894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek const VarDecl *vd = i->first; 39994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek UsesVec *vec = i->second; 400609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek 401609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek bool fixitIssued = false; 402609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek 40394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek // Sort the uses by their SourceLocations. While not strictly 40494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek // guaranteed to produce them in line/column order, this will provide 40594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek // a stable ordering. 40694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek std::sort(vec->begin(), vec->end(), SLocSort()); 40794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 40894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi) 40994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek { 410a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek if (const DeclRefExpr *dr = dyn_cast<DeclRefExpr>(*vi)) { 411609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek S.Diag(dr->getLocStart(), diag::warn_uninit_var) 412609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek << vd->getDeclName() << dr->getSourceRange(); 413a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek } 414a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek else { 415a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek const BlockExpr *be = cast<BlockExpr>(*vi); 416609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek S.Diag(be->getLocStart(), diag::warn_uninit_var_captured_by_block) 417a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek << vd->getDeclName(); 418a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek } 419609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek 420609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek // Report where the variable was declared. 421609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek S.Diag(vd->getLocStart(), diag::note_uninit_var_def) 422609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek << vd->getDeclName(); 423609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek 424609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek // Only report the fixit once. 425609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek if (fixitIssued) 426609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek continue; 427609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek 428609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek fixitIssued = true; 429fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek 430609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek // Suggest possible initialization (if any). 431609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek const char *initialization = 0; 432609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek QualType vdTy = vd->getType().getCanonicalType(); 433fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek 434609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek if (vdTy->getAs<ObjCObjectPointerType>()) { 435609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek // Check if 'nil' is defined. 436609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil"))) 437609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek initialization = " = nil"; 438609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek else 439609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek initialization = " = 0"; 440609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek } 441609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek else if (vdTy->isRealFloatingType()) 442609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek initialization = " = 0.0"; 443609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek else if (vdTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus) 444609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek initialization = " = false"; 445609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek else if (vdTy->isScalarType()) 446dcfb360f6e1aaab0754a98e1e245c2607c46058aTed Kremenek initialization = " = 0"; 447fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek 448609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek if (initialization) { 449609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek SourceLocation loc = S.PP.getLocForEndOfToken(vd->getLocEnd()); 450609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek S.Diag(loc, diag::note_var_fixit_add_initialization) 451609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek << FixItHint::CreateInsertion(loc, initialization); 452609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek } 453fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek } 45494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek delete vec; 45594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 45694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek delete uses; 457610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 458610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}; 459610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 460610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 461610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 462dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based 463dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// warnings on a function, method, or block. 464dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 465dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 466d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekclang::sema::AnalysisBasedWarnings::Policy::Policy() { 467dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek enableCheckFallThrough = 1; 468d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek enableCheckUnreachable = 0; 469d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek} 470dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 471d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekclang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s) { 472d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek Diagnostic &D = S.getDiagnostics(); 473d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek DefaultPolicy.enableCheckUnreachable = (unsigned) 4740827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis (D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) != 4750827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis Diagnostic::Ignored); 476dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 477dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 478d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekvoid clang::sema:: 479d064fdc4b7b64ca55b40b70490c79d6f569df78eTed KremenekAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 480b7e5f145f47b6ec1db1ba6fe9db9c0ed2fe38db3Ted Kremenek const Decl *D, QualType BlockTy) { 481d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 482dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek assert(BlockTy.isNull() || isa<BlockDecl>(D)); 483d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek 484dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // We avoid doing analysis-based warnings when there are errors for 485dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // two reasons: 486dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // (1) The CFGs often can't be constructed (if the body is invalid), so 487dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // don't bother trying. 488dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // (2) The code already has problems; running the analysis just takes more 489dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // time. 49099e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek Diagnostic &Diags = S.getDiagnostics(); 49199e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek 49299e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) 493d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek return; 494d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 495d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek // Do not do any analysis for declarations in system headers if we are 496d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek // going to just ignore them. 49799e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek if (Diags.getSuppressSystemWarnings() && 498d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek S.SourceMgr.isInSystemHeader(D->getLocation())) 499d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek return; 500d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 501e0054f61fd84133eb0d19c19ae9afaf117933274John McCall // For code in dependent contexts, we'll do this at instantiation time. 502e0054f61fd84133eb0d19c19ae9afaf117933274John McCall if (cast<DeclContext>(D)->isDependentContext()) 503e0054f61fd84133eb0d19c19ae9afaf117933274John McCall return; 504dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 505dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const Stmt *Body = D->getBody(); 506dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek assert(Body); 507dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 508dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Don't generate EH edges for CallExprs as we'd like to avoid the n^2 509dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // explosion for destrutors that can result and the compile time hit. 510eeef924c4fcb79a3bcc8782afce343e641bbcb83Chandler Carruth AnalysisContext AC(D, 0, /*useUnoptimizedCFG=*/false, /*addehedges=*/false, 511eeef924c4fcb79a3bcc8782afce343e641bbcb83Chandler Carruth /*addImplicitDtors=*/true, /*addInitializers=*/true); 512dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 513dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Warning: check missing 'return' 514d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek if (P.enableCheckFallThrough) { 515dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const CheckFallThroughDiagnostics &CD = 516dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock() 517ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor : CheckFallThroughDiagnostics::MakeForFunction(D)); 518dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughForBody(S, D, Body, BlockTy, CD, AC); 519dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 520dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 521dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Warning: check for unreachable code 522b7e5f145f47b6ec1db1ba6fe9db9c0ed2fe38db3Ted Kremenek if (P.enableCheckUnreachable) 523dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckUnreachable(S, AC); 524610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 525a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart()) 526610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek != Diagnostic::Ignored) { 52763b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek ASTContext &ctx = D->getASTContext(); 52863b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek llvm::OwningPtr<CFG> tmpCFG; 52963b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek bool useAlternateCFG = false; 53063b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek if (ctx.getLangOptions().CPlusPlus) { 53163b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek // Temporary workaround: implicit dtors in the CFG can confuse 53263b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek // the path-sensitivity in the uninitialized values analysis. 53363b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek // For now create (if necessary) a separate CFG without implicit dtors. 53463b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek // FIXME: We should not need to do this, as it results in multiple 53563b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek // CFGs getting constructed. 53663b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek CFG::BuildOptions B; 53763b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek B.AddEHEdges = false; 53863b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek B.AddImplicitDtors = false; 53963b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek B.AddInitializers = true; 54063b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek tmpCFG.reset(CFG::buildCFG(D, AC.getBody(), &ctx, B)); 54163b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek useAlternateCFG = true; 54263b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek } 54363b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek CFG *cfg = useAlternateCFG ? tmpCFG.get() : AC.getCFG(); 54463b54104700873dc4a5b95b3108052580b5370e7Ted Kremenek if (cfg) { 545c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek UninitValsDiagReporter reporter(S); 546a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC, 547a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek reporter); 548610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 549610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 550dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 551e0054f61fd84133eb0d19c19ae9afaf117933274John McCall 552e0054f61fd84133eb0d19c19ae9afaf117933274John McCallvoid clang::sema:: 553e0054f61fd84133eb0d19c19ae9afaf117933274John McCallAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 554e0054f61fd84133eb0d19c19ae9afaf117933274John McCall const BlockExpr *E) { 555e0054f61fd84133eb0d19c19ae9afaf117933274John McCall return IssueWarnings(P, E->getBlockDecl(), E->getType()); 556e0054f61fd84133eb0d19c19ae9afaf117933274John McCall} 557e0054f61fd84133eb0d19c19ae9afaf117933274John McCall 558e0054f61fd84133eb0d19c19ae9afaf117933274John McCallvoid clang::sema:: 559e0054f61fd84133eb0d19c19ae9afaf117933274John McCallAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 560e0054f61fd84133eb0d19c19ae9afaf117933274John McCall const ObjCMethodDecl *D) { 561e0054f61fd84133eb0d19c19ae9afaf117933274John McCall return IssueWarnings(P, D, QualType()); 562e0054f61fd84133eb0d19c19ae9afaf117933274John McCall} 563e0054f61fd84133eb0d19c19ae9afaf117933274John McCall 564e0054f61fd84133eb0d19c19ae9afaf117933274John McCallvoid clang::sema:: 565e0054f61fd84133eb0d19c19ae9afaf117933274John McCallAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 566e0054f61fd84133eb0d19c19ae9afaf117933274John McCall const FunctionDecl *D) { 567e0054f61fd84133eb0d19c19ae9afaf117933274John McCall return IssueWarnings(P, D, QualType()); 568e0054f61fd84133eb0d19c19ae9afaf117933274John McCall} 569