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" 18351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Sema/ScopeInfo.h" 19d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek#include "clang/Basic/SourceManager.h" 2075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski#include "clang/Basic/SourceLocation.h" 21fbb178a0b47fca1b0fb78c5d41198614cf52aa70Ted Kremenek#include "clang/Lex/Preprocessor.h" 22bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith#include "clang/Lex/Lexer.h" 237cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCall#include "clang/AST/DeclObjC.h" 24384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h" 25dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/ExprObjC.h" 26dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/ExprCXX.h" 27dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/StmtObjC.h" 28dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/AST/StmtCXX.h" 296f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek#include "clang/AST/EvaluatedExprVisitor.h" 303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "clang/AST/StmtVisitor.h" 31e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith#include "clang/AST/RecursiveASTVisitor.h" 32dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/AnalysisContext.h" 33dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/CFG.h" 34dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "clang/Analysis/Analyses/ReachableCode.h" 35351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h" 36402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski#include "clang/Analysis/Analyses/ThreadSafety.h" 37351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Analysis/CFGStmtMap.h" 386f34213f8d6ae8c77685b53664527e39bfaaca3bTed Kremenek#include "clang/Analysis/Analyses/UninitializedValues.h" 39dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/ADT/BitVector.h" 403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/FoldingSet.h" 413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/ImmutableMap.h" 423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/PostOrderIterator.h" 433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/SmallVector.h" 4475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski#include "llvm/ADT/StringRef.h" 45dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/Support/Casting.h" 463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include <algorithm> 47e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith#include <iterator> 483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include <vector> 49e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith#include <deque> 50dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 51dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekusing namespace clang; 52dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 53dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 54dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Unreachable code analysis. 55dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 56dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 57dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremeneknamespace { 58dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek class UnreachableCodeHandler : public reachable_code::Callback { 59dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Sema &S; 60dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek public: 61dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek UnreachableCodeHandler(Sema &s) : S(s) {} 62dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 63dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) { 64dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(L, diag::warn_unreachable) << R1 << R2; 65dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 66dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek }; 67dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 68dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 69dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckUnreachable - Check for unreachable code. 701d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekstatic void CheckUnreachable(Sema &S, AnalysisDeclContext &AC) { 71dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek UnreachableCodeHandler UC(S); 72dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek reachable_code::FindUnreachableCode(AC, UC); 73dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 74dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 75dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 76dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Check for missing return value. 77dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 78dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 7916565aa95b086fb239baf82335dccc1b1ec93942John McCallenum ControlFlowKind { 8016565aa95b086fb239baf82335dccc1b1ec93942John McCall UnknownFallThrough, 8116565aa95b086fb239baf82335dccc1b1ec93942John McCall NeverFallThrough, 8216565aa95b086fb239baf82335dccc1b1ec93942John McCall MaybeFallThrough, 8316565aa95b086fb239baf82335dccc1b1ec93942John McCall AlwaysFallThrough, 8416565aa95b086fb239baf82335dccc1b1ec93942John McCall NeverFallThroughOrReturn 8516565aa95b086fb239baf82335dccc1b1ec93942John McCall}; 86dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 87dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThrough - Check that we don't fall off the end of a 88dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// Statement that should return a value. 89dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// 90dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// \returns AlwaysFallThrough iff we always fall off the end of the statement, 91dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// MaybeFallThrough iff we might or might not fall off the end, 92dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// NeverFallThroughOrReturn iff we never fall off the end of the statement or 93dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// return. We assume NeverFallThrough iff we never fall off the end of the 94dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// statement but we may return. We assume that functions not marked noreturn 95dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// will return. 961d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekstatic ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) { 97dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CFG *cfg = AC.getCFG(); 9816565aa95b086fb239baf82335dccc1b1ec93942John McCall if (cfg == 0) return UnknownFallThrough; 99dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 100dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // The CFG leaves in dead things, and we don't want the dead code paths to 101dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // confuse us, so we mark all live things first. 102dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek llvm::BitVector live(cfg->getNumBlockIDs()); 1030f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(), 104dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek live); 105dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 106dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool AddEHEdges = AC.getAddEHEdges(); 107dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!AddEHEdges && count != cfg->getNumBlockIDs()) 108dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // When there are things remaining dead, and we didn't add EH edges 109dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // from CallExprs to the catch clauses, we have to go back and 110dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // mark them as live. 111dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) { 112dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CFGBlock &b = **I; 113dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!live[b.getBlockID()]) { 114dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (b.pred_begin() == b.pred_end()) { 115dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator())) 116dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // When not adding EH edges from calls, catch clauses 117dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // can otherwise seem dead. Avoid noting them as dead. 1180f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek count += reachable_code::ScanReachableFromBlock(&b, live); 119dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 120dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 121dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 122dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 123dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 124dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Now we know what is live, we check the live precessors of the exit block 125dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // and look for fall through paths, being careful to ignore normal returns, 126dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // and exceptional paths. 127dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasLiveReturn = false; 128dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasFakeEdge = false; 129dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasPlainEdge = false; 130dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasAbnormalEdge = false; 13190b828aa279542559f655d1af666580288cb1841Ted Kremenek 13290b828aa279542559f655d1af666580288cb1841Ted Kremenek // Ignore default cases that aren't likely to be reachable because all 13390b828aa279542559f655d1af666580288cb1841Ted Kremenek // enums in a switch(X) have explicit case statements. 13490b828aa279542559f655d1af666580288cb1841Ted Kremenek CFGBlock::FilterOptions FO; 13590b828aa279542559f655d1af666580288cb1841Ted Kremenek FO.IgnoreDefaultsWithCoveredEnums = 1; 13690b828aa279542559f655d1af666580288cb1841Ted Kremenek 13790b828aa279542559f655d1af666580288cb1841Ted Kremenek for (CFGBlock::filtered_pred_iterator 13890b828aa279542559f655d1af666580288cb1841Ted Kremenek I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) { 13990b828aa279542559f655d1af666580288cb1841Ted Kremenek const CFGBlock& B = **I; 140dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!live[B.getBlockID()]) 141dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 1425811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek 143e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth // Skip blocks which contain an element marked as no-return. They don't 144e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth // represent actually viable edges into the exit block, so mark them as 145e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth // abnormal. 146e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth if (B.hasNoReturnElement()) { 147e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth HasAbnormalEdge = true; 148e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth continue; 149e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth } 150e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth 1515811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // Destructors can appear after the 'return' in the CFG. This is 1525811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // normal. We need to look pass the destructors for the return 1535811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // statement (if it exists). 1545811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend(); 155e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth 156e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth for ( ; ri != re ; ++ri) 157e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth if (isa<CFGStmt>(*ri)) 1585811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek break; 159e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth 1605811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // No more CFGElements in the block? 1615811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek if (ri == re) { 162dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) { 163dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 164dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 165dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 166dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // A labeled empty statement, or the entry block... 167dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasPlainEdge = true; 168dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 169dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 170f39e6a388aaa2f155b46c61e655784b2473218ebTed Kremenek 1715811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek CFGStmt CS = cast<CFGStmt>(*ri); 172f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek const Stmt *S = CS.getStmt(); 173dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<ReturnStmt>(S)) { 174dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasLiveReturn = true; 175dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 176dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 177dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<ObjCAtThrowStmt>(S)) { 178dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 179dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 180dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 181dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<CXXThrowExpr>(S)) { 182dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 183dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 184dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 1858cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier if (isa<MSAsmStmt>(S)) { 1868cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier // TODO: Verify this is correct. 1878cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier HasFakeEdge = true; 1888cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier HasLiveReturn = true; 1898cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier continue; 1908cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier } 191dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<CXXTryStmt>(S)) { 192dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 193dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 194dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 195e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit()) 196e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth == B.succ_end()) { 197e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth HasAbnormalEdge = true; 198e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth continue; 199dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 200e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth 201e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth HasPlainEdge = true; 202dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 203dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!HasPlainEdge) { 204dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasLiveReturn) 205dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return NeverFallThrough; 206dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return NeverFallThroughOrReturn; 207dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 208dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn) 209dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return MaybeFallThrough; 210dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // This says AlwaysFallThrough for calls to functions that are not marked 211dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // noreturn, that don't return. If people would like this warning to be more 212dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // accurate, such functions should be marked as noreturn. 213dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return AlwaysFallThrough; 214dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 215dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 2163c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohmannamespace { 2173c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 218dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstruct CheckFallThroughDiagnostics { 219dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_MaybeFallThrough_HasNoReturn; 220dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_MaybeFallThrough_ReturnsNonVoid; 221dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_AlwaysFallThrough_HasNoReturn; 222dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_AlwaysFallThrough_ReturnsNonVoid; 223dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_NeverFallThroughOrReturn; 224793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor enum { Function, Block, Lambda } funMode; 2250827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis SourceLocation FuncLoc; 226d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 227ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { 228dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughDiagnostics D; 2290827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.FuncLoc = Func->getLocation(); 230dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_HasNoReturn = 231dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_noreturn_function; 232dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_ReturnsNonVoid = 233dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_maybe_falloff_nonvoid_function; 234dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_HasNoReturn = 235dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_noreturn_function; 236dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_ReturnsNonVoid = 237dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_nonvoid_function; 238ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 239ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor // Don't suggest that virtual functions be marked "noreturn", since they 240ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor // might be overridden by non-noreturn functions. 241ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor bool isVirtualMethod = false; 242ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func)) 243ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor isVirtualMethod = Method->isVirtual(); 244ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 245fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor // Don't suggest that template instantiations be marked "noreturn" 246fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor bool isTemplateInstantiation = false; 24775df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func)) 24875df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek isTemplateInstantiation = Function->isTemplateInstantiation(); 249fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor 250fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor if (!isVirtualMethod && !isTemplateInstantiation) 251ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor D.diag_NeverFallThroughOrReturn = 252ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor diag::warn_suggest_noreturn_function; 253ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor else 254ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor D.diag_NeverFallThroughOrReturn = 0; 255ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 256793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.funMode = Function; 257dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return D; 258dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 259d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 260dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek static CheckFallThroughDiagnostics MakeForBlock() { 261dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughDiagnostics D; 262dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_HasNoReturn = 263dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_noreturn_block_has_return_expr; 264dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_ReturnsNonVoid = 265dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_maybe_falloff_nonvoid_block; 266dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_HasNoReturn = 267dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_noreturn_block_has_return_expr; 268dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_ReturnsNonVoid = 269dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_falloff_nonvoid_block; 270dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_NeverFallThroughOrReturn = 271dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_suggest_noreturn_block; 272793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.funMode = Block; 273793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor return D; 274793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor } 275793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor 276793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor static CheckFallThroughDiagnostics MakeForLambda() { 277793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor CheckFallThroughDiagnostics D; 278793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.diag_MaybeFallThrough_HasNoReturn = 279793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor diag::err_noreturn_lambda_has_return_expr; 280793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.diag_MaybeFallThrough_ReturnsNonVoid = 281793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor diag::warn_maybe_falloff_nonvoid_lambda; 282793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.diag_AlwaysFallThrough_HasNoReturn = 283793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor diag::err_noreturn_lambda_has_return_expr; 284793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.diag_AlwaysFallThrough_ReturnsNonVoid = 285793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor diag::warn_falloff_nonvoid_lambda; 286793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.diag_NeverFallThroughOrReturn = 0; 287793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.funMode = Lambda; 288dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return D; 289dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 290d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 291d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid, 292dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasNoReturn) const { 293793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor if (funMode == Function) { 2940827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis return (ReturnsVoid || 2950827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function, 296d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie FuncLoc) == DiagnosticsEngine::Ignored) 2970827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis && (!HasNoReturn || 2980827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr, 299d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie FuncLoc) == DiagnosticsEngine::Ignored) 3000827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis && (!ReturnsVoid || 3010827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 302d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie == DiagnosticsEngine::Ignored); 303dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 304d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 305793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor // For blocks / lambdas. 306793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor return ReturnsVoid && !HasNoReturn 307793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor && ((funMode == Lambda) || 3080827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 309d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie == DiagnosticsEngine::Ignored); 310dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 311dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}; 312dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 3133c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman} 3143c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 315dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a 316dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// function that should return a value. Check that we don't fall off the end 317dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// of a noreturn function. We assume that functions and blocks not marked 318dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// noreturn will return. 319dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, 3203ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek const BlockExpr *blkExpr, 321dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const CheckFallThroughDiagnostics& CD, 3221d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContext &AC) { 323dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 324dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool ReturnsVoid = false; 325dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasNoReturn = false; 326dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 327dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 328dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = FD->getResultType()->isVoidType(); 329dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = FD->hasAttr<NoReturnAttr>() || 330264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola FD->getType()->getAs<FunctionType>()->getNoReturnAttr(); 331dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 332dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 333dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = MD->getResultType()->isVoidType(); 334dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = MD->hasAttr<NoReturnAttr>(); 335dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 336dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (isa<BlockDecl>(D)) { 3373ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek QualType BlockTy = blkExpr->getType(); 338d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek if (const FunctionType *FT = 339dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek BlockTy->getPointeeType()->getAs<FunctionType>()) { 340dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (FT->getResultType()->isVoidType()) 341dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = true; 342dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (FT->getNoReturnAttr()) 343dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = true; 344dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 345dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 346dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 347d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &Diags = S.getDiagnostics(); 348dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 349dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Short circuit for compilation speed. 350dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn)) 351dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return; 352d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 353dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // FIXME: Function try block 354dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { 355dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek switch (CheckFallThrough(AC)) { 35616565aa95b086fb239baf82335dccc1b1ec93942John McCall case UnknownFallThrough: 35716565aa95b086fb239baf82335dccc1b1ec93942John McCall break; 35816565aa95b086fb239baf82335dccc1b1ec93942John McCall 359dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case MaybeFallThrough: 360dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasNoReturn) 361dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 362dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_MaybeFallThrough_HasNoReturn); 363dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (!ReturnsVoid) 364dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 365dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_MaybeFallThrough_ReturnsNonVoid); 366dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 367dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case AlwaysFallThrough: 368dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasNoReturn) 369dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 370dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_AlwaysFallThrough_HasNoReturn); 371dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (!ReturnsVoid) 372dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 373dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_AlwaysFallThrough_ReturnsNonVoid); 374dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 375dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case NeverFallThroughOrReturn: 376b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) { 377b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 378b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn) 379b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor << 0 << FD; 380b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 381b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn) 382b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor << 1 << MD; 383b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth } else { 384b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn); 385b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth } 386b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth } 387dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 388dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case NeverFallThrough: 389dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 390dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 391dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 392dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 393dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 394dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 395610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// -Wuninitialized 396610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 397610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 3986f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremeneknamespace { 3999f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// ContainsReference - A visitor class to search for references to 4009f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// a particular declaration (the needle) within any evaluated component of an 4019f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// expression (recursively). 4026f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenekclass ContainsReference : public EvaluatedExprVisitor<ContainsReference> { 4039f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth bool FoundReference; 4049f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth const DeclRefExpr *Needle; 4059f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth 4066f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenekpublic: 4079f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth ContainsReference(ASTContext &Context, const DeclRefExpr *Needle) 4089f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth : EvaluatedExprVisitor<ContainsReference>(Context), 4099f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth FoundReference(false), Needle(Needle) {} 4109f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth 4119f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth void VisitExpr(Expr *E) { 4126f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek // Stop evaluating if we already have a reference. 4139f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth if (FoundReference) 4146f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek return; 4159f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth 4169f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth EvaluatedExprVisitor<ContainsReference>::VisitExpr(E); 4176f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek } 4189f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth 4199f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth void VisitDeclRefExpr(DeclRefExpr *E) { 4209f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth if (E == Needle) 4219f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth FoundReference = true; 4229f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth else 4239f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth EvaluatedExprVisitor<ContainsReference>::VisitDeclRefExpr(E); 4246f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek } 4259f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth 4269f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth bool doesContainReference() const { return FoundReference; } 4276f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek}; 4286f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek} 4296f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek 4304f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikiestatic bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) { 431a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian QualType VariableTy = VD->getType().getCanonicalType(); 432a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian if (VariableTy->isBlockPointerType() && 433a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian !VD->hasAttr<BlocksAttr>()) { 434a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization) << VD->getDeclName() 435a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian << FixItHint::CreateInsertion(VD->getLocation(), "__block "); 436a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian return true; 437a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian } 438a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian 4394f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie // Don't issue a fixit if there is already an initializer. 4404f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie if (VD->getInit()) 4414f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie return false; 442a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian 4434f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie // Suggest possible initialization (if any). 4442c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie std::string Init = S.getFixItZeroInitializerForType(VariableTy); 4452c0abf4ae33ab2ba690ccae724b8d6f196e7cfdaDavid Blaikie if (Init.empty()) 4464f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie return false; 4477b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu 4487b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu // Don't suggest a fixit inside macros. 4497b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu if (VD->getLocEnd().isMacroID()) 4507b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu return false; 4517b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu 4527984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd()); 453a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian 4547984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName() 4557984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith << FixItHint::CreateInsertion(Loc, Init); 4567984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith return true; 4574f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie} 4584f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie 459bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// Create a fixit to remove an if-like statement, on the assumption that its 460bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// condition is CondVal. 461bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smithstatic void CreateIfFixit(Sema &S, const Stmt *If, const Stmt *Then, 462bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith const Stmt *Else, bool CondVal, 463bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith FixItHint &Fixit1, FixItHint &Fixit2) { 464bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (CondVal) { 465bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // If condition is always true, remove all but the 'then'. 466bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateRemoval( 467bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith CharSourceRange::getCharRange(If->getLocStart(), 468bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Then->getLocStart())); 469bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (Else) { 470bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith SourceLocation ElseKwLoc = Lexer::getLocForEndOfToken( 471bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Then->getLocEnd(), 0, S.getSourceManager(), S.getLangOpts()); 472bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit2 = FixItHint::CreateRemoval( 473bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith SourceRange(ElseKwLoc, Else->getLocEnd())); 474bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith } 475bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith } else { 476bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // If condition is always false, remove all but the 'else'. 477bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (Else) 478bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateRemoval( 479bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith CharSourceRange::getCharRange(If->getLocStart(), 480bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Else->getLocStart())); 481bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith else 482bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateRemoval(If->getSourceRange()); 483bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith } 484bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith} 485bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 486bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// DiagUninitUse -- Helper function to produce a diagnostic for an 487bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// uninitialized use of a variable. 488bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smithstatic void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use, 489bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith bool IsCapturedByBlock) { 490bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith bool Diagnosed = false; 491bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 492bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // Diagnose each branch which leads to a sometimes-uninitialized use. 4932815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith for (UninitUse::branch_iterator I = Use.branch_begin(), E = Use.branch_end(); 4942815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith I != E; ++I) { 495bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith assert(Use.getKind() == UninitUse::Sometimes); 496bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 497bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith const Expr *User = Use.getUser(); 4982815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const Stmt *Term = I->Terminator; 499bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 500bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // Information used when building the diagnostic. 5012815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith unsigned DiagKind; 5022815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const char *Str; 503bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith SourceRange Range; 504bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 505bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // FixIts to suppress the diagnosic by removing the dead condition. 506bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // For all binary terminators, branch 0 is taken if the condition is true, 507bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // and branch 1 is taken if the condition is false. 508bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith int RemoveDiagKind = -1; 509bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith const char *FixitStr = 510bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith S.getLangOpts().CPlusPlus ? (I->Output ? "true" : "false") 511bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith : (I->Output ? "1" : "0"); 512bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith FixItHint Fixit1, Fixit2; 513bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 5142815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith switch (Term->getStmtClass()) { 5152815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith default: 516bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // Don't know how to report this. Just fall back to 'may be used 517bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // uninitialized'. This happens for range-based for, which the user 518bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // can't explicitly fix. 519bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // FIXME: This also happens if the first use of a variable is always 520bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // uninitialized, eg "for (int n; n < 10; ++n)". We should report that 521bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // with the 'is uninitialized' diagnostic. 5222815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith continue; 5232815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 5242815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith // "condition is true / condition is false". 525bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith case Stmt::IfStmtClass: { 526bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith const IfStmt *IS = cast<IfStmt>(Term); 5272815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 0; 5282815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "if"; 529bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Range = IS->getCond()->getSourceRange(); 530bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 0; 531bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith CreateIfFixit(S, IS, IS->getThen(), IS->getElse(), 532bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith I->Output, Fixit1, Fixit2); 5332815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 534bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith } 535bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith case Stmt::ConditionalOperatorClass: { 536bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith const ConditionalOperator *CO = cast<ConditionalOperator>(Term); 5372815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 0; 5382815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "?:"; 539bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Range = CO->getCond()->getSourceRange(); 540bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 0; 541bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(), 542bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith I->Output, Fixit1, Fixit2); 5432815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 544bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith } 5452815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::BinaryOperatorClass: { 5462815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const BinaryOperator *BO = cast<BinaryOperator>(Term); 5472815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith if (!BO->isLogicalOp()) 5482815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith continue; 5492815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 0; 5502815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = BO->getOpcodeStr(); 5512815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = BO->getLHS()->getSourceRange(); 552bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 0; 553bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if ((BO->getOpcode() == BO_LAnd && I->Output) || 554bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith (BO->getOpcode() == BO_LOr && !I->Output)) 555bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // true && y -> y, false || y -> y. 556bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateRemoval(SourceRange(BO->getLocStart(), 557bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith BO->getOperatorLoc())); 558bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith else 559bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // false && y -> false, true || y -> true. 560bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateReplacement(BO->getSourceRange(), FixitStr); 5612815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 5622815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith } 5632815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 5642815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith // "loop is entered / loop is exited". 5652815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::WhileStmtClass: 5662815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 1; 5672815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "while"; 5682815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = cast<WhileStmt>(Term)->getCond()->getSourceRange(); 569bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 1; 570bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateReplacement(Range, FixitStr); 5712815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 5722815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::ForStmtClass: 5732815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 1; 5742815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "for"; 5752815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = cast<ForStmt>(Term)->getCond()->getSourceRange(); 576bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 1; 577bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (I->Output) 578bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateRemoval(Range); 579bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith else 580bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateReplacement(Range, FixitStr); 5812815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 5822815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 5832815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith // "condition is true / loop is exited". 5842815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::DoStmtClass: 5852815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 2; 5862815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "do"; 5872815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = cast<DoStmt>(Term)->getCond()->getSourceRange(); 588bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 1; 589bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateReplacement(Range, FixitStr); 5902815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 5912815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 5922815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith // "switch case is taken". 5932815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::CaseStmtClass: 5942815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 3; 5952815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "case"; 5962815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = cast<CaseStmt>(Term)->getLHS()->getSourceRange(); 5972815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 5982815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::DefaultStmtClass: 5992815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 3; 6002815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "default"; 6012815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = cast<DefaultStmt>(Term)->getDefaultLoc(); 6022815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 6032815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith } 6042815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 605bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith S.Diag(Range.getBegin(), diag::warn_sometimes_uninit_var) 606bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << VD->getDeclName() << IsCapturedByBlock << DiagKind 607bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << Str << I->Output << Range; 608bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith S.Diag(User->getLocStart(), diag::note_uninit_var_use) 609bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << IsCapturedByBlock << User->getSourceRange(); 610bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (RemoveDiagKind != -1) 611bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith S.Diag(Fixit1.RemoveRange.getBegin(), diag::note_uninit_fixit_remove_cond) 612bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2; 613bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 614bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Diagnosed = true; 6152815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith } 616bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 617bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (!Diagnosed) 618bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith S.Diag(Use.getUser()->getLocStart(), 619bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Use.getKind() == UninitUse::Always ? diag::warn_uninit_var 620bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith : diag::warn_maybe_uninit_var) 621bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << VD->getDeclName() << IsCapturedByBlock 622bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << Use.getUser()->getSourceRange(); 6232815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith} 6242815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 625262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an 626262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// uninitialized variable. This manages the different forms of diagnostic 627262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// emitted for particular types of uses. Returns true if the use was diagnosed 6282815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith/// as a warning. If a particular use is one we omit warnings for, returns 629262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// false. 630262d50e1dcf529317da193ad585c11c16281a7acChandler Carruthstatic bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD, 6312815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const UninitUse &Use, 6329e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek bool alwaysReportSelfInit = false) { 6334c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth 6342815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Use.getUser())) { 635f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // Inspect the initializer of the variable declaration which is 636f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // being referenced prior to its initialization. We emit 637f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // specialized diagnostics for self-initialization, and we 638f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // specifically avoid warning about self references which take the 639f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // form of: 640f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // 641f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // int x = x; 642f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // 643f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // This is used to indicate to GCC that 'x' is intentionally left 644f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // uninitialized. Proven code paths which access 'x' in 645f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // an uninitialized state after this will still warn. 646f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu if (const Expr *Initializer = VD->getInit()) { 647f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu if (!alwaysReportSelfInit && DRE == Initializer->IgnoreParenImpCasts()) 648f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu return false; 649f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu 650f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu ContainsReference CR(S.Context, DRE); 651f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu CR.Visit(const_cast<Expr*>(Initializer)); 652f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu if (CR.doesContainReference()) { 6534c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth S.Diag(DRE->getLocStart(), 6544c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth diag::warn_uninit_self_reference_in_init) 655f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu << VD->getDeclName() << VD->getLocation() << DRE->getSourceRange(); 656f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu return true; 6574c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth } 6584c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth } 659f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu 660bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith DiagUninitUse(S, VD, Use, false); 6614c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth } else { 6622815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const BlockExpr *BE = cast<BlockExpr>(Use.getUser()); 663bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (VD->getType()->isBlockPointerType() && !VD->hasAttr<BlocksAttr>()) 664bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith S.Diag(BE->getLocStart(), 665bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith diag::warn_uninit_byref_blockvar_captured_by_block) 666a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian << VD->getDeclName(); 667bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith else 668bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith DiagUninitUse(S, VD, Use, true); 6694c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth } 6704c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth 6714c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth // Report where the variable was declared when the use wasn't within 6724f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie // the initializer of that declaration & we didn't already suggest 6734f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie // an initialization fixit. 674f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu if (!SuggestInitializationFixit(S, VD)) 6754c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth S.Diag(VD->getLocStart(), diag::note_uninit_var_def) 6764c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth << VD->getDeclName(); 6774c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth 678262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth return true; 67964fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth} 68064fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth 681e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smithnamespace { 682e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> { 683e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith public: 684e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FallthroughMapper(Sema &S) 685e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith : FoundSwitchStatements(false), 686e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith S(S) { 687e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 688e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 689e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool foundSwitchStatements() const { return FoundSwitchStatements; } 690e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 691e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith void markFallthroughVisited(const AttributedStmt *Stmt) { 692e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool Found = FallthroughStmts.erase(Stmt); 693e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith assert(Found); 6943bb2994a7de3679fb825f3a36f3dc11ea1daf6a6Kaelyn Uhrain (void)Found; 695e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 696e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 697e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts; 698e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 699e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const AttrStmts &getFallthroughStmts() const { 700e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return FallthroughStmts; 701e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 702e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 703e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) { 704e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith int UnannotatedCnt = 0; 705e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith AnnotatedCnt = 0; 706e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 707e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith std::deque<const CFGBlock*> BlockQueue; 708e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 709e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith std::copy(B.pred_begin(), B.pred_end(), std::back_inserter(BlockQueue)); 710e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 711e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith while (!BlockQueue.empty()) { 712e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const CFGBlock *P = BlockQueue.front(); 713e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith BlockQueue.pop_front(); 714e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 715e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const Stmt *Term = P->getTerminator(); 716e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (Term && isa<SwitchStmt>(Term)) 717e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; // Switch statement, good. 718e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 719e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel()); 720e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end()) 721e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; // Previous case label has no statements, good. 722e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 723e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (P->pred_begin() == P->pred_end()) { // The block is unreachable. 724e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // This only catches trivially unreachable blocks. 725e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith for (CFGBlock::const_iterator ElIt = P->begin(), ElEnd = P->end(); 726e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ElIt != ElEnd; ++ElIt) { 727e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (const CFGStmt *CS = ElIt->getAs<CFGStmt>()){ 728e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) { 729e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith S.Diag(AS->getLocStart(), 730e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith diag::warn_fallthrough_attr_unreachable); 731e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith markFallthroughVisited(AS); 732e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ++AnnotatedCnt; 733e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 734e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // Don't care about other unreachable statements. 735e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 736e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 737e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // If there are no unreachable statements, this may be a special 738e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // case in CFG: 739e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // case X: { 740e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // A a; // A has a destructor. 741e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // break; 742e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // } 743e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // // <<<< This place is represented by a 'hanging' CFG block. 744e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // case Y: 745e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; 746e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 747e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 748e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const Stmt *LastStmt = getLastStmt(*P); 749e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) { 750e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith markFallthroughVisited(AS); 751e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ++AnnotatedCnt; 752e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; // Fallthrough annotation, good. 753e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 754e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 755e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!LastStmt) { // This block contains no executable statements. 756e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // Traverse its predecessors. 757e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith std::copy(P->pred_begin(), P->pred_end(), 758e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith std::back_inserter(BlockQueue)); 759e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; 760e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 761e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 762e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ++UnannotatedCnt; 763e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 764e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return !!UnannotatedCnt; 765e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 766e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 767e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // RecursiveASTVisitor setup. 768e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool shouldWalkTypesOfTypeLocs() const { return false; } 769e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 770e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool VisitAttributedStmt(AttributedStmt *S) { 771e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (asFallThroughAttr(S)) 772e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FallthroughStmts.insert(S); 773e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return true; 774e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 775e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 776e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool VisitSwitchStmt(SwitchStmt *S) { 777e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FoundSwitchStatements = true; 778e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return true; 779e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 780e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 781e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith private: 782e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 783e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith static const AttributedStmt *asFallThroughAttr(const Stmt *S) { 784e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) { 785e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs())) 786e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return AS; 787e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 788e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return 0; 789e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 790e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 791e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith static const Stmt *getLastStmt(const CFGBlock &B) { 792e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (const Stmt *Term = B.getTerminator()) 793e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return Term; 794e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith for (CFGBlock::const_reverse_iterator ElemIt = B.rbegin(), 795e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ElemEnd = B.rend(); 796e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ElemIt != ElemEnd; ++ElemIt) { 797e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (const CFGStmt *CS = ElemIt->getAs<CFGStmt>()) 798e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return CS->getStmt(); 799e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 800e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // Workaround to detect a statement thrown out by CFGBuilder: 801e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // case X: {} case Y: 802e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // case X: ; case Y: 803e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel())) 804e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!isa<SwitchCase>(SW->getSubStmt())) 805e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return SW->getSubStmt(); 806e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 807e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return 0; 808e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 809e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 810e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool FoundSwitchStatements; 811e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith AttrStmts FallthroughStmts; 812e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith Sema &S; 813e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith }; 814e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith} 815e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 8161973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienkostatic void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC, 817c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt bool PerFunction) { 818e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FallthroughMapper FM(S); 819e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FM.TraverseStmt(AC.getBody()); 820e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 821e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!FM.foundSwitchStatements()) 822e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return; 823e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 824c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt if (PerFunction && FM.getFallthroughStmts().empty()) 8251973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko return; 8261973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko 827e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith CFG *Cfg = AC.getCFG(); 828e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 829e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!Cfg) 830e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return; 831e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 832e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith int AnnotatedCnt; 833e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 834e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith for (CFG::reverse_iterator I = Cfg->rbegin(), E = Cfg->rend(); I != E; ++I) { 835e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const CFGBlock &B = **I; 836e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const Stmt *Label = B.getLabel(); 837e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 838e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!Label || !isa<SwitchCase>(Label)) 839e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; 840e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 841e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!FM.checkFallThroughIntoBlock(B, AnnotatedCnt)) 842e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; 843e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 8441973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko S.Diag(Label->getLocStart(), 845c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt PerFunction ? diag::warn_unannotated_fallthrough_per_function 846c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt : diag::warn_unannotated_fallthrough); 847e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 848e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!AnnotatedCnt) { 849e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith SourceLocation L = Label->getLocStart(); 850e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (L.isMacroID()) 851e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; 852e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (S.getLangOpts().CPlusPlus0x) { 853a189d8976f1193b788508a1a29b2e9d0aca06acaAlexander Kornienko const Stmt *Term = B.getTerminator(); 854a189d8976f1193b788508a1a29b2e9d0aca06acaAlexander Kornienko if (!(B.empty() && Term && isa<BreakStmt>(Term))) { 855a189d8976f1193b788508a1a29b2e9d0aca06acaAlexander Kornienko S.Diag(L, diag::note_insert_fallthrough_fixit) << 856a189d8976f1193b788508a1a29b2e9d0aca06acaAlexander Kornienko FixItHint::CreateInsertion(L, "[[clang::fallthrough]]; "); 857a189d8976f1193b788508a1a29b2e9d0aca06acaAlexander Kornienko } 858e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 859e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith S.Diag(L, diag::note_insert_break_fixit) << 860e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FixItHint::CreateInsertion(L, "break; "); 861e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 862e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 863e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 864e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const FallthroughMapper::AttrStmts &Fallthroughs = FM.getFallthroughStmts(); 865e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith for (FallthroughMapper::AttrStmts::const_iterator I = Fallthroughs.begin(), 866e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith E = Fallthroughs.end(); 867e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith I != E; ++I) { 868e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith S.Diag((*I)->getLocStart(), diag::warn_fallthrough_attr_invalid_placement); 869e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 870e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 871e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith} 872e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 873610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremeneknamespace { 87494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenekstruct SLocSort { 875f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek bool operator()(const UninitUse &a, const UninitUse &b) { 8762815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith // Prefer a more confident report over a less confident one. 8772815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith if (a.getKind() != b.getKind()) 8782815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith return a.getKind() > b.getKind(); 8792815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith SourceLocation aLoc = a.getUser()->getLocStart(); 8802815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith SourceLocation bLoc = b.getUser()->getLocStart(); 88194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek return aLoc.getRawEncoding() < bLoc.getRawEncoding(); 88294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 88394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek}; 88494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 885610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass UninitValsDiagReporter : public UninitVariablesHandler { 886610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek Sema &S; 8875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner typedef SmallVector<UninitUse, 2> UsesVec; 8889e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek typedef llvm::DenseMap<const VarDecl *, std::pair<UsesVec*, bool> > UsesMap; 88994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek UsesMap *uses; 89094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 891610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic: 89294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek UninitValsDiagReporter(Sema &S) : S(S), uses(0) {} 89394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek ~UninitValsDiagReporter() { 89494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek flushDiagnostics(); 89594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 8969e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 8979e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek std::pair<UsesVec*, bool> &getUses(const VarDecl *vd) { 89894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek if (!uses) 89994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek uses = new UsesMap(); 9009e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 9019e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek UsesMap::mapped_type &V = (*uses)[vd]; 9029e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek UsesVec *&vec = V.first; 90394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek if (!vec) 90494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek vec = new UsesVec(); 90594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 9069e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek return V; 9079e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek } 9089e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 9092815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith void handleUseOfUninitVariable(const VarDecl *vd, const UninitUse &use) { 9102815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith getUses(vd).first->push_back(use); 9119e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek } 9129e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 9139e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek void handleSelfInit(const VarDecl *vd) { 9149e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek getUses(vd).second = true; 91594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 91694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 91794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek void flushDiagnostics() { 91894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek if (!uses) 91994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek return; 920609e3170841dac81c3b7b6b9eccb9c520e42c9b2Ted Kremenek 921818918855d84e3db1af5a0807070d4995ca2cf75Richard Smith // FIXME: This iteration order, and thus the resulting diagnostic order, 922818918855d84e3db1af5a0807070d4995ca2cf75Richard Smith // is nondeterministic. 92394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) { 92494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek const VarDecl *vd = i->first; 9259e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek const UsesMap::mapped_type &V = i->second; 9269e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 9279e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek UsesVec *vec = V.first; 9289e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek bool hasSelfInit = V.second; 9299e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 9309e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // Specially handle the case where we have uses of an uninitialized 9319e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // variable, but the root cause is an idiomatic self-init. We want 9329e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // to report the diagnostic at the self-init since that is the root cause. 9330d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay if (!vec->empty() && hasSelfInit && hasAlwaysUninitializedUse(vec)) 9342815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagnoseUninitializedUse(S, vd, 9352815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith UninitUse(vd->getInit()->IgnoreParenCasts(), 9362815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /* isAlwaysUninit */ true), 9370d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay /* alwaysReportSelfInit */ true); 9389e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek else { 9399e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // Sort the uses by their SourceLocations. While not strictly 9409e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // guaranteed to produce them in line/column order, this will provide 9419e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // a stable ordering. 9429e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek std::sort(vec->begin(), vec->end(), SLocSort()); 9439e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 9449e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; 9459e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek ++vi) { 9462815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith // If we have self-init, downgrade all uses to 'may be uninitialized'. 9472815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith UninitUse Use = hasSelfInit ? UninitUse(vi->getUser(), false) : *vi; 9482815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 9492815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith if (DiagnoseUninitializedUse(S, vd, Use)) 9509e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // Skip further diagnostics for this variable. We try to warn only 9519e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // on the first point at which a variable is used uninitialized. 9529e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek break; 9539e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek } 95464fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth } 9559e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 9569e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // Release the uses vector. 95794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek delete vec; 95894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 95994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek delete uses; 960610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 9610d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay 9620d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gayprivate: 9630d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay static bool hasAlwaysUninitializedUse(const UsesVec* vec) { 9640d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay for (UsesVec::const_iterator i = vec->begin(), e = vec->end(); i != e; ++i) { 9652815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith if (i->getKind() == UninitUse::Always) { 9660d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay return true; 9670d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay } 9680d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay } 9690d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay return false; 9700d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay} 971610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}; 972610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 973610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 9743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 9753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski//===----------------------------------------------------------------------===// 9763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// -Wthread-safety 9773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski//===----------------------------------------------------------------------===// 97875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskinamespace clang { 97975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskinamespace thread_safety { 9802e5156274b8051217565b557bfa14c80f7990e9cRichard Smithtypedef llvm::SmallVector<PartialDiagnosticAt, 1> OptionalNotes; 9812e5156274b8051217565b557bfa14c80f7990e9cRichard Smithtypedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag; 982ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramertypedef std::list<DelayedDiag> DiagList; 98375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 98475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskistruct SortDiagBySourceLocation { 985ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer SourceManager &SM; 986ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer SortDiagBySourceLocation(SourceManager &SM) : SM(SM) {} 98775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 98875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski bool operator()(const DelayedDiag &left, const DelayedDiag &right) { 98975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski // Although this call will be slow, this is only called when outputting 99075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski // multiple warnings. 991ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer return SM.isBeforeInTranslationUnit(left.first.first, right.first.first); 99275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 99375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski}; 99475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 99599ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikienamespace { 99675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskiclass ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler { 99775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski Sema &S; 99875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski DiagList Warnings; 9992e5156274b8051217565b557bfa14c80f7990e9cRichard Smith SourceLocation FunLocation, FunEndLocation; 100075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 100175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski // Helper functions 100275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski void warnLockMismatch(unsigned DiagID, Name LockName, SourceLocation Loc) { 1003f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins // Gracefully handle rare cases when the analysis can't get a more 1004f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins // precise source location. 1005f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins if (!Loc.isValid()) 1006f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins Loc = FunLocation; 10072e5156274b8051217565b557bfa14c80f7990e9cRichard Smith PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << LockName); 10082e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 100975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 101075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 101175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski public: 10122e5156274b8051217565b557bfa14c80f7990e9cRichard Smith ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL) 10132e5156274b8051217565b557bfa14c80f7990e9cRichard Smith : S(S), FunLocation(FL), FunEndLocation(FEL) {} 101475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 101575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski /// \brief Emit all buffered diagnostics in order of sourcelocation. 101675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski /// We need to output diagnostics produced while iterating through 101775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski /// the lockset in deterministic order, so this function orders diagnostics 101875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski /// and outputs them. 101975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski void emitDiagnostics() { 1020ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer Warnings.sort(SortDiagBySourceLocation(S.getSourceManager())); 102175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski for (DiagList::iterator I = Warnings.begin(), E = Warnings.end(); 10222e5156274b8051217565b557bfa14c80f7990e9cRichard Smith I != E; ++I) { 10232e5156274b8051217565b557bfa14c80f7990e9cRichard Smith S.Diag(I->first.first, I->first.second); 10242e5156274b8051217565b557bfa14c80f7990e9cRichard Smith const OptionalNotes &Notes = I->second; 10252e5156274b8051217565b557bfa14c80f7990e9cRichard Smith for (unsigned NoteI = 0, NoteN = Notes.size(); NoteI != NoteN; ++NoteI) 10262e5156274b8051217565b557bfa14c80f7990e9cRichard Smith S.Diag(Notes[NoteI].first, Notes[NoteI].second); 10272e5156274b8051217565b557bfa14c80f7990e9cRichard Smith } 102875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 102975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 103099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski void handleInvalidLockExp(SourceLocation Loc) { 10312e5156274b8051217565b557bfa14c80f7990e9cRichard Smith PartialDiagnosticAt Warning(Loc, 10322e5156274b8051217565b557bfa14c80f7990e9cRichard Smith S.PDiag(diag::warn_cannot_resolve_lock) << Loc); 10332e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 103499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski } 103575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) { 103675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski warnLockMismatch(diag::warn_unlock_but_no_lock, LockName, Loc); 103775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 103875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 103975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski void handleDoubleLock(Name LockName, SourceLocation Loc) { 104075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski warnLockMismatch(diag::warn_double_lock, LockName, Loc); 104175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 104275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 10432e5156274b8051217565b557bfa14c80f7990e9cRichard Smith void handleMutexHeldEndOfScope(Name LockName, SourceLocation LocLocked, 10442e5156274b8051217565b557bfa14c80f7990e9cRichard Smith SourceLocation LocEndOfScope, 10454e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski LockErrorKind LEK){ 10464e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski unsigned DiagID = 0; 10474e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski switch (LEK) { 10484e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski case LEK_LockedSomePredecessors: 10492e5156274b8051217565b557bfa14c80f7990e9cRichard Smith DiagID = diag::warn_lock_some_predecessors; 10504e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski break; 10514e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski case LEK_LockedSomeLoopIterations: 10524e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski DiagID = diag::warn_expecting_lock_held_on_loop; 10534e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski break; 10544e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski case LEK_LockedAtEndOfFunction: 10554e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski DiagID = diag::warn_no_unlock; 10564e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski break; 1057879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins case LEK_NotLockedAtEndOfFunction: 1058879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins DiagID = diag::warn_expecting_locked; 1059879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins break; 10604e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski } 10612e5156274b8051217565b557bfa14c80f7990e9cRichard Smith if (LocEndOfScope.isInvalid()) 10622e5156274b8051217565b557bfa14c80f7990e9cRichard Smith LocEndOfScope = FunEndLocation; 10632e5156274b8051217565b557bfa14c80f7990e9cRichard Smith 10642e5156274b8051217565b557bfa14c80f7990e9cRichard Smith PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << LockName); 10652e5156274b8051217565b557bfa14c80f7990e9cRichard Smith PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here)); 10662e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); 106775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 106875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 106975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 107075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski void handleExclusiveAndShared(Name LockName, SourceLocation Loc1, 107175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski SourceLocation Loc2) { 10722e5156274b8051217565b557bfa14c80f7990e9cRichard Smith PartialDiagnosticAt Warning( 10732e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Loc1, S.PDiag(diag::warn_lock_exclusive_and_shared) << LockName); 10742e5156274b8051217565b557bfa14c80f7990e9cRichard Smith PartialDiagnosticAt Note( 10752e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Loc2, S.PDiag(diag::note_lock_exclusive_and_shared) << LockName); 10762e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); 107775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 107875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 107975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK, 108075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski AccessKind AK, SourceLocation Loc) { 1081df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski assert((POK == POK_VarAccess || POK == POK_VarDereference) 1082df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski && "Only works for variables"); 1083df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski unsigned DiagID = POK == POK_VarAccess? 1084df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski diag::warn_variable_requires_any_lock: 1085df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski diag::warn_var_deref_requires_any_lock; 10862e5156274b8051217565b557bfa14c80f7990e9cRichard Smith PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) 10872e5156274b8051217565b557bfa14c80f7990e9cRichard Smith << D->getName() << getLockKindFromAccessKind(AK)); 10882e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 108975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 109075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 109175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski void handleMutexNotHeld(const NamedDecl *D, ProtectedOperationKind POK, 10923f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins Name LockName, LockKind LK, SourceLocation Loc, 10933f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins Name *PossibleMatch) { 1094e87158dfbca01577810f301543c3cdcfc955d8b0Caitlin Sadowski unsigned DiagID = 0; 10953f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins if (PossibleMatch) { 10963f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins switch (POK) { 10973f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_VarAccess: 10983f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_variable_requires_lock_precise; 10993f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 11003f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_VarDereference: 11013f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_var_deref_requires_lock_precise; 11023f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 11033f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_FunctionCall: 11043f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_fun_requires_lock_precise; 11053f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 11063f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins } 11073f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) 11083f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins << D->getName() << LockName << LK); 11093f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match) 11103f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins << *PossibleMatch); 11113f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); 11123f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins } else { 11133f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins switch (POK) { 11143f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_VarAccess: 11153f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_variable_requires_lock; 11163f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 11173f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_VarDereference: 11183f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_var_deref_requires_lock; 11193f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 11203f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_FunctionCall: 11213f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_fun_requires_lock; 11223f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 11233f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins } 11243f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) 11253f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins << D->getName() << LockName << LK); 11263f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 112775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 112875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 112975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 113075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski void handleFunExcludesLock(Name FunName, Name LockName, SourceLocation Loc) { 11312e5156274b8051217565b557bfa14c80f7990e9cRichard Smith PartialDiagnosticAt Warning(Loc, 11322e5156274b8051217565b557bfa14c80f7990e9cRichard Smith S.PDiag(diag::warn_fun_excludes_mutex) << FunName << LockName); 11332e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 113475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 113575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski}; 113675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski} 113775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski} 113899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie} 113975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 1140610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 1141dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based 1142dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// warnings on a function, method, or block. 1143dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 1144dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 1145d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekclang::sema::AnalysisBasedWarnings::Policy::Policy() { 1146dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek enableCheckFallThrough = 1; 1147d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek enableCheckUnreachable = 0; 11483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski enableThreadSafetyAnalysis = 0; 1149d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek} 1150dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 11515d98994c7749312a43ce6adf45537979a98e7afdChandler Carruthclang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) 11525d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth : S(s), 11535d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth NumFunctionsAnalyzed(0), 115454cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer NumFunctionsWithBadCFGs(0), 11555d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth NumCFGBlocks(0), 115654cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer MaxCFGBlocksPerFunction(0), 115754cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer NumUninitAnalysisFunctions(0), 115854cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer NumUninitAnalysisVariables(0), 115954cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer MaxUninitAnalysisVariablesPerFunction(0), 116054cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer NumUninitAnalysisBlockVisits(0), 116154cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer MaxUninitAnalysisBlockVisitsPerFunction(0) { 1162d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &D = S.getDiagnostics(); 1163d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek DefaultPolicy.enableCheckUnreachable = (unsigned) 11640827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis (D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) != 1165d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine::Ignored); 11663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski DefaultPolicy.enableThreadSafetyAnalysis = (unsigned) 11673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski (D.getDiagnosticLevel(diag::warn_double_lock, SourceLocation()) != 1168d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine::Ignored); 11693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 1170dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 1171dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 1172351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekstatic void flushDiagnostics(Sema &S, sema::FunctionScopeInfo *fscope) { 11735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator 1174351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek i = fscope->PossiblyUnreachableDiags.begin(), 1175351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek e = fscope->PossiblyUnreachableDiags.end(); 1176351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek i != e; ++i) { 1177351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek const sema::PossiblyUnreachableDiag &D = *i; 1178351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek S.Diag(D.Loc, D.PD); 1179351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek } 1180351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek} 1181351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 1182d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekvoid clang::sema:: 1183d064fdc4b7b64ca55b40b70490c79d6f569df78eTed KremenekAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 1184283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek sema::FunctionScopeInfo *fscope, 11853ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek const Decl *D, const BlockExpr *blkExpr) { 1186d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek 1187dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // We avoid doing analysis-based warnings when there are errors for 1188dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // two reasons: 1189dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // (1) The CFGs often can't be constructed (if the body is invalid), so 1190dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // don't bother trying. 1191dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // (2) The code already has problems; running the analysis just takes more 1192dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // time. 1193d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &Diags = S.getDiagnostics(); 119499e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek 1195d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek // Do not do any analysis for declarations in system headers if we are 1196d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek // going to just ignore them. 119799e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek if (Diags.getSuppressSystemWarnings() && 1198d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek S.SourceMgr.isInSystemHeader(D->getLocation())) 1199d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek return; 1200d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 1201e0054f61fd84133eb0d19c19ae9afaf117933274John McCall // For code in dependent contexts, we'll do this at instantiation time. 120223661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (cast<DeclContext>(D)->isDependentContext()) 120323661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie return; 1204dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 1205351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) { 1206351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek // Flush out any possibly unreachable diagnostics. 1207351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek flushDiagnostics(S, fscope); 1208351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek return; 1209351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek } 1210351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 1211dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const Stmt *Body = D->getBody(); 1212dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek assert(Body); 1213dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 1214d200187bd27f9ad68699693a6e57f9ee3ff260faJordy Rose AnalysisDeclContext AC(/* AnalysisDeclContextManager */ 0, D); 1215bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek 1216dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Don't generate EH edges for CallExprs as we'd like to avoid the n^2 1217dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // explosion for destrutors that can result and the compile time hit. 1218bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true; 1219bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek AC.getCFGBuildOptions().AddEHEdges = false; 1220bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek AC.getCFGBuildOptions().AddInitializers = true; 1221bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek AC.getCFGBuildOptions().AddImplicitDtors = true; 1222faadf48443f8c2fc53d267485d7e0e1bd382fc75Jordan Rose AC.getCFGBuildOptions().AddTemporaryDtors = true; 1223faadf48443f8c2fc53d267485d7e0e1bd382fc75Jordan Rose 12240c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // Force that certain expressions appear as CFGElements in the CFG. This 12250c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // is used to speed up various analyses. 12260c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // FIXME: This isn't the right factoring. This is here for initial 12270c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // prototyping, but we need a way for analyses to say what expressions they 12280c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // expect to always be CFGElements and then fill in the BuildOptions 12290c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // appropriately. This is essentially a layering violation. 12301fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis) { 12311fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins // Unreachable code analysis and thread safety require a linearized CFG. 12320f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek AC.getCFGBuildOptions().setAllAlwaysAdd(); 12330f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek } 12340f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek else { 12350f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek AC.getCFGBuildOptions() 12360f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek .setAlwaysAdd(Stmt::BinaryOperatorClass) 12376cfa78f6bd4e7d5e23366a0907f8f8792366bc4cRichard Smith .setAlwaysAdd(Stmt::CompoundAssignOperatorClass) 12380f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek .setAlwaysAdd(Stmt::BlockExprClass) 12390f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek .setAlwaysAdd(Stmt::CStyleCastExprClass) 12400f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek .setAlwaysAdd(Stmt::DeclRefExprClass) 12410f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek .setAlwaysAdd(Stmt::ImplicitCastExprClass) 1242e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith .setAlwaysAdd(Stmt::UnaryOperatorClass) 1243e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith .setAlwaysAdd(Stmt::AttributedStmtClass); 12440f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek } 1245bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek 1246bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek // Construct the analysis context with the specified CFG build options. 1247bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek 1248351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek // Emit delayed diagnostics. 124923661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (!fscope->PossiblyUnreachableDiags.empty()) { 1250351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek bool analyzed = false; 12510d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 12520d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek // Register the expressions with the CFGBuilder. 12535f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator 12540d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek i = fscope->PossiblyUnreachableDiags.begin(), 12550d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek e = fscope->PossiblyUnreachableDiags.end(); 12560d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek i != e; ++i) { 12570d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek if (const Stmt *stmt = i->stmt) 12580d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek AC.registerForcedBlockExpression(stmt); 12590d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek } 12600d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 12610d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek if (AC.getCFG()) { 12620d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek analyzed = true; 12635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator 12640d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek i = fscope->PossiblyUnreachableDiags.begin(), 12650d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek e = fscope->PossiblyUnreachableDiags.end(); 12660d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek i != e; ++i) 12670d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek { 12680d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek const sema::PossiblyUnreachableDiag &D = *i; 12690d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek bool processed = false; 12700d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek if (const Stmt *stmt = i->stmt) { 12710d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek const CFGBlock *block = AC.getBlockForRegisteredExpression(stmt); 127271b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman CFGReverseBlockReachabilityAnalysis *cra = 127371b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman AC.getCFGReachablityAnalysis(); 127471b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman // FIXME: We should be able to assert that block is non-null, but 127571b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman // the CFG analysis can skip potentially-evaluated expressions in 127671b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman // edge cases; see test/Sema/vla-2.c. 127771b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman if (block && cra) { 1278351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek // Can this block be reached from the entrance? 12790d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek if (cra->isReachable(&AC.getCFG()->getEntry(), block)) 1280351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek S.Diag(D.Loc, D.PD); 12810d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek processed = true; 1282351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek } 12830d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek } 12840d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek if (!processed) { 12850d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek // Emit the warning anyway if we cannot map to a basic block. 12860d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek S.Diag(D.Loc, D.PD); 1287351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek } 1288351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek } 12890d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek } 1290351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 1291351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek if (!analyzed) 1292351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek flushDiagnostics(S, fscope); 1293351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek } 1294351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 1295351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 1296dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Warning: check missing 'return' 129723661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (P.enableCheckFallThrough) { 1298dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const CheckFallThroughDiagnostics &CD = 1299dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock() 1300793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor : (isa<CXXMethodDecl>(D) && 1301793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call && 1302793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor cast<CXXMethodDecl>(D)->getParent()->isLambda()) 1303793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor ? CheckFallThroughDiagnostics::MakeForLambda() 1304793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor : CheckFallThroughDiagnostics::MakeForFunction(D)); 13053ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC); 1306dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 1307dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 1308dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Warning: check for unreachable code 13095dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek if (P.enableCheckUnreachable) { 13105dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek // Only check for unreachable code on non-template instantiations. 13115dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek // Different template instantiations can effectively change the control-flow 13125dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek // and it is very difficult to prove that a snippet of code in a template 13135dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek // is unreachable for all instantiations. 131475df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek bool isTemplateInstantiation = false; 131575df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) 131675df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek isTemplateInstantiation = Function->isTemplateInstantiation(); 131775df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek if (!isTemplateInstantiation) 13185dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek CheckUnreachable(S, AC); 13195dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek } 132075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 13213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Check for thread safety violations 132223661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (P.enableThreadSafetyAnalysis) { 1323f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins SourceLocation FL = AC.getDecl()->getLocation(); 13242e5156274b8051217565b557bfa14c80f7990e9cRichard Smith SourceLocation FEL = AC.getDecl()->getLocEnd(); 13252e5156274b8051217565b557bfa14c80f7990e9cRichard Smith thread_safety::ThreadSafetyReporter Reporter(S, FL, FEL); 132675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski thread_safety::runThreadSafetyAnalysis(AC, Reporter); 132775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski Reporter.emitDiagnostics(); 132875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 13293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 1330a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart()) 1331d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie != DiagnosticsEngine::Ignored || 13322815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Diags.getDiagnosticLevel(diag::warn_sometimes_uninit_var,D->getLocStart()) 13332815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith != DiagnosticsEngine::Ignored || 133476709bf816e5e1b70b859bb607cf3ee91db12b76Ted Kremenek Diags.getDiagnosticLevel(diag::warn_maybe_uninit_var, D->getLocStart()) 1335d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie != DiagnosticsEngine::Ignored) { 1336c5e43c19ddb40b8a1371291f73ae66fe54951ca5Ted Kremenek if (CFG *cfg = AC.getCFG()) { 1337c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek UninitValsDiagReporter reporter(S); 133857080fbac1ccce702255423335d52e81bcf17b6bFariborz Jahanian UninitVariablesAnalysisStats stats; 133912efd57ee474c06880a7434ece21a39ac3f34e24Benjamin Kramer std::memset(&stats, 0, sizeof(UninitVariablesAnalysisStats)); 1340a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC, 13415d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth reporter, stats); 13425d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 13435d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth if (S.CollectStats && stats.NumVariablesAnalyzed > 0) { 13445d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth ++NumUninitAnalysisFunctions; 13455d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth NumUninitAnalysisVariables += stats.NumVariablesAnalyzed; 13465d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth NumUninitAnalysisBlockVisits += stats.NumBlockVisits; 13475d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth MaxUninitAnalysisVariablesPerFunction = 13485d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth std::max(MaxUninitAnalysisVariablesPerFunction, 13495d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth stats.NumVariablesAnalyzed); 13505d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth MaxUninitAnalysisBlockVisitsPerFunction = 13515d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth std::max(MaxUninitAnalysisBlockVisitsPerFunction, 13525d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth stats.NumBlockVisits); 13535d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth } 13545d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth } 13555d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth } 13565d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 13571973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko bool FallThroughDiagFull = 13581973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough, 13591973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko D->getLocStart()) != DiagnosticsEngine::Ignored; 1360c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt bool FallThroughDiagPerFunction = 1361c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough_per_function, 13621973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko D->getLocStart()) != DiagnosticsEngine::Ignored; 1363c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt if (FallThroughDiagFull || FallThroughDiagPerFunction) { 13641973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull); 1365e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1366e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 13675d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth // Collect statistics about the CFG if it was built. 13685d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth if (S.CollectStats && AC.isCFGBuilt()) { 13695d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth ++NumFunctionsAnalyzed; 13705d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth if (CFG *cfg = AC.getCFG()) { 13715d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth // If we successfully built a CFG for this context, record some more 13725d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth // detail information about it. 13733ea4c49709c5bba5f8b16c6ceb725d9b9a1c48c6Chandler Carruth NumCFGBlocks += cfg->getNumBlockIDs(); 13745d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction, 13753ea4c49709c5bba5f8b16c6ceb725d9b9a1c48c6Chandler Carruth cfg->getNumBlockIDs()); 13765d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth } else { 13775d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth ++NumFunctionsWithBadCFGs; 1378610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 1379610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 1380dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 13815d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 13825d98994c7749312a43ce6adf45537979a98e7afdChandler Carruthvoid clang::sema::AnalysisBasedWarnings::PrintStats() const { 13835d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth llvm::errs() << "\n*** Analysis Based Warnings Stats:\n"; 13845d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 13855d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs; 13865d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth unsigned AvgCFGBlocksPerFunction = 13875d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt; 13885d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth llvm::errs() << NumFunctionsAnalyzed << " functions analyzed (" 13895d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << NumFunctionsWithBadCFGs << " w/o CFGs).\n" 13905d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << NumCFGBlocks << " CFG blocks built.\n" 13915d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << AvgCFGBlocksPerFunction 13925d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " average CFG blocks per function.\n" 13935d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << MaxCFGBlocksPerFunction 13945d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " max CFG blocks per function.\n"; 13955d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 13965d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0 13975d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth : NumUninitAnalysisVariables/NumUninitAnalysisFunctions; 13985d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0 13995d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions; 14005d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth llvm::errs() << NumUninitAnalysisFunctions 14015d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " functions analyzed for uninitialiazed variables\n" 14025d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << NumUninitAnalysisVariables << " variables analyzed.\n" 14035d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << AvgUninitVariablesPerFunction 14045d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " average variables per function.\n" 14055d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << MaxUninitAnalysisVariablesPerFunction 14065d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " max variables per function.\n" 14075d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << NumUninitAnalysisBlockVisits << " block visits.\n" 14085d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << AvgUninitBlockVisitsPerFunction 14095d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " average block visits per function.\n" 14105d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << MaxUninitAnalysisBlockVisitsPerFunction 14115d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " max block visits per function.\n"; 14125d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth} 1413