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" 17384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h" 1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/DeclObjC.h" 196f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek#include "clang/AST/EvaluatedExprVisitor.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/ExprCXX.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/ExprObjC.h" 22b5cd1220dd650a358622241237aa595c5d675506Jordan Rose#include "clang/AST/ParentMap.h" 23e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith#include "clang/AST/RecursiveASTVisitor.h" 2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/StmtCXX.h" 2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/StmtObjC.h" 2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/StmtVisitor.h" 27351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h" 28df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins#include "clang/Analysis/Analyses/Consumed.h" 2955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Analysis/Analyses/ReachableCode.h" 30402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski#include "clang/Analysis/Analyses/ThreadSafety.h" 316f34213f8d6ae8c77685b53664527e39bfaaca3bTed Kremenek#include "clang/Analysis/Analyses/UninitializedValues.h" 3255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Analysis/AnalysisContext.h" 3355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Analysis/CFG.h" 3455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Analysis/CFGStmtMap.h" 3555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/SourceLocation.h" 3655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/SourceManager.h" 3755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Lexer.h" 3855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Preprocessor.h" 3955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/ScopeInfo.h" 4055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/SemaInternal.h" 4166da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko#include "llvm/ADT/ArrayRef.h" 42dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/ADT/BitVector.h" 433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/FoldingSet.h" 443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/ImmutableMap.h" 453285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella#include "llvm/ADT/MapVector.h" 463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/PostOrderIterator.h" 471952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko#include "llvm/ADT/SmallString.h" 483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include "llvm/ADT/SmallVector.h" 4975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski#include "llvm/ADT/StringRef.h" 50dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek#include "llvm/Support/Casting.h" 513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include <algorithm> 5255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include <deque> 53e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith#include <iterator> 543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski#include <vector> 55dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 56dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekusing namespace clang; 57dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 58dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 59dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Unreachable code analysis. 60dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 61dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 62dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremeneknamespace { 63dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek class UnreachableCodeHandler : public reachable_code::Callback { 64dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek Sema &S; 65dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek public: 66dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek UnreachableCodeHandler(Sema &s) : S(s) {} 67dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void HandleUnreachable(reachable_code::UnreachableKind UK, 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation L, 70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceRange SilenceableCondVal, 71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceRange R1, 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceRange R2) override { 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned diag = diag::warn_unreachable; 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines switch (UK) { 75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case reachable_code::UK_Break: 76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines diag = diag::warn_unreachable_break; 77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case reachable_code::UK_Return: 79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines diag = diag::warn_unreachable_return; 80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case reachable_code::UK_Loop_Increment: 82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines diag = diag::warn_unreachable_loop_increment; 83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case reachable_code::UK_Other: 85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(L, diag) << R1 << R2; 89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation Open = SilenceableCondVal.getBegin(); 91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Open.isValid()) { 926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation Close = SilenceableCondVal.getEnd(); 936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Close = S.getLocForEndOfToken(Close); 94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Close.isValid()) { 95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(Open, diag::note_unreachable_silence) 96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << FixItHint::CreateInsertion(Open, "/* DISABLES CODE */ (") 97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << FixItHint::CreateInsertion(Close, ")"); 98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 100dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 101dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek }; 102dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 103dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 104dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckUnreachable - Check for unreachable code. 1051d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekstatic void CheckUnreachable(Sema &S, AnalysisDeclContext &AC) { 106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // As a heuristic prune all diagnostics not in the main file. Currently 107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // the majority of warnings in headers are false positives. These 108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // are largely caused by configuration state, e.g. preprocessor 109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // defined code, etc. 110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // 111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Note that this is also a performance optimization. Analyzing 112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // headers many times can be expensive. 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!S.getSourceManager().isInMainFile(AC.getDecl()->getLocStart())) 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 116dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek UnreachableCodeHandler UC(S); 117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines reachable_code::FindUnreachableCode(AC, S.getPreprocessor(), UC); 118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \brief Warn on logical operator errors in CFGBuilder 1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass LogicalErrorHandler : public CFGCallback { 1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Sema &S; 1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic: 1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LogicalErrorHandler(Sema &S) : CFGCallback(), S(S) {} 1266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static bool HasMacroID(const Expr *E) { 1286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (E->getExprLoc().isMacroID()) 1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return true; 1306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Recurse to children. 1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (ConstStmtRange SubStmts = E->children(); SubStmts; ++SubStmts) 1336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (*SubStmts) 1346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (const Expr *SubExpr = dyn_cast<Expr>(*SubStmts)) 1356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (HasMacroID(SubExpr)) 1366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return true; 1376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return false; 1396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) { 1426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (HasMacroID(B)) 1436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 1446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceRange DiagRange = B->getSourceRange(); 1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines S.Diag(B->getExprLoc(), diag::warn_tautological_overlap_comparison) 1476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << DiagRange << isAlwaysTrue; 1486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void compareBitwiseEquality(const BinaryOperator *B, bool isAlwaysTrue) { 1516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (HasMacroID(B)) 1526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 1536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceRange DiagRange = B->getSourceRange(); 1556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines S.Diag(B->getExprLoc(), diag::warn_comparison_bitwise_always) 1566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << DiagRange << isAlwaysTrue; 1576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}; 1596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===// 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Check for infinite self-recursion in functions 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===// 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// All blocks are in one of three states. States are ordered so that blocks 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// can only move to higher states. 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesenum RecursiveState { 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FoundNoPath, 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FoundPath, 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FoundPathWithNoRecursiveCall 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void checkForFunctionCall(Sema &S, const FunctionDecl *FD, 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CFGBlock &Block, unsigned ExitID, 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::SmallVectorImpl<RecursiveState> &States, 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RecursiveState State) { 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned ID = Block.getBlockID(); 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // A block's state can only move to a higher state. 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (States[ID] >= State) 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines States[ID] = State; 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Found a path to the exit node without a recursive call. 186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ID == ExitID && State == FoundPathWithNoRecursiveCall) 187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (State == FoundPathWithNoRecursiveCall) { 190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If the current state is FoundPathWithNoRecursiveCall, the successors 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // will be either FoundPathWithNoRecursiveCall or FoundPath. To determine 192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // which, process all the Stmt's in this block to find any recursive calls. 1936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &B : Block) { 1946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (B.getKind() != CFGElement::Statement) 195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const CallExpr *CE = dyn_cast<CallExpr>(B.getAs<CFGStmt>()->getStmt()); 198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CE && CE->getCalleeDecl() && 199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CE->getCalleeDecl()->getCanonicalDecl() == FD) { 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Skip function calls which are qualified with a templated class. 202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>( 203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CE->getCallee()->IgnoreParenImpCasts())) { 204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (NestedNameSpecifier *NNS = DRE->getQualifier()) { 205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (NNS->getKind() == NestedNameSpecifier::TypeSpec && 206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isa<TemplateSpecializationType>(NNS->getAsType())) { 207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE)) { 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (isa<CXXThisExpr>(MCE->getImplicitObjectArgument()) || 214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines !MCE->getMethodDecl()->isVirtual()) { 215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines State = FoundPath; 216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else { 219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines State = FoundPath; 220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 225651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (CFGBlock::succ_iterator I = Block.succ_begin(), E = Block.succ_end(); 227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines I != E; ++I) 228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (*I) 229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines checkForFunctionCall(S, FD, **I, ExitID, States, State); 230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void checkRecursiveFunction(Sema &S, const FunctionDecl *FD, 233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Stmt *Body, 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AnalysisDeclContext &AC) { 235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FD = FD->getCanonicalDecl(); 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Only run on non-templated functions and non-templated members of 238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // templated classes. 239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate && 240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FD->getTemplatedKind() != FunctionDecl::TK_MemberSpecialization) 241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CFG *cfg = AC.getCFG(); 2446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!cfg) return; 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If the exit block is unreachable, skip processing the function. 247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (cfg->getExit().pred_empty()) 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Mark all nodes as FoundNoPath, then begin processing the entry block. 251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::SmallVector<RecursiveState, 16> states(cfg->getNumBlockIDs(), 252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FoundNoPath); 253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines checkForFunctionCall(S, FD, cfg->getEntry(), cfg->getExit().getBlockID(), 254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines states, FoundPathWithNoRecursiveCall); 255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Check that the exit block is reachable. This prevents triggering the 257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // warning on functions that do not terminate. 258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (states[cfg->getExit().getBlockID()] == FoundPath) 259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(Body->getLocStart(), diag::warn_infinite_recursive_function); 260dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 261dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 262dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 263dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// Check for missing return value. 264dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 265dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 26616565aa95b086fb239baf82335dccc1b1ec93942John McCallenum ControlFlowKind { 26716565aa95b086fb239baf82335dccc1b1ec93942John McCall UnknownFallThrough, 26816565aa95b086fb239baf82335dccc1b1ec93942John McCall NeverFallThrough, 26916565aa95b086fb239baf82335dccc1b1ec93942John McCall MaybeFallThrough, 27016565aa95b086fb239baf82335dccc1b1ec93942John McCall AlwaysFallThrough, 27116565aa95b086fb239baf82335dccc1b1ec93942John McCall NeverFallThroughOrReturn 27216565aa95b086fb239baf82335dccc1b1ec93942John McCall}; 273dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 274dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThrough - Check that we don't fall off the end of a 275dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// Statement that should return a value. 276dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// 277f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// \returns AlwaysFallThrough iff we always fall off the end of the statement, 278f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// MaybeFallThrough iff we might or might not fall off the end, 279f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// NeverFallThroughOrReturn iff we never fall off the end of the statement or 280f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// return. We assume NeverFallThrough iff we never fall off the end of the 281dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// statement but we may return. We assume that functions not marked noreturn 282dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// will return. 2831d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekstatic ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) { 284dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CFG *cfg = AC.getCFG(); 2856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!cfg) return UnknownFallThrough; 286dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 287dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // The CFG leaves in dead things, and we don't want the dead code paths to 288dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // confuse us, so we mark all live things first. 289dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek llvm::BitVector live(cfg->getNumBlockIDs()); 2900f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(), 291dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek live); 292dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 293dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool AddEHEdges = AC.getAddEHEdges(); 294dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!AddEHEdges && count != cfg->getNumBlockIDs()) 295dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // When there are things remaining dead, and we didn't add EH edges 296dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // from CallExprs to the catch clauses, we have to go back and 297dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // mark them as live. 2986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto *B : *cfg) { 2996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!live[B->getBlockID()]) { 3006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (B->pred_begin() == B->pred_end()) { 3016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (B->getTerminator() && isa<CXXTryStmt>(B->getTerminator())) 302dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // When not adding EH edges from calls, catch clauses 303dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // can otherwise seem dead. Avoid noting them as dead. 3046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines count += reachable_code::ScanReachableFromBlock(B, live); 305dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 306dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 307dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 308dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 309dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 310dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Now we know what is live, we check the live precessors of the exit block 311dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // and look for fall through paths, being careful to ignore normal returns, 312dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // and exceptional paths. 313dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasLiveReturn = false; 314dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasFakeEdge = false; 315dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasPlainEdge = false; 316dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasAbnormalEdge = false; 31790b828aa279542559f655d1af666580288cb1841Ted Kremenek 31890b828aa279542559f655d1af666580288cb1841Ted Kremenek // Ignore default cases that aren't likely to be reachable because all 31990b828aa279542559f655d1af666580288cb1841Ted Kremenek // enums in a switch(X) have explicit case statements. 32090b828aa279542559f655d1af666580288cb1841Ted Kremenek CFGBlock::FilterOptions FO; 32190b828aa279542559f655d1af666580288cb1841Ted Kremenek FO.IgnoreDefaultsWithCoveredEnums = 1; 32290b828aa279542559f655d1af666580288cb1841Ted Kremenek 32390b828aa279542559f655d1af666580288cb1841Ted Kremenek for (CFGBlock::filtered_pred_iterator 32490b828aa279542559f655d1af666580288cb1841Ted Kremenek I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) { 32590b828aa279542559f655d1af666580288cb1841Ted Kremenek const CFGBlock& B = **I; 326dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!live[B.getBlockID()]) 327dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 3285811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek 329e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth // Skip blocks which contain an element marked as no-return. They don't 330e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth // represent actually viable edges into the exit block, so mark them as 331e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth // abnormal. 332e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth if (B.hasNoReturnElement()) { 333e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth HasAbnormalEdge = true; 334e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth continue; 335e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth } 336e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth 3375811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // Destructors can appear after the 'return' in the CFG. This is 3385811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // normal. We need to look pass the destructors for the return 3395811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // statement (if it exists). 3405811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend(); 341e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth 342e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth for ( ; ri != re ; ++ri) 343fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie if (ri->getAs<CFGStmt>()) 3445811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek break; 345e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth 3465811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek // No more CFGElements in the block? 3475811f5978feaa7b89bd89e174fa7ad077b48413eTed Kremenek if (ri == re) { 348dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) { 349dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 350dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 351dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 352dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // A labeled empty statement, or the entry block... 353dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasPlainEdge = true; 354dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 355dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 356f39e6a388aaa2f155b46c61e655784b2473218ebTed Kremenek 357fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie CFGStmt CS = ri->castAs<CFGStmt>(); 358f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek const Stmt *S = CS.getStmt(); 359dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<ReturnStmt>(S)) { 360dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasLiveReturn = true; 361dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 362dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 363dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<ObjCAtThrowStmt>(S)) { 364dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 365dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 366dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 367dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<CXXThrowExpr>(S)) { 368dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasFakeEdge = true; 369dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 370dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 3718cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier if (isa<MSAsmStmt>(S)) { 3728cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier // TODO: Verify this is correct. 3738cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier HasFakeEdge = true; 3748cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier HasLiveReturn = true; 3758cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier continue; 3768cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier } 377dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (isa<CXXTryStmt>(S)) { 378dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasAbnormalEdge = true; 379dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek continue; 380dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 381e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit()) 382e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth == B.succ_end()) { 383e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth HasAbnormalEdge = true; 384e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth continue; 385dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 386e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth 387e05ee6df356c25e792b0334d7a4dec3fe4f79f07Chandler Carruth HasPlainEdge = true; 388dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 389dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (!HasPlainEdge) { 390dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasLiveReturn) 391dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return NeverFallThrough; 392dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return NeverFallThroughOrReturn; 393dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 394dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn) 395dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return MaybeFallThrough; 396dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // This says AlwaysFallThrough for calls to functions that are not marked 397dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // noreturn, that don't return. If people would like this warning to be more 398dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // accurate, such functions should be marked as noreturn. 399dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return AlwaysFallThrough; 400dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 401dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 4023c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohmannamespace { 4033c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 404dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstruct CheckFallThroughDiagnostics { 405dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_MaybeFallThrough_HasNoReturn; 406dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_MaybeFallThrough_ReturnsNonVoid; 407dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_AlwaysFallThrough_HasNoReturn; 408dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_AlwaysFallThrough_ReturnsNonVoid; 409dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek unsigned diag_NeverFallThroughOrReturn; 410793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor enum { Function, Block, Lambda } funMode; 4110827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis SourceLocation FuncLoc; 412d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 413ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { 414dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughDiagnostics D; 4150827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis D.FuncLoc = Func->getLocation(); 416dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_HasNoReturn = 417dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_noreturn_function; 418dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_ReturnsNonVoid = 419dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_maybe_falloff_nonvoid_function; 420dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_HasNoReturn = 421dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_noreturn_function; 422dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_ReturnsNonVoid = 423dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::warn_falloff_nonvoid_function; 424ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 425ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor // Don't suggest that virtual functions be marked "noreturn", since they 426ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor // might be overridden by non-noreturn functions. 427ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor bool isVirtualMethod = false; 428ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func)) 429ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor isVirtualMethod = Method->isVirtual(); 430ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 431fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor // Don't suggest that template instantiations be marked "noreturn" 432fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor bool isTemplateInstantiation = false; 43375df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func)) 43475df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek isTemplateInstantiation = Function->isTemplateInstantiation(); 435fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor 436fcdd2cb2fdf35f806dd800b369fe0772a1c8c26cDouglas Gregor if (!isVirtualMethod && !isTemplateInstantiation) 437ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor D.diag_NeverFallThroughOrReturn = 438ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor diag::warn_suggest_noreturn_function; 439ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor else 440ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor D.diag_NeverFallThroughOrReturn = 0; 441ca7eaeeed817001dc7cee4852a7e41f0982da1efDouglas Gregor 442793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.funMode = Function; 443dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return D; 444dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 445d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 446dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek static CheckFallThroughDiagnostics MakeForBlock() { 447dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CheckFallThroughDiagnostics D; 448dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_HasNoReturn = 449dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_noreturn_block_has_return_expr; 450dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_MaybeFallThrough_ReturnsNonVoid = 451dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_maybe_falloff_nonvoid_block; 452dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_HasNoReturn = 453dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_noreturn_block_has_return_expr; 454dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek D.diag_AlwaysFallThrough_ReturnsNonVoid = 455dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek diag::err_falloff_nonvoid_block; 4566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines D.diag_NeverFallThroughOrReturn = 0; 457793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.funMode = Block; 458793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor return D; 459793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor } 460793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor 461793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor static CheckFallThroughDiagnostics MakeForLambda() { 462793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor CheckFallThroughDiagnostics D; 463793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.diag_MaybeFallThrough_HasNoReturn = 464793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor diag::err_noreturn_lambda_has_return_expr; 465793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.diag_MaybeFallThrough_ReturnsNonVoid = 466793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor diag::warn_maybe_falloff_nonvoid_lambda; 467793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.diag_AlwaysFallThrough_HasNoReturn = 468793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor diag::err_noreturn_lambda_has_return_expr; 469793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.diag_AlwaysFallThrough_ReturnsNonVoid = 470793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor diag::warn_falloff_nonvoid_lambda; 471793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.diag_NeverFallThroughOrReturn = 0; 472793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor D.funMode = Lambda; 473dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return D; 474dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 475d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 476d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid, 477dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasNoReturn) const { 478793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor if (funMode == Function) { 4790827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis return (ReturnsVoid || 480ef8225444452a1486bd721f3285301fe84643b00Stephen Hines D.isIgnored(diag::warn_maybe_falloff_nonvoid_function, 481ef8225444452a1486bd721f3285301fe84643b00Stephen Hines FuncLoc)) && 482ef8225444452a1486bd721f3285301fe84643b00Stephen Hines (!HasNoReturn || 483ef8225444452a1486bd721f3285301fe84643b00Stephen Hines D.isIgnored(diag::warn_noreturn_function_has_return_expr, 484ef8225444452a1486bd721f3285301fe84643b00Stephen Hines FuncLoc)) && 485ef8225444452a1486bd721f3285301fe84643b00Stephen Hines (!ReturnsVoid || 486ef8225444452a1486bd721f3285301fe84643b00Stephen Hines D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc)); 487dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 488d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 489793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor // For blocks / lambdas. 4906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return ReturnsVoid && !HasNoReturn; 491dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 492dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek}; 493dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 4943c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman} 4953c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 496dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a 497dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// function that should return a value. Check that we don't fall off the end 498dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// of a noreturn function. We assume that functions and blocks not marked 499dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek/// noreturn will return. 500dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenekstatic void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, 5013ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek const BlockExpr *blkExpr, 502dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const CheckFallThroughDiagnostics& CD, 5031d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContext &AC) { 504dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 505dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool ReturnsVoid = false; 506dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek bool HasNoReturn = false; 507dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 508dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 509651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ReturnsVoid = FD->getReturnType()->isVoidType(); 510cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith HasNoReturn = FD->isNoReturn(); 511dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 512dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 513651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ReturnsVoid = MD->getReturnType()->isVoidType(); 514dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = MD->hasAttr<NoReturnAttr>(); 515dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 516dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (isa<BlockDecl>(D)) { 5173ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek QualType BlockTy = blkExpr->getType(); 518d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek if (const FunctionType *FT = 519dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek BlockTy->getPointeeType()->getAs<FunctionType>()) { 520651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FT->getReturnType()->isVoidType()) 521dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek ReturnsVoid = true; 522dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (FT->getNoReturnAttr()) 523dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek HasNoReturn = true; 524dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 525dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 526dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 527d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &Diags = S.getDiagnostics(); 528dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 529dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Short circuit for compilation speed. 530dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn)) 531dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek return; 532d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 533dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // FIXME: Function try block 534dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { 535dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek switch (CheckFallThrough(AC)) { 53616565aa95b086fb239baf82335dccc1b1ec93942John McCall case UnknownFallThrough: 53716565aa95b086fb239baf82335dccc1b1ec93942John McCall break; 53816565aa95b086fb239baf82335dccc1b1ec93942John McCall 539dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case MaybeFallThrough: 540dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasNoReturn) 541dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 542dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_MaybeFallThrough_HasNoReturn); 543dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (!ReturnsVoid) 544dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 545dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_MaybeFallThrough_ReturnsNonVoid); 546dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 547dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case AlwaysFallThrough: 548dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek if (HasNoReturn) 549dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 550dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_AlwaysFallThrough_HasNoReturn); 551dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek else if (!ReturnsVoid) 552dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek S.Diag(Compound->getRBracLoc(), 553dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek CD.diag_AlwaysFallThrough_ReturnsNonVoid); 554dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 555dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case NeverFallThroughOrReturn: 556b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) { 557b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 558b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn) 559b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor << 0 << FD; 560b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 561b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn) 562b3321093f6ead084427eb4a6621832fc4ee2f5deDouglas Gregor << 1 << MD; 563b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth } else { 564b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn); 565b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth } 566b0656ec72e25e5c8e463c2dc39914636f0cb06d1Chandler Carruth } 567dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 568dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek case NeverFallThrough: 569dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek break; 570dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 571dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 572dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 573dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 574dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 575610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// -Wuninitialized 576610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 577610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 5786f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremeneknamespace { 5799f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// ContainsReference - A visitor class to search for references to 5809f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// a particular declaration (the needle) within any evaluated component of an 5819f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth/// expression (recursively). 5826f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenekclass ContainsReference : public EvaluatedExprVisitor<ContainsReference> { 5839f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth bool FoundReference; 5849f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth const DeclRefExpr *Needle; 5859f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth 5866f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenekpublic: 5879f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth ContainsReference(ASTContext &Context, const DeclRefExpr *Needle) 5889f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth : EvaluatedExprVisitor<ContainsReference>(Context), 5899f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth FoundReference(false), Needle(Needle) {} 5909f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth 5919f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth void VisitExpr(Expr *E) { 5926f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek // Stop evaluating if we already have a reference. 5939f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth if (FoundReference) 5946f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek return; 5959f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth 5969f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth EvaluatedExprVisitor<ContainsReference>::VisitExpr(E); 5976f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek } 5989f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth 5999f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth void VisitDeclRefExpr(DeclRefExpr *E) { 6009f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth if (E == Needle) 6019f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth FoundReference = true; 6029f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth else 6039f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth EvaluatedExprVisitor<ContainsReference>::VisitDeclRefExpr(E); 6046f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek } 6059f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth 6069f6494687c05fe1d334af76408ee056b5f80e027Chandler Carruth bool doesContainReference() const { return FoundReference; } 6076f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek}; 6086f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek} 6096f41715df2c6a31c0c3ab3088b8cd18a3c8321b8Ted Kremenek 6104f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikiestatic bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) { 611a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian QualType VariableTy = VD->getType().getCanonicalType(); 612a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian if (VariableTy->isBlockPointerType() && 613a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian !VD->hasAttr<BlocksAttr>()) { 614ef8225444452a1486bd721f3285301fe84643b00Stephen Hines S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization) 615ef8225444452a1486bd721f3285301fe84643b00Stephen Hines << VD->getDeclName() 616ef8225444452a1486bd721f3285301fe84643b00Stephen Hines << FixItHint::CreateInsertion(VD->getLocation(), "__block "); 617a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian return true; 618a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian } 6198adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith 6204f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie // Don't issue a fixit if there is already an initializer. 6214f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie if (VD->getInit()) 6224f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie return false; 6237b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu 6247b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu // Don't suggest a fixit inside macros. 6257b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu if (VD->getLocEnd().isMacroID()) 6267b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu return false; 6277b0a3e378c441cec60f929d13bd48846c267a008Richard Trieu 6286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation Loc = S.getLocForEndOfToken(VD->getLocEnd()); 6298adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith 6308adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith // Suggest possible initialization (if any). 6318adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith std::string Init = S.getFixItZeroInitializerForType(VariableTy, Loc); 6328adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith if (Init.empty()) 6338adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith return false; 6348adf837adc65b55a3f74643c02c1ee077dc26f06Richard Smith 6357984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName() 6367984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith << FixItHint::CreateInsertion(Loc, Init); 6377984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith return true; 6384f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie} 6394f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie 640bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// Create a fixit to remove an if-like statement, on the assumption that its 641bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// condition is CondVal. 642bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smithstatic void CreateIfFixit(Sema &S, const Stmt *If, const Stmt *Then, 643bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith const Stmt *Else, bool CondVal, 644bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith FixItHint &Fixit1, FixItHint &Fixit2) { 645bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (CondVal) { 646bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // If condition is always true, remove all but the 'then'. 647bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateRemoval( 648bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith CharSourceRange::getCharRange(If->getLocStart(), 649bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Then->getLocStart())); 650bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (Else) { 651bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith SourceLocation ElseKwLoc = Lexer::getLocForEndOfToken( 652bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Then->getLocEnd(), 0, S.getSourceManager(), S.getLangOpts()); 653bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit2 = FixItHint::CreateRemoval( 654bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith SourceRange(ElseKwLoc, Else->getLocEnd())); 655bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith } 656bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith } else { 657bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // If condition is always false, remove all but the 'else'. 658bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (Else) 659bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateRemoval( 660bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith CharSourceRange::getCharRange(If->getLocStart(), 661bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Else->getLocStart())); 662bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith else 663bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateRemoval(If->getSourceRange()); 664bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith } 665bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith} 666bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 667bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// DiagUninitUse -- Helper function to produce a diagnostic for an 668bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith/// uninitialized use of a variable. 669bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smithstatic void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use, 670bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith bool IsCapturedByBlock) { 671bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith bool Diagnosed = false; 672bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 6738a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith switch (Use.getKind()) { 6748a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith case UninitUse::Always: 6758a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith S.Diag(Use.getUser()->getLocStart(), diag::warn_uninit_var) 6768a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith << VD->getDeclName() << IsCapturedByBlock 6778a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith << Use.getUser()->getSourceRange(); 6788a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith return; 6798a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith 6808a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith case UninitUse::AfterDecl: 6818a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith case UninitUse::AfterCall: 6828a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith S.Diag(VD->getLocation(), diag::warn_sometimes_uninit_var) 6838a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith << VD->getDeclName() << IsCapturedByBlock 6848a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith << (Use.getKind() == UninitUse::AfterDecl ? 4 : 5) 6858a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith << const_cast<DeclContext*>(VD->getLexicalDeclContext()) 6868a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith << VD->getSourceRange(); 6878a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith S.Diag(Use.getUser()->getLocStart(), diag::note_uninit_var_use) 6888a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith << IsCapturedByBlock << Use.getUser()->getSourceRange(); 6898a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith return; 6908a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith 6918a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith case UninitUse::Maybe: 6928a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith case UninitUse::Sometimes: 6938a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith // Carry on to report sometimes-uninitialized branches, if possible, 6948a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith // or a 'may be used uninitialized' diagnostic otherwise. 6958a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith break; 6968a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith } 6978a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith 698bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // Diagnose each branch which leads to a sometimes-uninitialized use. 6992815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith for (UninitUse::branch_iterator I = Use.branch_begin(), E = Use.branch_end(); 7002815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith I != E; ++I) { 701bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith assert(Use.getKind() == UninitUse::Sometimes); 702bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 703bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith const Expr *User = Use.getUser(); 7042815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const Stmt *Term = I->Terminator; 705bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 706bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // Information used when building the diagnostic. 7072815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith unsigned DiagKind; 7080bea86307eb8c16339315a1e261fc490eb505c5bDavid Blaikie StringRef Str; 709bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith SourceRange Range; 710bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 711fc09336a5965040736f9bc63a70416003972364eStefanus Du Toit // FixIts to suppress the diagnostic by removing the dead condition. 712bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // For all binary terminators, branch 0 is taken if the condition is true, 713bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // and branch 1 is taken if the condition is false. 714bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith int RemoveDiagKind = -1; 715bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith const char *FixitStr = 716bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith S.getLangOpts().CPlusPlus ? (I->Output ? "true" : "false") 717bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith : (I->Output ? "1" : "0"); 718bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith FixItHint Fixit1, Fixit2; 719bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 7208a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith switch (Term ? Term->getStmtClass() : Stmt::DeclStmtClass) { 7212815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith default: 722bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // Don't know how to report this. Just fall back to 'may be used 7238a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith // uninitialized'. FIXME: Can this happen? 7242815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith continue; 7252815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 7262815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith // "condition is true / condition is false". 727bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith case Stmt::IfStmtClass: { 728bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith const IfStmt *IS = cast<IfStmt>(Term); 7292815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 0; 7302815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "if"; 731bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Range = IS->getCond()->getSourceRange(); 732bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 0; 733bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith CreateIfFixit(S, IS, IS->getThen(), IS->getElse(), 734bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith I->Output, Fixit1, Fixit2); 7352815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 736bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith } 737bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith case Stmt::ConditionalOperatorClass: { 738bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith const ConditionalOperator *CO = cast<ConditionalOperator>(Term); 7392815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 0; 7402815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "?:"; 741bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Range = CO->getCond()->getSourceRange(); 742bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 0; 743bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(), 744bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith I->Output, Fixit1, Fixit2); 7452815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 746bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith } 7472815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::BinaryOperatorClass: { 7482815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const BinaryOperator *BO = cast<BinaryOperator>(Term); 7492815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith if (!BO->isLogicalOp()) 7502815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith continue; 7512815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 0; 7522815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = BO->getOpcodeStr(); 7532815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = BO->getLHS()->getSourceRange(); 754bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 0; 755bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if ((BO->getOpcode() == BO_LAnd && I->Output) || 756bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith (BO->getOpcode() == BO_LOr && !I->Output)) 757bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // true && y -> y, false || y -> y. 758bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateRemoval(SourceRange(BO->getLocStart(), 759bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith BO->getOperatorLoc())); 760bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith else 761bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith // false && y -> false, true || y -> true. 762bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateReplacement(BO->getSourceRange(), FixitStr); 7632815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 7642815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith } 7652815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 7662815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith // "loop is entered / loop is exited". 7672815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::WhileStmtClass: 7682815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 1; 7692815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "while"; 7702815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = cast<WhileStmt>(Term)->getCond()->getSourceRange(); 771bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 1; 772bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateReplacement(Range, FixitStr); 7732815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 7742815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::ForStmtClass: 7752815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 1; 7762815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "for"; 7772815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = cast<ForStmt>(Term)->getCond()->getSourceRange(); 778bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 1; 779bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (I->Output) 780bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateRemoval(Range); 781bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith else 782bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateReplacement(Range, FixitStr); 7832815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 7848a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith case Stmt::CXXForRangeStmtClass: 7858a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith if (I->Output == 1) { 7868a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith // The use occurs if a range-based for loop's body never executes. 7878a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith // That may be impossible, and there's no syntactic fix for this, 7888a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith // so treat it as a 'may be uninitialized' case. 7898a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith continue; 7908a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith } 7918a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith DiagKind = 1; 7928a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith Str = "for"; 7938a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith Range = cast<CXXForRangeStmt>(Term)->getRangeInit()->getSourceRange(); 7948a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith break; 7952815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 7962815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith // "condition is true / loop is exited". 7972815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::DoStmtClass: 7982815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 2; 7992815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "do"; 8002815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = cast<DoStmt>(Term)->getCond()->getSourceRange(); 801bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith RemoveDiagKind = 1; 802bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Fixit1 = FixItHint::CreateReplacement(Range, FixitStr); 8032815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 8042815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 8052815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith // "switch case is taken". 8062815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::CaseStmtClass: 8072815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 3; 8082815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "case"; 8092815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = cast<CaseStmt>(Term)->getLHS()->getSourceRange(); 8102815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 8112815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith case Stmt::DefaultStmtClass: 8122815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagKind = 3; 8132815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Str = "default"; 8142815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith Range = cast<DefaultStmt>(Term)->getDefaultLoc(); 8152815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith break; 8162815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith } 8172815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 818bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith S.Diag(Range.getBegin(), diag::warn_sometimes_uninit_var) 819bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << VD->getDeclName() << IsCapturedByBlock << DiagKind 820bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << Str << I->Output << Range; 821bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith S.Diag(User->getLocStart(), diag::note_uninit_var_use) 822bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << IsCapturedByBlock << User->getSourceRange(); 823bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (RemoveDiagKind != -1) 824bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith S.Diag(Fixit1.RemoveRange.getBegin(), diag::note_uninit_fixit_remove_cond) 825bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2; 826bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 827bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith Diagnosed = true; 8282815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith } 829bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith 830bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (!Diagnosed) 8318a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9bRichard Smith S.Diag(Use.getUser()->getLocStart(), diag::warn_maybe_uninit_var) 832bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << VD->getDeclName() << IsCapturedByBlock 833bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith << Use.getUser()->getSourceRange(); 8342815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith} 8352815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 836262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an 837262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// uninitialized variable. This manages the different forms of diagnostic 838262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// emitted for particular types of uses. Returns true if the use was diagnosed 8392815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith/// as a warning. If a particular use is one we omit warnings for, returns 840262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth/// false. 841262d50e1dcf529317da193ad585c11c16281a7acChandler Carruthstatic bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD, 8422815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const UninitUse &Use, 8439e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek bool alwaysReportSelfInit = false) { 8444c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth 8452815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Use.getUser())) { 846f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // Inspect the initializer of the variable declaration which is 847f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // being referenced prior to its initialization. We emit 848f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // specialized diagnostics for self-initialization, and we 849f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // specifically avoid warning about self references which take the 850f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // form of: 851f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // 852f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // int x = x; 853f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // 854f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // This is used to indicate to GCC that 'x' is intentionally left 855f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // uninitialized. Proven code paths which access 'x' in 856f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu // an uninitialized state after this will still warn. 857f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu if (const Expr *Initializer = VD->getInit()) { 858f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu if (!alwaysReportSelfInit && DRE == Initializer->IgnoreParenImpCasts()) 859f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu return false; 860f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu 861f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu ContainsReference CR(S.Context, DRE); 862f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu CR.Visit(const_cast<Expr*>(Initializer)); 863f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu if (CR.doesContainReference()) { 8644c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth S.Diag(DRE->getLocStart(), 8654c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth diag::warn_uninit_self_reference_in_init) 866f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu << VD->getDeclName() << VD->getLocation() << DRE->getSourceRange(); 867f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu return true; 8684c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth } 8694c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth } 870f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu 871bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith DiagUninitUse(S, VD, Use, false); 8724c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth } else { 8732815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith const BlockExpr *BE = cast<BlockExpr>(Use.getUser()); 874bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith if (VD->getType()->isBlockPointerType() && !VD->hasAttr<BlocksAttr>()) 875bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith S.Diag(BE->getLocStart(), 876bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith diag::warn_uninit_byref_blockvar_captured_by_block) 877a34194f035096dd8dce10574e3a186da968aa211Fariborz Jahanian << VD->getDeclName(); 878bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith else 879bdb97ff687ce85e45cc728b87612ed546f48c1e7Richard Smith DiagUninitUse(S, VD, Use, true); 8804c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth } 8814c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth 8824c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth // Report where the variable was declared when the use wasn't within 8834f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie // the initializer of that declaration & we didn't already suggest 8844f4f349208b2b2307454e169ac7b039e989f003fDavid Blaikie // an initialization fixit. 885f6278e545d9bc09fb5d7579d1123f0a455352627Richard Trieu if (!SuggestInitializationFixit(S, VD)) 8864c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth S.Diag(VD->getLocStart(), diag::note_uninit_var_def) 8874c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth << VD->getDeclName(); 8884c4983bbd2904670a25c840b07600f14efbafd7fChandler Carruth 889262d50e1dcf529317da193ad585c11c16281a7acChandler Carruth return true; 89064fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth} 89164fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth 892e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smithnamespace { 893e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> { 894e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith public: 895e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FallthroughMapper(Sema &S) 896e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith : FoundSwitchStatements(false), 897e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith S(S) { 898e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 899e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 900e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool foundSwitchStatements() const { return FoundSwitchStatements; } 901e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 902e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith void markFallthroughVisited(const AttributedStmt *Stmt) { 903e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool Found = FallthroughStmts.erase(Stmt); 904e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith assert(Found); 9053bb2994a7de3679fb825f3a36f3dc11ea1daf6a6Kaelyn Uhrain (void)Found; 906e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 907e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 908e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts; 909e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 910e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const AttrStmts &getFallthroughStmts() const { 911e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return FallthroughStmts; 912e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 913e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 9144874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko void fillReachableBlocks(CFG *Cfg) { 9154874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko assert(ReachableBlocks.empty() && "ReachableBlocks already filled"); 9164874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko std::deque<const CFGBlock *> BlockQueue; 9174874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko 9184874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko ReachableBlocks.insert(&Cfg->getEntry()); 9194874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko BlockQueue.push_back(&Cfg->getEntry()); 920878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko // Mark all case blocks reachable to avoid problems with switching on 921878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko // constants, covered enums, etc. 922878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko // These blocks can contain fall-through annotations, and we don't want to 923878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko // issue a warn_fallthrough_attr_unreachable for them. 9246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto *B : *Cfg) { 925878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko const Stmt *L = B->getLabel(); 926878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko if (L && isa<SwitchCase>(L) && ReachableBlocks.insert(B)) 927878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko BlockQueue.push_back(B); 928878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko } 929878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko 9304874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko while (!BlockQueue.empty()) { 9314874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko const CFGBlock *P = BlockQueue.front(); 9324874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko BlockQueue.pop_front(); 9334874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko for (CFGBlock::const_succ_iterator I = P->succ_begin(), 9344874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko E = P->succ_end(); 9354874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko I != E; ++I) { 9360162b832fd6450cd3a23019a3c900382d0e9415cAlexander Kornienko if (*I && ReachableBlocks.insert(*I)) 9374874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko BlockQueue.push_back(*I); 9384874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko } 9394874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko } 9404874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko } 9414874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko 942e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) { 9434874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko assert(!ReachableBlocks.empty() && "ReachableBlocks empty"); 9444874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko 945e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith int UnannotatedCnt = 0; 946e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith AnnotatedCnt = 0; 947e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 9486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines std::deque<const CFGBlock*> BlockQueue(B.pred_begin(), B.pred_end()); 949e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith while (!BlockQueue.empty()) { 950e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const CFGBlock *P = BlockQueue.front(); 951e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith BlockQueue.pop_front(); 952651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!P) continue; 953e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 954e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const Stmt *Term = P->getTerminator(); 955e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (Term && isa<SwitchStmt>(Term)) 956e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; // Switch statement, good. 957e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 958e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel()); 959e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end()) 960e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; // Previous case label has no statements, good. 961e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 962c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel()); 963c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end()) 964c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko continue; // Case label is preceded with a normal label, good. 965c6dcea93b499b504da22f9921fc198423ad0b13bAlexander Kornienko 9664874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko if (!ReachableBlocks.count(P)) { 967878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko for (CFGBlock::const_reverse_iterator ElemIt = P->rbegin(), 968878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko ElemEnd = P->rend(); 969878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko ElemIt != ElemEnd; ++ElemIt) { 970b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (Optional<CFGStmt> CS = ElemIt->getAs<CFGStmt>()) { 971b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) { 972e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith S.Diag(AS->getLocStart(), 973e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith diag::warn_fallthrough_attr_unreachable); 974e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith markFallthroughVisited(AS); 975e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ++AnnotatedCnt; 976878d0ad2c9d83ee6485fd16e21c5082acc63a890Alexander Kornienko break; 977e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 978e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // Don't care about other unreachable statements. 979e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 980e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 981e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // If there are no unreachable statements, this may be a special 982e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // case in CFG: 983e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // case X: { 984e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // A a; // A has a destructor. 985e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // break; 986e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // } 987e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // // <<<< This place is represented by a 'hanging' CFG block. 988e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // case Y: 989e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; 990e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 991e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 992e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith const Stmt *LastStmt = getLastStmt(*P); 993e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) { 994e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith markFallthroughVisited(AS); 995e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ++AnnotatedCnt; 996e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; // Fallthrough annotation, good. 997e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 998e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 999e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!LastStmt) { // This block contains no executable statements. 1000e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // Traverse its predecessors. 1001e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith std::copy(P->pred_begin(), P->pred_end(), 1002e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith std::back_inserter(BlockQueue)); 1003e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; 1004e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1005e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1006e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ++UnannotatedCnt; 1007e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1008e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return !!UnannotatedCnt; 1009e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1010e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1011e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // RecursiveASTVisitor setup. 1012e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool shouldWalkTypesOfTypeLocs() const { return false; } 1013e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1014e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool VisitAttributedStmt(AttributedStmt *S) { 1015e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (asFallThroughAttr(S)) 1016e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FallthroughStmts.insert(S); 1017e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return true; 1018e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1019e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1020e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool VisitSwitchStmt(SwitchStmt *S) { 1021e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FoundSwitchStatements = true; 1022e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return true; 1023e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1024e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1025b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko // We don't want to traverse local type declarations. We analyze their 1026b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko // methods separately. 1027b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko bool TraverseDecl(Decl *D) { return true; } 1028b0707c9a933b1839fa966e4c72e4dcb9a198f11fAlexander Kornienko 1029ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // We analyze lambda bodies separately. Skip them here. 1030ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool TraverseLambdaBody(LambdaExpr *LE) { return true; } 1031ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 1032e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith private: 1033e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1034e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith static const AttributedStmt *asFallThroughAttr(const Stmt *S) { 1035e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) { 1036e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs())) 1037e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return AS; 1038e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 10396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 1040e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1041e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1042e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith static const Stmt *getLastStmt(const CFGBlock &B) { 1043e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (const Stmt *Term = B.getTerminator()) 1044e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return Term; 1045e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith for (CFGBlock::const_reverse_iterator ElemIt = B.rbegin(), 1046e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ElemEnd = B.rend(); 1047e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ElemIt != ElemEnd; ++ElemIt) { 1048b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (Optional<CFGStmt> CS = ElemIt->getAs<CFGStmt>()) 1049b07805485c603be3d8011f72611465324c9e664bDavid Blaikie return CS->getStmt(); 1050e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1051e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // Workaround to detect a statement thrown out by CFGBuilder: 1052e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // case X: {} case Y: 1053e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // case X: ; case Y: 1054e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel())) 1055e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!isa<SwitchCase>(SW->getSubStmt())) 1056e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return SW->getSubStmt(); 1057e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 10586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 1059e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1060e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1061e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith bool FoundSwitchStatements; 1062e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith AttrStmts FallthroughStmts; 1063e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith Sema &S; 10644874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks; 1065e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith }; 1066e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith} 1067e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 10681973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienkostatic void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC, 1069c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt bool PerFunction) { 10703078353fb56772193b9304510048ac075a2c95b5Ted Kremenek // Only perform this analysis when using C++11. There is no good workflow 10713078353fb56772193b9304510048ac075a2c95b5Ted Kremenek // for this warning when not using C++11. There is no good way to silence 10723078353fb56772193b9304510048ac075a2c95b5Ted Kremenek // the warning (no attribute is available) unless we are using C++11's support 10733078353fb56772193b9304510048ac075a2c95b5Ted Kremenek // for generalized attributes. Once could use pragmas to silence the warning, 10743078353fb56772193b9304510048ac075a2c95b5Ted Kremenek // but as a general solution that is gross and not in the spirit of this 10753078353fb56772193b9304510048ac075a2c95b5Ted Kremenek // warning. 10763078353fb56772193b9304510048ac075a2c95b5Ted Kremenek // 10773078353fb56772193b9304510048ac075a2c95b5Ted Kremenek // NOTE: This an intermediate solution. There are on-going discussions on 10783078353fb56772193b9304510048ac075a2c95b5Ted Kremenek // how to properly support this warning outside of C++11 with an annotation. 107980ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (!AC.getASTContext().getLangOpts().CPlusPlus11) 10803078353fb56772193b9304510048ac075a2c95b5Ted Kremenek return; 10813078353fb56772193b9304510048ac075a2c95b5Ted Kremenek 1082e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FallthroughMapper FM(S); 1083e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FM.TraverseStmt(AC.getBody()); 1084e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1085e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!FM.foundSwitchStatements()) 1086e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return; 1087e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1088c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt if (PerFunction && FM.getFallthroughStmts().empty()) 10891973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko return; 10901973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko 1091e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith CFG *Cfg = AC.getCFG(); 1092e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1093e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!Cfg) 1094e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith return; 1095e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 10964874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko FM.fillReachableBlocks(Cfg); 1097e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1098e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith for (CFG::reverse_iterator I = Cfg->rbegin(), E = Cfg->rend(); I != E; ++I) { 1099e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko const CFGBlock *B = *I; 1100e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko const Stmt *Label = B->getLabel(); 1101e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1102e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!Label || !isa<SwitchCase>(Label)) 1103e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; 1104e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 11054874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko int AnnotatedCnt; 11064874a8143dc3032205f97527ff619730db3d1f57Alexander Kornienko 1107e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt)) 1108e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; 1109e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 11101973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko S.Diag(Label->getLocStart(), 1111c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt PerFunction ? diag::warn_unannotated_fallthrough_per_function 1112c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt : diag::warn_unannotated_fallthrough); 1113e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1114e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (!AnnotatedCnt) { 1115e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith SourceLocation L = Label->getLocStart(); 1116e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (L.isMacroID()) 1117e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith continue; 111880ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (S.getLangOpts().CPlusPlus11) { 1119e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko const Stmt *Term = B->getTerminator(); 1120e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko // Skip empty cases. 1121e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko while (B->empty() && !Term && B->succ_size() == 1) { 1122e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko B = *B->succ_begin(); 1123e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko Term = B->getTerminator(); 1124e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko } 1125e992ed1a065d857947b3969e6b779c41cc35c234Alexander Kornienko if (!(B->empty() && Term && isa<BreakStmt>(Term))) { 112666da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko Preprocessor &PP = S.getPreprocessor(); 112766da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko TokenValue Tokens[] = { 112866da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"), 112966da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko tok::coloncolon, PP.getIdentifierInfo("fallthrough"), 113066da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko tok::r_square, tok::r_square 113166da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko }; 11321952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko StringRef AnnotationSpelling = "[[clang::fallthrough]]"; 11331952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko StringRef MacroName = PP.getLastMacroWithSpelling(L, Tokens); 11341952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko if (!MacroName.empty()) 11351952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko AnnotationSpelling = MacroName; 11361952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko SmallString<64> TextToInsert(AnnotationSpelling); 11371952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko TextToInsert += "; "; 1138a189d8976f1193b788508a1a29b2e9d0aca06acaAlexander Kornienko S.Diag(L, diag::note_insert_fallthrough_fixit) << 113966da0abf7ab7cd449bb1d5134b2ef97d9d34d812Alexander Kornienko AnnotationSpelling << 11401952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko FixItHint::CreateInsertion(L, TextToInsert); 1141a189d8976f1193b788508a1a29b2e9d0aca06acaAlexander Kornienko } 1142e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1143e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith S.Diag(L, diag::note_insert_break_fixit) << 1144e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith FixItHint::CreateInsertion(L, "break; "); 1145e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1146e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1147e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 11486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto *F : FM.getFallthroughStmts()) 11496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines S.Diag(F->getLocStart(), diag::warn_fallthrough_attr_invalid_placement); 1150e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith} 1151e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 1152c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rosestatic bool isInLoop(const ASTContext &Ctx, const ParentMap &PM, 1153c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose const Stmt *S) { 1154b5cd1220dd650a358622241237aa595c5d675506Jordan Rose assert(S); 1155b5cd1220dd650a358622241237aa595c5d675506Jordan Rose 1156b5cd1220dd650a358622241237aa595c5d675506Jordan Rose do { 1157b5cd1220dd650a358622241237aa595c5d675506Jordan Rose switch (S->getStmtClass()) { 1158b5cd1220dd650a358622241237aa595c5d675506Jordan Rose case Stmt::ForStmtClass: 1159b5cd1220dd650a358622241237aa595c5d675506Jordan Rose case Stmt::WhileStmtClass: 1160b5cd1220dd650a358622241237aa595c5d675506Jordan Rose case Stmt::CXXForRangeStmtClass: 1161b5cd1220dd650a358622241237aa595c5d675506Jordan Rose case Stmt::ObjCForCollectionStmtClass: 1162b5cd1220dd650a358622241237aa595c5d675506Jordan Rose return true; 1163c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose case Stmt::DoStmtClass: { 1164c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose const Expr *Cond = cast<DoStmt>(S)->getCond(); 1165c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose llvm::APSInt Val; 1166c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose if (!Cond->EvaluateAsInt(Val, Ctx)) 1167c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose return true; 1168c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose return Val.getBoolValue(); 1169c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose } 1170b5cd1220dd650a358622241237aa595c5d675506Jordan Rose default: 1171b5cd1220dd650a358622241237aa595c5d675506Jordan Rose break; 1172b5cd1220dd650a358622241237aa595c5d675506Jordan Rose } 1173b5cd1220dd650a358622241237aa595c5d675506Jordan Rose } while ((S = PM.getParent(S))); 1174b5cd1220dd650a358622241237aa595c5d675506Jordan Rose 1175b5cd1220dd650a358622241237aa595c5d675506Jordan Rose return false; 1176b5cd1220dd650a358622241237aa595c5d675506Jordan Rose} 1177b5cd1220dd650a358622241237aa595c5d675506Jordan Rose 117858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 117958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosestatic void diagnoseRepeatedUseOfWeak(Sema &S, 118058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const sema::FunctionScopeInfo *CurFn, 1181b5cd1220dd650a358622241237aa595c5d675506Jordan Rose const Decl *D, 1182b5cd1220dd650a358622241237aa595c5d675506Jordan Rose const ParentMap &PM) { 118358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy; 118458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap; 118558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector; 1186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typedef std::pair<const Stmt *, WeakObjectUseMap::const_iterator> 1187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StmtUsesPair; 118858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 1189c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose ASTContext &Ctx = S.getASTContext(); 1190c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose 119158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const WeakObjectUseMap &WeakMap = CurFn->getWeakObjectUses(); 119258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 119358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // Extract all weak objects that are referenced more than once. 119458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose SmallVector<StmtUsesPair, 8> UsesByStmt; 119558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose for (WeakObjectUseMap::const_iterator I = WeakMap.begin(), E = WeakMap.end(); 119658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose I != E; ++I) { 119758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const WeakUseVector &Uses = I->second; 119858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 119958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // Find the first read of the weak object. 120058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end(); 120158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose for ( ; UI != UE; ++UI) { 120258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose if (UI->isUnsafe()) 120358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose break; 120458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 120558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 120658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // If there were only writes to this object, don't warn. 120758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose if (UI == UE) 120858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose continue; 120958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 1210b5cd1220dd650a358622241237aa595c5d675506Jordan Rose // If there was only one read, followed by any number of writes, and the 1211c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose // read is not within a loop, don't warn. Additionally, don't warn in a 1212c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose // loop if the base object is a local variable -- local variables are often 1213c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose // changed in loops. 1214b5cd1220dd650a358622241237aa595c5d675506Jordan Rose if (UI == Uses.begin()) { 1215b5cd1220dd650a358622241237aa595c5d675506Jordan Rose WeakUseVector::const_iterator UI2 = UI; 1216b5cd1220dd650a358622241237aa595c5d675506Jordan Rose for (++UI2; UI2 != UE; ++UI2) 1217b5cd1220dd650a358622241237aa595c5d675506Jordan Rose if (UI2->isUnsafe()) 1218b5cd1220dd650a358622241237aa595c5d675506Jordan Rose break; 1219b5cd1220dd650a358622241237aa595c5d675506Jordan Rose 1220c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose if (UI2 == UE) { 1221c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose if (!isInLoop(Ctx, PM, UI->getUseExpr())) 1222b5cd1220dd650a358622241237aa595c5d675506Jordan Rose continue; 1223c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose 1224c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose const WeakObjectProfileTy &Profile = I->first; 1225c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose if (!Profile.isExactProfile()) 1226c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose continue; 1227c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose 1228c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose const NamedDecl *Base = Profile.getBase(); 1229c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose if (!Base) 1230c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose Base = Profile.getProperty(); 1231c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose assert(Base && "A profile always has a base or property."); 1232c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose 1233c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose if (const VarDecl *BaseVar = dyn_cast<VarDecl>(Base)) 1234c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose if (BaseVar->hasLocalStorage() && !isa<ParmVarDecl>(Base)) 1235c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose continue; 1236c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose } 1237b5cd1220dd650a358622241237aa595c5d675506Jordan Rose } 1238b5cd1220dd650a358622241237aa595c5d675506Jordan Rose 123958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose UsesByStmt.push_back(StmtUsesPair(UI->getUseExpr(), I)); 124058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 124158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 124258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose if (UsesByStmt.empty()) 124358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return; 124458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 124558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // Sort by first use so that we emit the warnings in a deterministic order. 1246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceManager &SM = S.getSourceManager(); 124758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose std::sort(UsesByStmt.begin(), UsesByStmt.end(), 1248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines [&SM](const StmtUsesPair &LHS, const StmtUsesPair &RHS) { 1249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return SM.isBeforeInTranslationUnit(LHS.first->getLocStart(), 1250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RHS.first->getLocStart()); 1251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines }); 125258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 125358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // Classify the current code body for better warning text. 125458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // This enum should stay in sync with the cases in 125558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak. 125658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // FIXME: Should we use a common classification enum and the same set of 125758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // possibilities all throughout Sema? 125858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose enum { 125958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose Function, 126058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose Method, 126158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose Block, 126258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose Lambda 126358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } FunctionKind; 126458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 126558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose if (isa<sema::BlockScopeInfo>(CurFn)) 126658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose FunctionKind = Block; 126758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose else if (isa<sema::LambdaScopeInfo>(CurFn)) 126858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose FunctionKind = Lambda; 126958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose else if (isa<ObjCMethodDecl>(D)) 127058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose FunctionKind = Method; 127158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose else 127258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose FunctionKind = Function; 127358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 127458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // Iterate through the sorted problems and emit warnings for each. 12756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &P : UsesByStmt) { 12766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Stmt *FirstRead = P.first; 12776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const WeakObjectProfileTy &Key = P.second->first; 12786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const WeakUseVector &Uses = P.second->second; 127958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 12807a2704800943fbb69207e125d28186278712af36Jordan Rose // For complicated expressions like 'a.b.c' and 'x.b.c', WeakObjectProfileTy 12817a2704800943fbb69207e125d28186278712af36Jordan Rose // may not contain enough information to determine that these are different 12827a2704800943fbb69207e125d28186278712af36Jordan Rose // properties. We can only be 100% sure of a repeated use in certain cases, 12837a2704800943fbb69207e125d28186278712af36Jordan Rose // and we adjust the diagnostic kind accordingly so that the less certain 12847a2704800943fbb69207e125d28186278712af36Jordan Rose // case can be turned off if it is too noisy. 128558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose unsigned DiagKind; 128658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose if (Key.isExactProfile()) 128758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose DiagKind = diag::warn_arc_repeated_use_of_weak; 128858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose else 128958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose DiagKind = diag::warn_arc_possible_repeated_use_of_weak; 129058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 12917a2704800943fbb69207e125d28186278712af36Jordan Rose // Classify the weak object being accessed for better warning text. 12927a2704800943fbb69207e125d28186278712af36Jordan Rose // This enum should stay in sync with the cases in 12937a2704800943fbb69207e125d28186278712af36Jordan Rose // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak. 12947a2704800943fbb69207e125d28186278712af36Jordan Rose enum { 12957a2704800943fbb69207e125d28186278712af36Jordan Rose Variable, 12967a2704800943fbb69207e125d28186278712af36Jordan Rose Property, 12977a2704800943fbb69207e125d28186278712af36Jordan Rose ImplicitProperty, 12987a2704800943fbb69207e125d28186278712af36Jordan Rose Ivar 12997a2704800943fbb69207e125d28186278712af36Jordan Rose } ObjectKind; 13007a2704800943fbb69207e125d28186278712af36Jordan Rose 13017a2704800943fbb69207e125d28186278712af36Jordan Rose const NamedDecl *D = Key.getProperty(); 13027a2704800943fbb69207e125d28186278712af36Jordan Rose if (isa<VarDecl>(D)) 13037a2704800943fbb69207e125d28186278712af36Jordan Rose ObjectKind = Variable; 13047a2704800943fbb69207e125d28186278712af36Jordan Rose else if (isa<ObjCPropertyDecl>(D)) 13057a2704800943fbb69207e125d28186278712af36Jordan Rose ObjectKind = Property; 13067a2704800943fbb69207e125d28186278712af36Jordan Rose else if (isa<ObjCMethodDecl>(D)) 13077a2704800943fbb69207e125d28186278712af36Jordan Rose ObjectKind = ImplicitProperty; 13087a2704800943fbb69207e125d28186278712af36Jordan Rose else if (isa<ObjCIvarDecl>(D)) 13097a2704800943fbb69207e125d28186278712af36Jordan Rose ObjectKind = Ivar; 13107a2704800943fbb69207e125d28186278712af36Jordan Rose else 13117a2704800943fbb69207e125d28186278712af36Jordan Rose llvm_unreachable("Unexpected weak object kind!"); 13127a2704800943fbb69207e125d28186278712af36Jordan Rose 131358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // Show the first time the object was read. 131458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose S.Diag(FirstRead->getLocStart(), DiagKind) 13157348454025693dd20a411c2bcaabd4460cb87559Joerg Sonnenberger << int(ObjectKind) << D << int(FunctionKind) 131658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose << FirstRead->getSourceRange(); 131758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 131858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // Print all the other accesses as notes. 13196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &Use : Uses) { 13206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Use.getUseExpr() == FirstRead) 132158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose continue; 13226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines S.Diag(Use.getUseExpr()->getLocStart(), 132358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose diag::note_arc_weak_also_accessed_here) 13246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << Use.getUseExpr()->getSourceRange(); 132558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 132658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 132758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose} 132858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 132958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosenamespace { 1330610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass UninitValsDiagReporter : public UninitVariablesHandler { 1331610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek Sema &S; 13325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner typedef SmallVector<UninitUse, 2> UsesVec; 1333e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer typedef llvm::PointerIntPair<UsesVec *, 1, bool> MappedType; 13343285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella // Prefer using MapVector to DenseMap, so that iteration order will be 13353285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella // the same as insertion order. This is needed to obtain a deterministic 13363285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella // order of diagnostics when calling flushDiagnostics(). 13373285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella typedef llvm::MapVector<const VarDecl *, MappedType> UsesMap; 133894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek UsesMap *uses; 133994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 1340610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic: 13416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UninitValsDiagReporter(Sema &S) : S(S), uses(nullptr) {} 134294b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek ~UninitValsDiagReporter() { 134394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek flushDiagnostics(); 134494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 13459e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 13463285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella MappedType &getUses(const VarDecl *vd) { 134794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek if (!uses) 134894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek uses = new UsesMap(); 13499e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 13503285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella MappedType &V = (*uses)[vd]; 1351e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer if (!V.getPointer()) 1352e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer V.setPointer(new UsesVec()); 135394b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 13549e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek return V; 13559e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek } 1356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void handleUseOfUninitVariable(const VarDecl *vd, 1358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const UninitUse &use) override { 1359e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer getUses(vd).getPointer()->push_back(use); 13609e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek } 13619e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 1362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void handleSelfInit(const VarDecl *vd) override { 1363e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer getUses(vd).setInt(true); 136494b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 136594b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek 136694b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek void flushDiagnostics() { 136794b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek if (!uses) 136894b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek return; 13693285c78041f80a26f6a947e2922e15c4af6e00bbEnea Zaffanella 13706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &P : *uses) { 13716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const VarDecl *vd = P.first; 13726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const MappedType &V = P.second; 13739e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 1374e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer UsesVec *vec = V.getPointer(); 1375e103979ceac63c98873f3307ee897eab559356a0Benjamin Kramer bool hasSelfInit = V.getInt(); 13769e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 13779e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // Specially handle the case where we have uses of an uninitialized 13789e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // variable, but the root cause is an idiomatic self-init. We want 13799e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // to report the diagnostic at the self-init since that is the root cause. 13800d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay if (!vec->empty() && hasSelfInit && hasAlwaysUninitializedUse(vec)) 13812815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith DiagnoseUninitializedUse(S, vd, 13822815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith UninitUse(vd->getInit()->IgnoreParenCasts(), 13832815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith /* isAlwaysUninit */ true), 13840d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay /* alwaysReportSelfInit */ true); 13859e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek else { 13869e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // Sort the uses by their SourceLocations. While not strictly 13879e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // guaranteed to produce them in line/column order, this will provide 13889e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // a stable ordering. 1389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::sort(vec->begin(), vec->end(), 1390651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines [](const UninitUse &a, const UninitUse &b) { 1391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Prefer a more confident report over a less confident one. 1392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (a.getKind() != b.getKind()) 1393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return a.getKind() > b.getKind(); 1394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return a.getUser()->getLocStart() < b.getUser()->getLocStart(); 1395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines }); 1396651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 13976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &U : *vec) { 13982815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith // If we have self-init, downgrade all uses to 'may be uninitialized'. 13996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UninitUse Use = hasSelfInit ? UninitUse(U.getUser(), false) : U; 14002815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith 14012815e1a075c74143a0b60a632090ece1dffa5c7cRichard Smith if (DiagnoseUninitializedUse(S, vd, Use)) 14029e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // Skip further diagnostics for this variable. We try to warn only 14039e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // on the first point at which a variable is used uninitialized. 14049e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek break; 14059e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek } 140664fb959beb3a0ecb84a58e6ff82660a7a669f7b8Chandler Carruth } 14079e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek 14089e7617220135a6f6226cf09cb242cc1b905aedb4Ted Kremenek // Release the uses vector. 140994b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek delete vec; 141094b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek } 141194b1b4d785bc0f09f6af4be394e59d51f35dda60Ted Kremenek delete uses; 1412610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 14130d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay 14140d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gayprivate: 14150d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay static bool hasAlwaysUninitializedUse(const UsesVec* vec) { 14166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return std::any_of(vec->begin(), vec->end(), [](const UninitUse &U) { 14176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return U.getKind() == UninitUse::Always || 14186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines U.getKind() == UninitUse::AfterCall || 14196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines U.getKind() == UninitUse::AfterDecl; 14206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines }); 14210d381810da19dd7677b9a79fca516d298fa5addbMatt Beaumont-Gay } 1422610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}; 1423610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 1424610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 142575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskinamespace clang { 1426df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace { 1427cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkotypedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes; 14282e5156274b8051217565b557bfa14c80f7990e9cRichard Smithtypedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag; 1429ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramertypedef std::list<DelayedDiag> DiagList; 143075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 143175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskistruct SortDiagBySourceLocation { 1432ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer SourceManager &SM; 1433ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer SortDiagBySourceLocation(SourceManager &SM) : SM(SM) {} 143475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 143575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski bool operator()(const DelayedDiag &left, const DelayedDiag &right) { 143675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski // Although this call will be slow, this is only called when outputting 143775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski // multiple warnings. 1438ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer return SM.isBeforeInTranslationUnit(left.first.first, right.first.first); 143975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 144075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski}; 1441df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins}} 144275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 1443df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===// 1444df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// -Wthread-safety 1445df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===// 1446df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace clang { 1447df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace thread_safety { 144899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikienamespace { 144975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowskiclass ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler { 145075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski Sema &S; 145175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski DiagList Warnings; 14522e5156274b8051217565b557bfa14c80f7990e9cRichard Smith SourceLocation FunLocation, FunEndLocation; 145375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 145475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski // Helper functions 1455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void warnLockMismatch(unsigned DiagID, StringRef Kind, Name LockName, 1456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation Loc) { 1457f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins // Gracefully handle rare cases when the analysis can't get a more 1458f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins // precise source location. 1459f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins if (!Loc.isValid()) 1460f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins Loc = FunLocation; 1461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName); 14622e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 146375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 146475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 146575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski public: 14662e5156274b8051217565b557bfa14c80f7990e9cRichard Smith ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL) 14672e5156274b8051217565b557bfa14c80f7990e9cRichard Smith : S(S), FunLocation(FL), FunEndLocation(FEL) {} 146875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 146975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski /// \brief Emit all buffered diagnostics in order of sourcelocation. 147075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski /// We need to output diagnostics produced while iterating through 147175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski /// the lockset in deterministic order, so this function orders diagnostics 147275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski /// and outputs them. 147375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski void emitDiagnostics() { 1474ecafd309b3ed2ffc6f8ae7eecd1e7eae84b26f81Benjamin Kramer Warnings.sort(SortDiagBySourceLocation(S.getSourceManager())); 14756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &Diag : Warnings) { 14766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines S.Diag(Diag.first.first, Diag.first.second); 14776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &Note : Diag.second) 14786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines S.Diag(Note.first, Note.second); 14792e5156274b8051217565b557bfa14c80f7990e9cRichard Smith } 148075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 148175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 1482651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) override { 1483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_cannot_resolve_lock) 1484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << Loc); 14852e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 148699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski } 1487651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void handleUnmatchedUnlock(StringRef Kind, Name LockName, 1488651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation Loc) override { 1489651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines warnLockMismatch(diag::warn_unlock_but_no_lock, Kind, LockName, Loc); 149075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 1491651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void handleIncorrectUnlockKind(StringRef Kind, Name LockName, 1492651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LockKind Expected, LockKind Received, 1493651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation Loc) override { 1494651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Loc.isInvalid()) 1495651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Loc = FunLocation; 1496651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_kind_mismatch) 1497651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << Kind << LockName << Received 1498651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << Expected); 1499651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1500651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1501651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override { 1502651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines warnLockMismatch(diag::warn_double_lock, Kind, LockName, Loc); 150375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 150475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 1505651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void handleMutexHeldEndOfScope(StringRef Kind, Name LockName, 1506651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation LocLocked, 15072e5156274b8051217565b557bfa14c80f7990e9cRichard Smith SourceLocation LocEndOfScope, 1508651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LockErrorKind LEK) override { 15094e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski unsigned DiagID = 0; 15104e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski switch (LEK) { 15114e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski case LEK_LockedSomePredecessors: 15122e5156274b8051217565b557bfa14c80f7990e9cRichard Smith DiagID = diag::warn_lock_some_predecessors; 15134e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski break; 15144e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski case LEK_LockedSomeLoopIterations: 15154e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski DiagID = diag::warn_expecting_lock_held_on_loop; 15164e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski break; 15174e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski case LEK_LockedAtEndOfFunction: 15184e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski DiagID = diag::warn_no_unlock; 15194e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski break; 1520879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins case LEK_NotLockedAtEndOfFunction: 1521879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins DiagID = diag::warn_expecting_locked; 1522879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins break; 15234e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski } 15242e5156274b8051217565b557bfa14c80f7990e9cRichard Smith if (LocEndOfScope.isInvalid()) 15252e5156274b8051217565b557bfa14c80f7990e9cRichard Smith LocEndOfScope = FunEndLocation; 15262e5156274b8051217565b557bfa14c80f7990e9cRichard Smith 1527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << Kind 1528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << LockName); 15295696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins if (LocLocked.isValid()) { 1530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here) 1531651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << Kind); 15325696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); 15335696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins return; 15345696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins } 15355696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 153675f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 153775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 1538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void handleExclusiveAndShared(StringRef Kind, Name LockName, 1539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation Loc1, 1540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation Loc2) override { 1541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PartialDiagnosticAt Warning(Loc1, 1542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.PDiag(diag::warn_lock_exclusive_and_shared) 1543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << Kind << LockName); 1544651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PartialDiagnosticAt Note(Loc2, S.PDiag(diag::note_lock_exclusive_and_shared) 1545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << Kind << LockName); 15462e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); 154775f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 154875f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 1549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void handleNoMutexHeld(StringRef Kind, const NamedDecl *D, 1550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProtectedOperationKind POK, AccessKind AK, 1551651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation Loc) override { 1552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((POK == POK_VarAccess || POK == POK_VarDereference) && 1553651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "Only works for variables"); 1554df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski unsigned DiagID = POK == POK_VarAccess? 1555df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski diag::warn_variable_requires_any_lock: 1556df8327c28d293cf7c6952b86dba26863235dcc0fCaitlin Sadowski diag::warn_var_deref_requires_any_lock; 15572e5156274b8051217565b557bfa14c80f7990e9cRichard Smith PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) 15585b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins << D->getNameAsString() << getLockKindFromAccessKind(AK)); 15592e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 156075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 156175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 1562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void handleMutexNotHeld(StringRef Kind, const NamedDecl *D, 1563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProtectedOperationKind POK, Name LockName, 1564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LockKind LK, SourceLocation Loc, 1565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Name *PossibleMatch) override { 1566e87158dfbca01577810f301543c3cdcfc955d8b0Caitlin Sadowski unsigned DiagID = 0; 15673f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins if (PossibleMatch) { 15683f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins switch (POK) { 15693f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_VarAccess: 15703f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_variable_requires_lock_precise; 15713f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 15723f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_VarDereference: 15733f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_var_deref_requires_lock_precise; 15743f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 15753f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_FunctionCall: 15763f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_fun_requires_lock_precise; 15773f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 15783f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins } 1579651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind 1580651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << D->getNameAsString() 1581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << LockName << LK); 15823f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match) 1583651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << *PossibleMatch); 15843f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); 15853f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins } else { 15863f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins switch (POK) { 15873f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_VarAccess: 15883f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_variable_requires_lock; 15893f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 15903f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_VarDereference: 15913f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_var_deref_requires_lock; 15923f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 15933f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins case POK_FunctionCall: 15943f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins DiagID = diag::warn_fun_requires_lock; 15953f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins break; 15963f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins } 1597651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind 1598651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << D->getNameAsString() 1599651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << LockName << LK); 16003f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 160175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 160275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 160375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 1604651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void handleFunExcludesLock(StringRef Kind, Name FunName, Name LockName, 1605651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation Loc) override { 1606651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_fun_excludes_mutex) 1607651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << Kind << FunName << LockName); 16082e5156274b8051217565b557bfa14c80f7990e9cRichard Smith Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 160975f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 161075f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski}; 161175f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski} 161275f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski} 161399ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie} 161475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 1615610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 1616df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// -Wconsumed 1617df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===// 1618df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1619df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace clang { 1620df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace consumed { 1621df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace { 1622df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsclass ConsumedWarningsHandler : public ConsumedWarningsHandlerBase { 1623df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1624df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins Sema &S; 1625df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins DiagList Warnings; 1626df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1627df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinspublic: 1628df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1629df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins ConsumedWarningsHandler(Sema &S) : S(S) {} 1630651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1631651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void emitDiagnostics() override { 1632df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins Warnings.sort(SortDiagBySourceLocation(S.getSourceManager())); 16336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &Diag : Warnings) { 16346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines S.Diag(Diag.first.first, Diag.first.second); 16356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &Note : Diag.second) 16366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines S.Diag(Note.first, Note.second); 1637df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins } 1638df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins } 1639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1640651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void warnLoopStateMismatch(SourceLocation Loc, 1641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef VariableName) override { 16427385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch) << 16437385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins VariableName); 16447385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins 16457385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 16467385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins } 16477385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins 1648cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins void warnParamReturnTypestateMismatch(SourceLocation Loc, 1649cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins StringRef VariableName, 1650cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins StringRef ExpectedState, 1651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef ObservedState) override { 1652cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins 1653cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins PartialDiagnosticAt Warning(Loc, S.PDiag( 1654cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins diag::warn_param_return_typestate_mismatch) << VariableName << 1655cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins ExpectedState << ObservedState); 1656cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins 1657cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1658cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins } 1659cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins 1660d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins void warnParamTypestateMismatch(SourceLocation Loc, StringRef ExpectedState, 1661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef ObservedState) override { 1662d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins 1663d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins PartialDiagnosticAt Warning(Loc, S.PDiag( 1664d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins diag::warn_param_typestate_mismatch) << ExpectedState << ObservedState); 1665d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins 1666d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1667d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins } 1668d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins 16690e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins void warnReturnTypestateForUnconsumableType(SourceLocation Loc, 1670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef TypeName) override { 16710e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins PartialDiagnosticAt Warning(Loc, S.PDiag( 16720e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins diag::warn_return_typestate_for_unconsumable_type) << TypeName); 16730e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins 16740e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 16750e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins } 16760e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins 16770e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState, 1678651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef ObservedState) override { 16790e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins 16800e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins PartialDiagnosticAt Warning(Loc, S.PDiag( 16810e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins diag::warn_return_typestate_mismatch) << ExpectedState << ObservedState); 16820e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins 16830e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 16840e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins } 16850e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins 168666540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State, 1687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation Loc) override { 1688df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1689df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins PartialDiagnosticAt Warning(Loc, S.PDiag( 169066540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins diag::warn_use_of_temp_in_invalid_state) << MethodName << State); 1691df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1692df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1693df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins } 1694df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 169566540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins void warnUseInInvalidState(StringRef MethodName, StringRef VariableName, 1696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef State, SourceLocation Loc) override { 1697df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 169866540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state) << 169966540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins MethodName << VariableName << State); 1700df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1701df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1702df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins } 1703df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins}; 1704df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins}}} 1705df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1706df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===// 1707dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based 1708dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek// warnings on a function, method, or block. 1709dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek//===----------------------------------------------------------------------===// 1710dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 1711d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekclang::sema::AnalysisBasedWarnings::Policy::Policy() { 1712dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek enableCheckFallThrough = 1; 1713d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek enableCheckUnreachable = 0; 17143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski enableThreadSafetyAnalysis = 0; 1715df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins enableConsumedAnalysis = 0; 1716d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek} 1717dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 1718651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic unsigned isEnabled(DiagnosticsEngine &D, unsigned diag) { 1719ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return (unsigned)!D.isIgnored(diag, SourceLocation()); 1720651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1721651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 17225d98994c7749312a43ce6adf45537979a98e7afdChandler Carruthclang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) 17235d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth : S(s), 17245d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth NumFunctionsAnalyzed(0), 172554cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer NumFunctionsWithBadCFGs(0), 17265d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth NumCFGBlocks(0), 172754cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer MaxCFGBlocksPerFunction(0), 172854cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer NumUninitAnalysisFunctions(0), 172954cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer NumUninitAnalysisVariables(0), 173054cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer MaxUninitAnalysisVariablesPerFunction(0), 173154cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer NumUninitAnalysisBlockVisits(0), 173254cf341bd4145e5e31f91c5777fcdaf3f2400537Benjamin Kramer MaxUninitAnalysisBlockVisitsPerFunction(0) { 1733651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1734651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines using namespace diag; 1735d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &D = S.getDiagnostics(); 1736651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1737651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DefaultPolicy.enableCheckUnreachable = 1738651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isEnabled(D, warn_unreachable) || 1739651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isEnabled(D, warn_unreachable_break) || 1740651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isEnabled(D, warn_unreachable_return) || 1741651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isEnabled(D, warn_unreachable_loop_increment); 1742651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1743651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DefaultPolicy.enableThreadSafetyAnalysis = 1744651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isEnabled(D, warn_double_lock); 1745651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1746651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DefaultPolicy.enableConsumedAnalysis = 1747651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isEnabled(D, warn_use_in_invalid_state); 1748dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 1749dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 17506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstatic void flushDiagnostics(Sema &S, const sema::FunctionScopeInfo *fscope) { 17516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &D : fscope->PossiblyUnreachableDiags) 1752351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek S.Diag(D.Loc, D.PD); 1753351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek} 1754351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 1755d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenekvoid clang::sema:: 1756d064fdc4b7b64ca55b40b70490c79d6f569df78eTed KremenekAnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 1757283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek sema::FunctionScopeInfo *fscope, 17583ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek const Decl *D, const BlockExpr *blkExpr) { 1759d068aabc484c4009282122c6ef26e66e68cfa044Ted Kremenek 1760dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // We avoid doing analysis-based warnings when there are errors for 1761dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // two reasons: 1762dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // (1) The CFGs often can't be constructed (if the body is invalid), so 1763dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // don't bother trying. 1764dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // (2) The code already has problems; running the analysis just takes more 1765dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // time. 1766d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie DiagnosticsEngine &Diags = S.getDiagnostics(); 176799e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek 1768d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek // Do not do any analysis for declarations in system headers if we are 1769d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek // going to just ignore them. 177099e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek if (Diags.getSuppressSystemWarnings() && 1771d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek S.SourceMgr.isInSystemHeader(D->getLocation())) 1772d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek return; 1773d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 1774e0054f61fd84133eb0d19c19ae9afaf117933274John McCall // For code in dependent contexts, we'll do this at instantiation time. 177523661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (cast<DeclContext>(D)->isDependentContext()) 177623661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie return; 1777dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 177812f37e411462b8388eb1309357bd62257debacacDeLesley Hutchins if (Diags.hasUncompilableErrorOccurred() || Diags.hasFatalErrorOccurred()) { 1779351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek // Flush out any possibly unreachable diagnostics. 1780351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek flushDiagnostics(S, fscope); 1781351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek return; 1782351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek } 1783351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 1784dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const Stmt *Body = D->getBody(); 1785dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek assert(Body); 1786dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 17870cd72319e74899c4e5561cc70b7c4939d3767bd9Ted Kremenek // Construct the analysis context with the specified CFG build options. 17886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AnalysisDeclContext AC(/* AnalysisDeclContextManager */ nullptr, D); 1789bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek 1790dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Don't generate EH edges for CallExprs as we'd like to avoid the n^2 1791e575359c34a9248c55ec0c03a8fc945f1ee4cb01Benjamin Kramer // explosion for destructors that can result and the compile time hit. 1792bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true; 1793bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek AC.getCFGBuildOptions().AddEHEdges = false; 1794bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek AC.getCFGBuildOptions().AddInitializers = true; 1795bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek AC.getCFGBuildOptions().AddImplicitDtors = true; 1796faadf48443f8c2fc53d267485d7e0e1bd382fc75Jordan Rose AC.getCFGBuildOptions().AddTemporaryDtors = true; 1797651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AC.getCFGBuildOptions().AddCXXNewAllocator = false; 1798faadf48443f8c2fc53d267485d7e0e1bd382fc75Jordan Rose 17990c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // Force that certain expressions appear as CFGElements in the CFG. This 18000c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // is used to speed up various analyses. 18010c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // FIXME: This isn't the right factoring. This is here for initial 18020c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // prototyping, but we need a way for analyses to say what expressions they 18030c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // expect to always be CFGElements and then fill in the BuildOptions 18040c8e5a0f70cbdb800d939c1807d05f380b2854d4Ted Kremenek // appropriately. This is essentially a layering violation. 1805df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis || 1806df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins P.enableConsumedAnalysis) { 18071fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins // Unreachable code analysis and thread safety require a linearized CFG. 18080f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek AC.getCFGBuildOptions().setAllAlwaysAdd(); 18090f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek } 18100f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek else { 18110f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek AC.getCFGBuildOptions() 18120f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek .setAlwaysAdd(Stmt::BinaryOperatorClass) 18136cfa78f6bd4e7d5e23366a0907f8f8792366bc4cRichard Smith .setAlwaysAdd(Stmt::CompoundAssignOperatorClass) 18140f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek .setAlwaysAdd(Stmt::BlockExprClass) 18150f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek .setAlwaysAdd(Stmt::CStyleCastExprClass) 18160f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek .setAlwaysAdd(Stmt::DeclRefExprClass) 18170f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek .setAlwaysAdd(Stmt::ImplicitCastExprClass) 1818e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith .setAlwaysAdd(Stmt::UnaryOperatorClass) 1819e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith .setAlwaysAdd(Stmt::AttributedStmtClass); 18200f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek } 1821bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek 18226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Install the logical handler for -Wtautological-overlap-compare 18236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines std::unique_ptr<LogicalErrorHandler> LEH; 1824ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison, 1825ef8225444452a1486bd721f3285301fe84643b00Stephen Hines D->getLocStart())) { 18266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LEH.reset(new LogicalErrorHandler(S)); 18276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AC.getCFGBuildOptions().Observer = LEH.get(); 18286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 18290cd72319e74899c4e5561cc70b7c4939d3767bd9Ted Kremenek 1830351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek // Emit delayed diagnostics. 183123661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (!fscope->PossiblyUnreachableDiags.empty()) { 1832351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek bool analyzed = false; 18330d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 18340d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek // Register the expressions with the CFGBuilder. 18356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &D : fscope->PossiblyUnreachableDiags) { 18366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (D.stmt) 18376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AC.registerForcedBlockExpression(D.stmt); 18380d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek } 18390d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 18400d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek if (AC.getCFG()) { 18410d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek analyzed = true; 18426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const auto &D : fscope->PossiblyUnreachableDiags) { 18430d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek bool processed = false; 18446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (D.stmt) { 18456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const CFGBlock *block = AC.getBlockForRegisteredExpression(D.stmt); 184671b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman CFGReverseBlockReachabilityAnalysis *cra = 184771b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman AC.getCFGReachablityAnalysis(); 184871b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman // FIXME: We should be able to assert that block is non-null, but 184971b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman // the CFG analysis can skip potentially-evaluated expressions in 185071b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman // edge cases; see test/Sema/vla-2.c. 185171b8fb5d4233420d2ed2f150a54ea61431bd8684Eli Friedman if (block && cra) { 1852351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek // Can this block be reached from the entrance? 18530d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek if (cra->isReachable(&AC.getCFG()->getEntry(), block)) 1854351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek S.Diag(D.Loc, D.PD); 18550d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek processed = true; 1856351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek } 18570d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek } 18580d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek if (!processed) { 18590d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek // Emit the warning anyway if we cannot map to a basic block. 18600d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek S.Diag(D.Loc, D.PD); 1861351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek } 1862351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek } 18630d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek } 1864351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 1865351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek if (!analyzed) 1866351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek flushDiagnostics(S, fscope); 1867351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek } 1868351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 1869351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 1870dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Warning: check missing 'return' 187123661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (P.enableCheckFallThrough) { 1872dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek const CheckFallThroughDiagnostics &CD = 1873dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock() 1874793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor : (isa<CXXMethodDecl>(D) && 1875793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call && 1876793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor cast<CXXMethodDecl>(D)->getParent()->isLambda()) 1877793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor ? CheckFallThroughDiagnostics::MakeForLambda() 1878793cd1c4cdfaafc52e2c2ad9dae959befe4bb166Douglas Gregor : CheckFallThroughDiagnostics::MakeForFunction(D)); 18793ed6fc08a9cd293d012fa49ab2a615e618d7c3faTed Kremenek CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC); 1880dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek } 1881dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek 1882dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek // Warning: check for unreachable code 18835dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek if (P.enableCheckUnreachable) { 18845dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek // Only check for unreachable code on non-template instantiations. 18855dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek // Different template instantiations can effectively change the control-flow 18865dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek // and it is very difficult to prove that a snippet of code in a template 18875dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek // is unreachable for all instantiations. 188875df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek bool isTemplateInstantiation = false; 188975df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) 189075df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek isTemplateInstantiation = Function->isTemplateInstantiation(); 189175df4eeede7b91c22c1d63fafd4dd4142844e3b9Ted Kremenek if (!isTemplateInstantiation) 18925dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek CheckUnreachable(S, AC); 18935dfee06daa359bbe0f3c9de055b8a02d61a05173Ted Kremenek } 189475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski 18953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Check for thread safety violations 189623661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (P.enableThreadSafetyAnalysis) { 1897f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins SourceLocation FL = AC.getDecl()->getLocation(); 18982e5156274b8051217565b557bfa14c80f7990e9cRichard Smith SourceLocation FEL = AC.getDecl()->getLocEnd(); 18992e5156274b8051217565b557bfa14c80f7990e9cRichard Smith thread_safety::ThreadSafetyReporter Reporter(S, FL, FEL); 1900ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (!Diags.isIgnored(diag::warn_thread_safety_beta, D->getLocStart())) 1901fb4afc2fc659faff43a6df4c1d0e07df9c90479dDeLesley Hutchins Reporter.setIssueBetaWarnings(true); 1902fb4afc2fc659faff43a6df4c1d0e07df9c90479dDeLesley Hutchins 190375f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski thread_safety::runThreadSafetyAnalysis(AC, Reporter); 190475f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski Reporter.emitDiagnostics(); 190575f23aeb1c820b49f9faebed63b1cbef76c2c907Caitlin Sadowski } 19063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 1907df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins // Check for violations of consumed properties. 1908df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins if (P.enableConsumedAnalysis) { 1909df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins consumed::ConsumedWarningsHandler WarningHandler(S); 19102d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner consumed::ConsumedAnalyzer Analyzer(WarningHandler); 1911df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins Analyzer.run(AC); 1912df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins } 1913df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1914ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (!Diags.isIgnored(diag::warn_uninit_var, D->getLocStart()) || 1915ef8225444452a1486bd721f3285301fe84643b00Stephen Hines !Diags.isIgnored(diag::warn_sometimes_uninit_var, D->getLocStart()) || 1916ef8225444452a1486bd721f3285301fe84643b00Stephen Hines !Diags.isIgnored(diag::warn_maybe_uninit_var, D->getLocStart())) { 1917c5e43c19ddb40b8a1371291f73ae66fe54951ca5Ted Kremenek if (CFG *cfg = AC.getCFG()) { 1918c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek UninitValsDiagReporter reporter(S); 191957080fbac1ccce702255423335d52e81bcf17b6bFariborz Jahanian UninitVariablesAnalysisStats stats; 192012efd57ee474c06880a7434ece21a39ac3f34e24Benjamin Kramer std::memset(&stats, 0, sizeof(UninitVariablesAnalysisStats)); 1921a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC, 19225d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth reporter, stats); 19235d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 19245d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth if (S.CollectStats && stats.NumVariablesAnalyzed > 0) { 19255d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth ++NumUninitAnalysisFunctions; 19265d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth NumUninitAnalysisVariables += stats.NumVariablesAnalyzed; 19275d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth NumUninitAnalysisBlockVisits += stats.NumBlockVisits; 19285d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth MaxUninitAnalysisVariablesPerFunction = 19295d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth std::max(MaxUninitAnalysisVariablesPerFunction, 19305d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth stats.NumVariablesAnalyzed); 19315d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth MaxUninitAnalysisBlockVisitsPerFunction = 19325d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth std::max(MaxUninitAnalysisBlockVisitsPerFunction, 19335d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth stats.NumBlockVisits); 19345d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth } 19355d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth } 19365d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth } 19375d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 19381973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko bool FallThroughDiagFull = 1939ef8225444452a1486bd721f3285301fe84643b00Stephen Hines !Diags.isIgnored(diag::warn_unannotated_fallthrough, D->getLocStart()); 1940ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool FallThroughDiagPerFunction = !Diags.isIgnored( 1941ef8225444452a1486bd721f3285301fe84643b00Stephen Hines diag::warn_unannotated_fallthrough_per_function, D->getLocStart()); 1942c2f51cfefd77e9b25f201ecf879343d6d9a45158Sean Hunt if (FallThroughDiagFull || FallThroughDiagPerFunction) { 19431973634e445d4f1abdeedc2809f2d281929253b6Alexander Kornienko DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull); 1944e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 1945e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 194658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose if (S.getLangOpts().ObjCARCWeak && 1947ef8225444452a1486bd721f3285301fe84643b00Stephen Hines !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, D->getLocStart())) 1948b5cd1220dd650a358622241237aa595c5d675506Jordan Rose diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap()); 194958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 1950651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1951651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Check for infinite self-recursion in functions 1952ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (!Diags.isIgnored(diag::warn_infinite_recursive_function, 1953ef8225444452a1486bd721f3285301fe84643b00Stephen Hines D->getLocStart())) { 1954651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1955651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines checkRecursiveFunction(S, FD, Body, AC); 1956651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1957651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1958651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 19596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If none of the previous checks caused a CFG build, trigger one here 19606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // for -Wtautological-overlap-compare 1961ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison, 19626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines D->getLocStart())) { 19636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AC.getCFG(); 19646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 19656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 19665d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth // Collect statistics about the CFG if it was built. 19675d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth if (S.CollectStats && AC.isCFGBuilt()) { 19685d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth ++NumFunctionsAnalyzed; 19695d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth if (CFG *cfg = AC.getCFG()) { 19705d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth // If we successfully built a CFG for this context, record some more 19715d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth // detail information about it. 19723ea4c49709c5bba5f8b16c6ceb725d9b9a1c48c6Chandler Carruth NumCFGBlocks += cfg->getNumBlockIDs(); 19735d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction, 19743ea4c49709c5bba5f8b16c6ceb725d9b9a1c48c6Chandler Carruth cfg->getNumBlockIDs()); 19755d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth } else { 19765d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth ++NumFunctionsWithBadCFGs; 1977610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 1978610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 1979dbdbaaf34f798fa5cabec273c4b9397b3fd6a98cTed Kremenek} 19805d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 19815d98994c7749312a43ce6adf45537979a98e7afdChandler Carruthvoid clang::sema::AnalysisBasedWarnings::PrintStats() const { 19825d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth llvm::errs() << "\n*** Analysis Based Warnings Stats:\n"; 19835d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 19845d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs; 19855d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth unsigned AvgCFGBlocksPerFunction = 19865d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt; 19875d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth llvm::errs() << NumFunctionsAnalyzed << " functions analyzed (" 19885d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << NumFunctionsWithBadCFGs << " w/o CFGs).\n" 19895d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << NumCFGBlocks << " CFG blocks built.\n" 19905d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << AvgCFGBlocksPerFunction 19915d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " average CFG blocks per function.\n" 19925d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << MaxCFGBlocksPerFunction 19935d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " max CFG blocks per function.\n"; 19945d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 19955d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0 19965d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth : NumUninitAnalysisVariables/NumUninitAnalysisFunctions; 19975d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0 19985d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions; 19995d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth llvm::errs() << NumUninitAnalysisFunctions 20005d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " functions analyzed for uninitialiazed variables\n" 20015d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << NumUninitAnalysisVariables << " variables analyzed.\n" 20025d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << AvgUninitVariablesPerFunction 20035d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " average variables per function.\n" 20045d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << MaxUninitAnalysisVariablesPerFunction 20055d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " max variables per function.\n" 20065d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << NumUninitAnalysisBlockVisits << " block visits.\n" 20075d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << AvgUninitBlockVisitsPerFunction 20085d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " average block visits per function.\n" 20095d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " " << MaxUninitAnalysisBlockVisitsPerFunction 20105d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth << " max block visits per function.\n"; 20115d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth} 2012