AnalysisBasedWarnings.cpp revision 8a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9b
1//=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis -*- C++ -*-=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines analysis_warnings::[Policy,Executor]. 11// Together they are used by Sema to issue warnings based on inexpensive 12// static analysis algorithms in libAnalysis. 13// 14//===----------------------------------------------------------------------===// 15 16#include "clang/Sema/AnalysisBasedWarnings.h" 17#include "clang/AST/DeclCXX.h" 18#include "clang/AST/DeclObjC.h" 19#include "clang/AST/EvaluatedExprVisitor.h" 20#include "clang/AST/ExprCXX.h" 21#include "clang/AST/ExprObjC.h" 22#include "clang/AST/ParentMap.h" 23#include "clang/AST/RecursiveASTVisitor.h" 24#include "clang/AST/StmtCXX.h" 25#include "clang/AST/StmtObjC.h" 26#include "clang/AST/StmtVisitor.h" 27#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h" 28#include "clang/Analysis/Analyses/Consumed.h" 29#include "clang/Analysis/Analyses/ReachableCode.h" 30#include "clang/Analysis/Analyses/ThreadSafety.h" 31#include "clang/Analysis/Analyses/UninitializedValues.h" 32#include "clang/Analysis/AnalysisContext.h" 33#include "clang/Analysis/CFG.h" 34#include "clang/Analysis/CFGStmtMap.h" 35#include "clang/Basic/SourceLocation.h" 36#include "clang/Basic/SourceManager.h" 37#include "clang/Lex/Lexer.h" 38#include "clang/Lex/Preprocessor.h" 39#include "clang/Sema/ScopeInfo.h" 40#include "clang/Sema/SemaInternal.h" 41#include "llvm/ADT/ArrayRef.h" 42#include "llvm/ADT/BitVector.h" 43#include "llvm/ADT/FoldingSet.h" 44#include "llvm/ADT/ImmutableMap.h" 45#include "llvm/ADT/MapVector.h" 46#include "llvm/ADT/PostOrderIterator.h" 47#include "llvm/ADT/SmallString.h" 48#include "llvm/ADT/SmallVector.h" 49#include "llvm/ADT/StringRef.h" 50#include "llvm/Support/Casting.h" 51#include <algorithm> 52#include <deque> 53#include <iterator> 54#include <vector> 55 56using namespace clang; 57 58//===----------------------------------------------------------------------===// 59// Unreachable code analysis. 60//===----------------------------------------------------------------------===// 61 62namespace { 63 class UnreachableCodeHandler : public reachable_code::Callback { 64 Sema &S; 65 public: 66 UnreachableCodeHandler(Sema &s) : S(s) {} 67 68 void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) { 69 S.Diag(L, diag::warn_unreachable) << R1 << R2; 70 } 71 }; 72} 73 74/// CheckUnreachable - Check for unreachable code. 75static void CheckUnreachable(Sema &S, AnalysisDeclContext &AC) { 76 UnreachableCodeHandler UC(S); 77 reachable_code::FindUnreachableCode(AC, UC); 78} 79 80//===----------------------------------------------------------------------===// 81// Check for missing return value. 82//===----------------------------------------------------------------------===// 83 84enum ControlFlowKind { 85 UnknownFallThrough, 86 NeverFallThrough, 87 MaybeFallThrough, 88 AlwaysFallThrough, 89 NeverFallThroughOrReturn 90}; 91 92/// CheckFallThrough - Check that we don't fall off the end of a 93/// Statement that should return a value. 94/// 95/// \returns AlwaysFallThrough iff we always fall off the end of the statement, 96/// MaybeFallThrough iff we might or might not fall off the end, 97/// NeverFallThroughOrReturn iff we never fall off the end of the statement or 98/// return. We assume NeverFallThrough iff we never fall off the end of the 99/// statement but we may return. We assume that functions not marked noreturn 100/// will return. 101static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) { 102 CFG *cfg = AC.getCFG(); 103 if (cfg == 0) return UnknownFallThrough; 104 105 // The CFG leaves in dead things, and we don't want the dead code paths to 106 // confuse us, so we mark all live things first. 107 llvm::BitVector live(cfg->getNumBlockIDs()); 108 unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(), 109 live); 110 111 bool AddEHEdges = AC.getAddEHEdges(); 112 if (!AddEHEdges && count != cfg->getNumBlockIDs()) 113 // When there are things remaining dead, and we didn't add EH edges 114 // from CallExprs to the catch clauses, we have to go back and 115 // mark them as live. 116 for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) { 117 CFGBlock &b = **I; 118 if (!live[b.getBlockID()]) { 119 if (b.pred_begin() == b.pred_end()) { 120 if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator())) 121 // When not adding EH edges from calls, catch clauses 122 // can otherwise seem dead. Avoid noting them as dead. 123 count += reachable_code::ScanReachableFromBlock(&b, live); 124 continue; 125 } 126 } 127 } 128 129 // Now we know what is live, we check the live precessors of the exit block 130 // and look for fall through paths, being careful to ignore normal returns, 131 // and exceptional paths. 132 bool HasLiveReturn = false; 133 bool HasFakeEdge = false; 134 bool HasPlainEdge = false; 135 bool HasAbnormalEdge = false; 136 137 // Ignore default cases that aren't likely to be reachable because all 138 // enums in a switch(X) have explicit case statements. 139 CFGBlock::FilterOptions FO; 140 FO.IgnoreDefaultsWithCoveredEnums = 1; 141 142 for (CFGBlock::filtered_pred_iterator 143 I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) { 144 const CFGBlock& B = **I; 145 if (!live[B.getBlockID()]) 146 continue; 147 148 // Skip blocks which contain an element marked as no-return. They don't 149 // represent actually viable edges into the exit block, so mark them as 150 // abnormal. 151 if (B.hasNoReturnElement()) { 152 HasAbnormalEdge = true; 153 continue; 154 } 155 156 // Destructors can appear after the 'return' in the CFG. This is 157 // normal. We need to look pass the destructors for the return 158 // statement (if it exists). 159 CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend(); 160 161 for ( ; ri != re ; ++ri) 162 if (ri->getAs<CFGStmt>()) 163 break; 164 165 // No more CFGElements in the block? 166 if (ri == re) { 167 if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) { 168 HasAbnormalEdge = true; 169 continue; 170 } 171 // A labeled empty statement, or the entry block... 172 HasPlainEdge = true; 173 continue; 174 } 175 176 CFGStmt CS = ri->castAs<CFGStmt>(); 177 const Stmt *S = CS.getStmt(); 178 if (isa<ReturnStmt>(S)) { 179 HasLiveReturn = true; 180 continue; 181 } 182 if (isa<ObjCAtThrowStmt>(S)) { 183 HasFakeEdge = true; 184 continue; 185 } 186 if (isa<CXXThrowExpr>(S)) { 187 HasFakeEdge = true; 188 continue; 189 } 190 if (isa<MSAsmStmt>(S)) { 191 // TODO: Verify this is correct. 192 HasFakeEdge = true; 193 HasLiveReturn = true; 194 continue; 195 } 196 if (isa<CXXTryStmt>(S)) { 197 HasAbnormalEdge = true; 198 continue; 199 } 200 if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit()) 201 == B.succ_end()) { 202 HasAbnormalEdge = true; 203 continue; 204 } 205 206 HasPlainEdge = true; 207 } 208 if (!HasPlainEdge) { 209 if (HasLiveReturn) 210 return NeverFallThrough; 211 return NeverFallThroughOrReturn; 212 } 213 if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn) 214 return MaybeFallThrough; 215 // This says AlwaysFallThrough for calls to functions that are not marked 216 // noreturn, that don't return. If people would like this warning to be more 217 // accurate, such functions should be marked as noreturn. 218 return AlwaysFallThrough; 219} 220 221namespace { 222 223struct CheckFallThroughDiagnostics { 224 unsigned diag_MaybeFallThrough_HasNoReturn; 225 unsigned diag_MaybeFallThrough_ReturnsNonVoid; 226 unsigned diag_AlwaysFallThrough_HasNoReturn; 227 unsigned diag_AlwaysFallThrough_ReturnsNonVoid; 228 unsigned diag_NeverFallThroughOrReturn; 229 enum { Function, Block, Lambda } funMode; 230 SourceLocation FuncLoc; 231 232 static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { 233 CheckFallThroughDiagnostics D; 234 D.FuncLoc = Func->getLocation(); 235 D.diag_MaybeFallThrough_HasNoReturn = 236 diag::warn_falloff_noreturn_function; 237 D.diag_MaybeFallThrough_ReturnsNonVoid = 238 diag::warn_maybe_falloff_nonvoid_function; 239 D.diag_AlwaysFallThrough_HasNoReturn = 240 diag::warn_falloff_noreturn_function; 241 D.diag_AlwaysFallThrough_ReturnsNonVoid = 242 diag::warn_falloff_nonvoid_function; 243 244 // Don't suggest that virtual functions be marked "noreturn", since they 245 // might be overridden by non-noreturn functions. 246 bool isVirtualMethod = false; 247 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func)) 248 isVirtualMethod = Method->isVirtual(); 249 250 // Don't suggest that template instantiations be marked "noreturn" 251 bool isTemplateInstantiation = false; 252 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func)) 253 isTemplateInstantiation = Function->isTemplateInstantiation(); 254 255 if (!isVirtualMethod && !isTemplateInstantiation) 256 D.diag_NeverFallThroughOrReturn = 257 diag::warn_suggest_noreturn_function; 258 else 259 D.diag_NeverFallThroughOrReturn = 0; 260 261 D.funMode = Function; 262 return D; 263 } 264 265 static CheckFallThroughDiagnostics MakeForBlock() { 266 CheckFallThroughDiagnostics D; 267 D.diag_MaybeFallThrough_HasNoReturn = 268 diag::err_noreturn_block_has_return_expr; 269 D.diag_MaybeFallThrough_ReturnsNonVoid = 270 diag::err_maybe_falloff_nonvoid_block; 271 D.diag_AlwaysFallThrough_HasNoReturn = 272 diag::err_noreturn_block_has_return_expr; 273 D.diag_AlwaysFallThrough_ReturnsNonVoid = 274 diag::err_falloff_nonvoid_block; 275 D.diag_NeverFallThroughOrReturn = 276 diag::warn_suggest_noreturn_block; 277 D.funMode = Block; 278 return D; 279 } 280 281 static CheckFallThroughDiagnostics MakeForLambda() { 282 CheckFallThroughDiagnostics D; 283 D.diag_MaybeFallThrough_HasNoReturn = 284 diag::err_noreturn_lambda_has_return_expr; 285 D.diag_MaybeFallThrough_ReturnsNonVoid = 286 diag::warn_maybe_falloff_nonvoid_lambda; 287 D.diag_AlwaysFallThrough_HasNoReturn = 288 diag::err_noreturn_lambda_has_return_expr; 289 D.diag_AlwaysFallThrough_ReturnsNonVoid = 290 diag::warn_falloff_nonvoid_lambda; 291 D.diag_NeverFallThroughOrReturn = 0; 292 D.funMode = Lambda; 293 return D; 294 } 295 296 bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid, 297 bool HasNoReturn) const { 298 if (funMode == Function) { 299 return (ReturnsVoid || 300 D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function, 301 FuncLoc) == DiagnosticsEngine::Ignored) 302 && (!HasNoReturn || 303 D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr, 304 FuncLoc) == DiagnosticsEngine::Ignored) 305 && (!ReturnsVoid || 306 D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 307 == DiagnosticsEngine::Ignored); 308 } 309 310 // For blocks / lambdas. 311 return ReturnsVoid && !HasNoReturn 312 && ((funMode == Lambda) || 313 D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 314 == DiagnosticsEngine::Ignored); 315 } 316}; 317 318} 319 320/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a 321/// function that should return a value. Check that we don't fall off the end 322/// of a noreturn function. We assume that functions and blocks not marked 323/// noreturn will return. 324static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, 325 const BlockExpr *blkExpr, 326 const CheckFallThroughDiagnostics& CD, 327 AnalysisDeclContext &AC) { 328 329 bool ReturnsVoid = false; 330 bool HasNoReturn = false; 331 332 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 333 ReturnsVoid = FD->getResultType()->isVoidType(); 334 HasNoReturn = FD->isNoReturn(); 335 } 336 else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 337 ReturnsVoid = MD->getResultType()->isVoidType(); 338 HasNoReturn = MD->hasAttr<NoReturnAttr>(); 339 } 340 else if (isa<BlockDecl>(D)) { 341 QualType BlockTy = blkExpr->getType(); 342 if (const FunctionType *FT = 343 BlockTy->getPointeeType()->getAs<FunctionType>()) { 344 if (FT->getResultType()->isVoidType()) 345 ReturnsVoid = true; 346 if (FT->getNoReturnAttr()) 347 HasNoReturn = true; 348 } 349 } 350 351 DiagnosticsEngine &Diags = S.getDiagnostics(); 352 353 // Short circuit for compilation speed. 354 if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn)) 355 return; 356 357 // FIXME: Function try block 358 if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { 359 switch (CheckFallThrough(AC)) { 360 case UnknownFallThrough: 361 break; 362 363 case MaybeFallThrough: 364 if (HasNoReturn) 365 S.Diag(Compound->getRBracLoc(), 366 CD.diag_MaybeFallThrough_HasNoReturn); 367 else if (!ReturnsVoid) 368 S.Diag(Compound->getRBracLoc(), 369 CD.diag_MaybeFallThrough_ReturnsNonVoid); 370 break; 371 case AlwaysFallThrough: 372 if (HasNoReturn) 373 S.Diag(Compound->getRBracLoc(), 374 CD.diag_AlwaysFallThrough_HasNoReturn); 375 else if (!ReturnsVoid) 376 S.Diag(Compound->getRBracLoc(), 377 CD.diag_AlwaysFallThrough_ReturnsNonVoid); 378 break; 379 case NeverFallThroughOrReturn: 380 if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) { 381 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 382 S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn) 383 << 0 << FD; 384 } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 385 S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn) 386 << 1 << MD; 387 } else { 388 S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn); 389 } 390 } 391 break; 392 case NeverFallThrough: 393 break; 394 } 395 } 396} 397 398//===----------------------------------------------------------------------===// 399// -Wuninitialized 400//===----------------------------------------------------------------------===// 401 402namespace { 403/// ContainsReference - A visitor class to search for references to 404/// a particular declaration (the needle) within any evaluated component of an 405/// expression (recursively). 406class ContainsReference : public EvaluatedExprVisitor<ContainsReference> { 407 bool FoundReference; 408 const DeclRefExpr *Needle; 409 410public: 411 ContainsReference(ASTContext &Context, const DeclRefExpr *Needle) 412 : EvaluatedExprVisitor<ContainsReference>(Context), 413 FoundReference(false), Needle(Needle) {} 414 415 void VisitExpr(Expr *E) { 416 // Stop evaluating if we already have a reference. 417 if (FoundReference) 418 return; 419 420 EvaluatedExprVisitor<ContainsReference>::VisitExpr(E); 421 } 422 423 void VisitDeclRefExpr(DeclRefExpr *E) { 424 if (E == Needle) 425 FoundReference = true; 426 else 427 EvaluatedExprVisitor<ContainsReference>::VisitDeclRefExpr(E); 428 } 429 430 bool doesContainReference() const { return FoundReference; } 431}; 432} 433 434static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) { 435 QualType VariableTy = VD->getType().getCanonicalType(); 436 if (VariableTy->isBlockPointerType() && 437 !VD->hasAttr<BlocksAttr>()) { 438 S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization) << VD->getDeclName() 439 << FixItHint::CreateInsertion(VD->getLocation(), "__block "); 440 return true; 441 } 442 443 // Don't issue a fixit if there is already an initializer. 444 if (VD->getInit()) 445 return false; 446 447 // Suggest possible initialization (if any). 448 std::string Init = S.getFixItZeroInitializerForType(VariableTy); 449 if (Init.empty()) 450 return false; 451 452 // Don't suggest a fixit inside macros. 453 if (VD->getLocEnd().isMacroID()) 454 return false; 455 456 SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd()); 457 458 S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName() 459 << FixItHint::CreateInsertion(Loc, Init); 460 return true; 461} 462 463/// Create a fixit to remove an if-like statement, on the assumption that its 464/// condition is CondVal. 465static void CreateIfFixit(Sema &S, const Stmt *If, const Stmt *Then, 466 const Stmt *Else, bool CondVal, 467 FixItHint &Fixit1, FixItHint &Fixit2) { 468 if (CondVal) { 469 // If condition is always true, remove all but the 'then'. 470 Fixit1 = FixItHint::CreateRemoval( 471 CharSourceRange::getCharRange(If->getLocStart(), 472 Then->getLocStart())); 473 if (Else) { 474 SourceLocation ElseKwLoc = Lexer::getLocForEndOfToken( 475 Then->getLocEnd(), 0, S.getSourceManager(), S.getLangOpts()); 476 Fixit2 = FixItHint::CreateRemoval( 477 SourceRange(ElseKwLoc, Else->getLocEnd())); 478 } 479 } else { 480 // If condition is always false, remove all but the 'else'. 481 if (Else) 482 Fixit1 = FixItHint::CreateRemoval( 483 CharSourceRange::getCharRange(If->getLocStart(), 484 Else->getLocStart())); 485 else 486 Fixit1 = FixItHint::CreateRemoval(If->getSourceRange()); 487 } 488} 489 490/// DiagUninitUse -- Helper function to produce a diagnostic for an 491/// uninitialized use of a variable. 492static void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use, 493 bool IsCapturedByBlock) { 494 bool Diagnosed = false; 495 496 switch (Use.getKind()) { 497 case UninitUse::Always: 498 S.Diag(Use.getUser()->getLocStart(), diag::warn_uninit_var) 499 << VD->getDeclName() << IsCapturedByBlock 500 << Use.getUser()->getSourceRange(); 501 return; 502 503 case UninitUse::AfterDecl: 504 case UninitUse::AfterCall: 505 S.Diag(VD->getLocation(), diag::warn_sometimes_uninit_var) 506 << VD->getDeclName() << IsCapturedByBlock 507 << (Use.getKind() == UninitUse::AfterDecl ? 4 : 5) 508 << const_cast<DeclContext*>(VD->getLexicalDeclContext()) 509 << VD->getSourceRange(); 510 S.Diag(Use.getUser()->getLocStart(), diag::note_uninit_var_use) 511 << IsCapturedByBlock << Use.getUser()->getSourceRange(); 512 return; 513 514 case UninitUse::Maybe: 515 case UninitUse::Sometimes: 516 // Carry on to report sometimes-uninitialized branches, if possible, 517 // or a 'may be used uninitialized' diagnostic otherwise. 518 break; 519 } 520 521 // Diagnose each branch which leads to a sometimes-uninitialized use. 522 for (UninitUse::branch_iterator I = Use.branch_begin(), E = Use.branch_end(); 523 I != E; ++I) { 524 assert(Use.getKind() == UninitUse::Sometimes); 525 526 const Expr *User = Use.getUser(); 527 const Stmt *Term = I->Terminator; 528 529 // Information used when building the diagnostic. 530 unsigned DiagKind; 531 StringRef Str; 532 SourceRange Range; 533 534 // FixIts to suppress the diagnostic by removing the dead condition. 535 // For all binary terminators, branch 0 is taken if the condition is true, 536 // and branch 1 is taken if the condition is false. 537 int RemoveDiagKind = -1; 538 const char *FixitStr = 539 S.getLangOpts().CPlusPlus ? (I->Output ? "true" : "false") 540 : (I->Output ? "1" : "0"); 541 FixItHint Fixit1, Fixit2; 542 543 switch (Term ? Term->getStmtClass() : Stmt::DeclStmtClass) { 544 default: 545 // Don't know how to report this. Just fall back to 'may be used 546 // uninitialized'. FIXME: Can this happen? 547 continue; 548 549 // "condition is true / condition is false". 550 case Stmt::IfStmtClass: { 551 const IfStmt *IS = cast<IfStmt>(Term); 552 DiagKind = 0; 553 Str = "if"; 554 Range = IS->getCond()->getSourceRange(); 555 RemoveDiagKind = 0; 556 CreateIfFixit(S, IS, IS->getThen(), IS->getElse(), 557 I->Output, Fixit1, Fixit2); 558 break; 559 } 560 case Stmt::ConditionalOperatorClass: { 561 const ConditionalOperator *CO = cast<ConditionalOperator>(Term); 562 DiagKind = 0; 563 Str = "?:"; 564 Range = CO->getCond()->getSourceRange(); 565 RemoveDiagKind = 0; 566 CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(), 567 I->Output, Fixit1, Fixit2); 568 break; 569 } 570 case Stmt::BinaryOperatorClass: { 571 const BinaryOperator *BO = cast<BinaryOperator>(Term); 572 if (!BO->isLogicalOp()) 573 continue; 574 DiagKind = 0; 575 Str = BO->getOpcodeStr(); 576 Range = BO->getLHS()->getSourceRange(); 577 RemoveDiagKind = 0; 578 if ((BO->getOpcode() == BO_LAnd && I->Output) || 579 (BO->getOpcode() == BO_LOr && !I->Output)) 580 // true && y -> y, false || y -> y. 581 Fixit1 = FixItHint::CreateRemoval(SourceRange(BO->getLocStart(), 582 BO->getOperatorLoc())); 583 else 584 // false && y -> false, true || y -> true. 585 Fixit1 = FixItHint::CreateReplacement(BO->getSourceRange(), FixitStr); 586 break; 587 } 588 589 // "loop is entered / loop is exited". 590 case Stmt::WhileStmtClass: 591 DiagKind = 1; 592 Str = "while"; 593 Range = cast<WhileStmt>(Term)->getCond()->getSourceRange(); 594 RemoveDiagKind = 1; 595 Fixit1 = FixItHint::CreateReplacement(Range, FixitStr); 596 break; 597 case Stmt::ForStmtClass: 598 DiagKind = 1; 599 Str = "for"; 600 Range = cast<ForStmt>(Term)->getCond()->getSourceRange(); 601 RemoveDiagKind = 1; 602 if (I->Output) 603 Fixit1 = FixItHint::CreateRemoval(Range); 604 else 605 Fixit1 = FixItHint::CreateReplacement(Range, FixitStr); 606 break; 607 case Stmt::CXXForRangeStmtClass: 608 if (I->Output == 1) { 609 // The use occurs if a range-based for loop's body never executes. 610 // That may be impossible, and there's no syntactic fix for this, 611 // so treat it as a 'may be uninitialized' case. 612 continue; 613 } 614 DiagKind = 1; 615 Str = "for"; 616 Range = cast<CXXForRangeStmt>(Term)->getRangeInit()->getSourceRange(); 617 break; 618 619 // "condition is true / loop is exited". 620 case Stmt::DoStmtClass: 621 DiagKind = 2; 622 Str = "do"; 623 Range = cast<DoStmt>(Term)->getCond()->getSourceRange(); 624 RemoveDiagKind = 1; 625 Fixit1 = FixItHint::CreateReplacement(Range, FixitStr); 626 break; 627 628 // "switch case is taken". 629 case Stmt::CaseStmtClass: 630 DiagKind = 3; 631 Str = "case"; 632 Range = cast<CaseStmt>(Term)->getLHS()->getSourceRange(); 633 break; 634 case Stmt::DefaultStmtClass: 635 DiagKind = 3; 636 Str = "default"; 637 Range = cast<DefaultStmt>(Term)->getDefaultLoc(); 638 break; 639 } 640 641 S.Diag(Range.getBegin(), diag::warn_sometimes_uninit_var) 642 << VD->getDeclName() << IsCapturedByBlock << DiagKind 643 << Str << I->Output << Range; 644 S.Diag(User->getLocStart(), diag::note_uninit_var_use) 645 << IsCapturedByBlock << User->getSourceRange(); 646 if (RemoveDiagKind != -1) 647 S.Diag(Fixit1.RemoveRange.getBegin(), diag::note_uninit_fixit_remove_cond) 648 << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2; 649 650 Diagnosed = true; 651 } 652 653 if (!Diagnosed) 654 S.Diag(Use.getUser()->getLocStart(), diag::warn_maybe_uninit_var) 655 << VD->getDeclName() << IsCapturedByBlock 656 << Use.getUser()->getSourceRange(); 657} 658 659/// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an 660/// uninitialized variable. This manages the different forms of diagnostic 661/// emitted for particular types of uses. Returns true if the use was diagnosed 662/// as a warning. If a particular use is one we omit warnings for, returns 663/// false. 664static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD, 665 const UninitUse &Use, 666 bool alwaysReportSelfInit = false) { 667 668 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Use.getUser())) { 669 // Inspect the initializer of the variable declaration which is 670 // being referenced prior to its initialization. We emit 671 // specialized diagnostics for self-initialization, and we 672 // specifically avoid warning about self references which take the 673 // form of: 674 // 675 // int x = x; 676 // 677 // This is used to indicate to GCC that 'x' is intentionally left 678 // uninitialized. Proven code paths which access 'x' in 679 // an uninitialized state after this will still warn. 680 if (const Expr *Initializer = VD->getInit()) { 681 if (!alwaysReportSelfInit && DRE == Initializer->IgnoreParenImpCasts()) 682 return false; 683 684 ContainsReference CR(S.Context, DRE); 685 CR.Visit(const_cast<Expr*>(Initializer)); 686 if (CR.doesContainReference()) { 687 S.Diag(DRE->getLocStart(), 688 diag::warn_uninit_self_reference_in_init) 689 << VD->getDeclName() << VD->getLocation() << DRE->getSourceRange(); 690 return true; 691 } 692 } 693 694 DiagUninitUse(S, VD, Use, false); 695 } else { 696 const BlockExpr *BE = cast<BlockExpr>(Use.getUser()); 697 if (VD->getType()->isBlockPointerType() && !VD->hasAttr<BlocksAttr>()) 698 S.Diag(BE->getLocStart(), 699 diag::warn_uninit_byref_blockvar_captured_by_block) 700 << VD->getDeclName(); 701 else 702 DiagUninitUse(S, VD, Use, true); 703 } 704 705 // Report where the variable was declared when the use wasn't within 706 // the initializer of that declaration & we didn't already suggest 707 // an initialization fixit. 708 if (!SuggestInitializationFixit(S, VD)) 709 S.Diag(VD->getLocStart(), diag::note_uninit_var_def) 710 << VD->getDeclName(); 711 712 return true; 713} 714 715namespace { 716 class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> { 717 public: 718 FallthroughMapper(Sema &S) 719 : FoundSwitchStatements(false), 720 S(S) { 721 } 722 723 bool foundSwitchStatements() const { return FoundSwitchStatements; } 724 725 void markFallthroughVisited(const AttributedStmt *Stmt) { 726 bool Found = FallthroughStmts.erase(Stmt); 727 assert(Found); 728 (void)Found; 729 } 730 731 typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts; 732 733 const AttrStmts &getFallthroughStmts() const { 734 return FallthroughStmts; 735 } 736 737 void fillReachableBlocks(CFG *Cfg) { 738 assert(ReachableBlocks.empty() && "ReachableBlocks already filled"); 739 std::deque<const CFGBlock *> BlockQueue; 740 741 ReachableBlocks.insert(&Cfg->getEntry()); 742 BlockQueue.push_back(&Cfg->getEntry()); 743 // Mark all case blocks reachable to avoid problems with switching on 744 // constants, covered enums, etc. 745 // These blocks can contain fall-through annotations, and we don't want to 746 // issue a warn_fallthrough_attr_unreachable for them. 747 for (CFG::iterator I = Cfg->begin(), E = Cfg->end(); I != E; ++I) { 748 const CFGBlock *B = *I; 749 const Stmt *L = B->getLabel(); 750 if (L && isa<SwitchCase>(L) && ReachableBlocks.insert(B)) 751 BlockQueue.push_back(B); 752 } 753 754 while (!BlockQueue.empty()) { 755 const CFGBlock *P = BlockQueue.front(); 756 BlockQueue.pop_front(); 757 for (CFGBlock::const_succ_iterator I = P->succ_begin(), 758 E = P->succ_end(); 759 I != E; ++I) { 760 if (*I && ReachableBlocks.insert(*I)) 761 BlockQueue.push_back(*I); 762 } 763 } 764 } 765 766 bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) { 767 assert(!ReachableBlocks.empty() && "ReachableBlocks empty"); 768 769 int UnannotatedCnt = 0; 770 AnnotatedCnt = 0; 771 772 std::deque<const CFGBlock*> BlockQueue; 773 774 std::copy(B.pred_begin(), B.pred_end(), std::back_inserter(BlockQueue)); 775 776 while (!BlockQueue.empty()) { 777 const CFGBlock *P = BlockQueue.front(); 778 BlockQueue.pop_front(); 779 780 const Stmt *Term = P->getTerminator(); 781 if (Term && isa<SwitchStmt>(Term)) 782 continue; // Switch statement, good. 783 784 const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel()); 785 if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end()) 786 continue; // Previous case label has no statements, good. 787 788 const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel()); 789 if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end()) 790 continue; // Case label is preceded with a normal label, good. 791 792 if (!ReachableBlocks.count(P)) { 793 for (CFGBlock::const_reverse_iterator ElemIt = P->rbegin(), 794 ElemEnd = P->rend(); 795 ElemIt != ElemEnd; ++ElemIt) { 796 if (Optional<CFGStmt> CS = ElemIt->getAs<CFGStmt>()) { 797 if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) { 798 S.Diag(AS->getLocStart(), 799 diag::warn_fallthrough_attr_unreachable); 800 markFallthroughVisited(AS); 801 ++AnnotatedCnt; 802 break; 803 } 804 // Don't care about other unreachable statements. 805 } 806 } 807 // If there are no unreachable statements, this may be a special 808 // case in CFG: 809 // case X: { 810 // A a; // A has a destructor. 811 // break; 812 // } 813 // // <<<< This place is represented by a 'hanging' CFG block. 814 // case Y: 815 continue; 816 } 817 818 const Stmt *LastStmt = getLastStmt(*P); 819 if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) { 820 markFallthroughVisited(AS); 821 ++AnnotatedCnt; 822 continue; // Fallthrough annotation, good. 823 } 824 825 if (!LastStmt) { // This block contains no executable statements. 826 // Traverse its predecessors. 827 std::copy(P->pred_begin(), P->pred_end(), 828 std::back_inserter(BlockQueue)); 829 continue; 830 } 831 832 ++UnannotatedCnt; 833 } 834 return !!UnannotatedCnt; 835 } 836 837 // RecursiveASTVisitor setup. 838 bool shouldWalkTypesOfTypeLocs() const { return false; } 839 840 bool VisitAttributedStmt(AttributedStmt *S) { 841 if (asFallThroughAttr(S)) 842 FallthroughStmts.insert(S); 843 return true; 844 } 845 846 bool VisitSwitchStmt(SwitchStmt *S) { 847 FoundSwitchStatements = true; 848 return true; 849 } 850 851 // We don't want to traverse local type declarations. We analyze their 852 // methods separately. 853 bool TraverseDecl(Decl *D) { return true; } 854 855 private: 856 857 static const AttributedStmt *asFallThroughAttr(const Stmt *S) { 858 if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) { 859 if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs())) 860 return AS; 861 } 862 return 0; 863 } 864 865 static const Stmt *getLastStmt(const CFGBlock &B) { 866 if (const Stmt *Term = B.getTerminator()) 867 return Term; 868 for (CFGBlock::const_reverse_iterator ElemIt = B.rbegin(), 869 ElemEnd = B.rend(); 870 ElemIt != ElemEnd; ++ElemIt) { 871 if (Optional<CFGStmt> CS = ElemIt->getAs<CFGStmt>()) 872 return CS->getStmt(); 873 } 874 // Workaround to detect a statement thrown out by CFGBuilder: 875 // case X: {} case Y: 876 // case X: ; case Y: 877 if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel())) 878 if (!isa<SwitchCase>(SW->getSubStmt())) 879 return SW->getSubStmt(); 880 881 return 0; 882 } 883 884 bool FoundSwitchStatements; 885 AttrStmts FallthroughStmts; 886 Sema &S; 887 llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks; 888 }; 889} 890 891static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC, 892 bool PerFunction) { 893 // Only perform this analysis when using C++11. There is no good workflow 894 // for this warning when not using C++11. There is no good way to silence 895 // the warning (no attribute is available) unless we are using C++11's support 896 // for generalized attributes. Once could use pragmas to silence the warning, 897 // but as a general solution that is gross and not in the spirit of this 898 // warning. 899 // 900 // NOTE: This an intermediate solution. There are on-going discussions on 901 // how to properly support this warning outside of C++11 with an annotation. 902 if (!AC.getASTContext().getLangOpts().CPlusPlus11) 903 return; 904 905 FallthroughMapper FM(S); 906 FM.TraverseStmt(AC.getBody()); 907 908 if (!FM.foundSwitchStatements()) 909 return; 910 911 if (PerFunction && FM.getFallthroughStmts().empty()) 912 return; 913 914 CFG *Cfg = AC.getCFG(); 915 916 if (!Cfg) 917 return; 918 919 FM.fillReachableBlocks(Cfg); 920 921 for (CFG::reverse_iterator I = Cfg->rbegin(), E = Cfg->rend(); I != E; ++I) { 922 const CFGBlock *B = *I; 923 const Stmt *Label = B->getLabel(); 924 925 if (!Label || !isa<SwitchCase>(Label)) 926 continue; 927 928 int AnnotatedCnt; 929 930 if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt)) 931 continue; 932 933 S.Diag(Label->getLocStart(), 934 PerFunction ? diag::warn_unannotated_fallthrough_per_function 935 : diag::warn_unannotated_fallthrough); 936 937 if (!AnnotatedCnt) { 938 SourceLocation L = Label->getLocStart(); 939 if (L.isMacroID()) 940 continue; 941 if (S.getLangOpts().CPlusPlus11) { 942 const Stmt *Term = B->getTerminator(); 943 // Skip empty cases. 944 while (B->empty() && !Term && B->succ_size() == 1) { 945 B = *B->succ_begin(); 946 Term = B->getTerminator(); 947 } 948 if (!(B->empty() && Term && isa<BreakStmt>(Term))) { 949 Preprocessor &PP = S.getPreprocessor(); 950 TokenValue Tokens[] = { 951 tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"), 952 tok::coloncolon, PP.getIdentifierInfo("fallthrough"), 953 tok::r_square, tok::r_square 954 }; 955 StringRef AnnotationSpelling = "[[clang::fallthrough]]"; 956 StringRef MacroName = PP.getLastMacroWithSpelling(L, Tokens); 957 if (!MacroName.empty()) 958 AnnotationSpelling = MacroName; 959 SmallString<64> TextToInsert(AnnotationSpelling); 960 TextToInsert += "; "; 961 S.Diag(L, diag::note_insert_fallthrough_fixit) << 962 AnnotationSpelling << 963 FixItHint::CreateInsertion(L, TextToInsert); 964 } 965 } 966 S.Diag(L, diag::note_insert_break_fixit) << 967 FixItHint::CreateInsertion(L, "break; "); 968 } 969 } 970 971 const FallthroughMapper::AttrStmts &Fallthroughs = FM.getFallthroughStmts(); 972 for (FallthroughMapper::AttrStmts::const_iterator I = Fallthroughs.begin(), 973 E = Fallthroughs.end(); 974 I != E; ++I) { 975 S.Diag((*I)->getLocStart(), diag::warn_fallthrough_attr_invalid_placement); 976 } 977 978} 979 980namespace { 981typedef std::pair<const Stmt *, 982 sema::FunctionScopeInfo::WeakObjectUseMap::const_iterator> 983 StmtUsesPair; 984 985class StmtUseSorter { 986 const SourceManager &SM; 987 988public: 989 explicit StmtUseSorter(const SourceManager &SM) : SM(SM) { } 990 991 bool operator()(const StmtUsesPair &LHS, const StmtUsesPair &RHS) { 992 return SM.isBeforeInTranslationUnit(LHS.first->getLocStart(), 993 RHS.first->getLocStart()); 994 } 995}; 996} 997 998static bool isInLoop(const ASTContext &Ctx, const ParentMap &PM, 999 const Stmt *S) { 1000 assert(S); 1001 1002 do { 1003 switch (S->getStmtClass()) { 1004 case Stmt::ForStmtClass: 1005 case Stmt::WhileStmtClass: 1006 case Stmt::CXXForRangeStmtClass: 1007 case Stmt::ObjCForCollectionStmtClass: 1008 return true; 1009 case Stmt::DoStmtClass: { 1010 const Expr *Cond = cast<DoStmt>(S)->getCond(); 1011 llvm::APSInt Val; 1012 if (!Cond->EvaluateAsInt(Val, Ctx)) 1013 return true; 1014 return Val.getBoolValue(); 1015 } 1016 default: 1017 break; 1018 } 1019 } while ((S = PM.getParent(S))); 1020 1021 return false; 1022} 1023 1024 1025static void diagnoseRepeatedUseOfWeak(Sema &S, 1026 const sema::FunctionScopeInfo *CurFn, 1027 const Decl *D, 1028 const ParentMap &PM) { 1029 typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy; 1030 typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap; 1031 typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector; 1032 1033 ASTContext &Ctx = S.getASTContext(); 1034 1035 const WeakObjectUseMap &WeakMap = CurFn->getWeakObjectUses(); 1036 1037 // Extract all weak objects that are referenced more than once. 1038 SmallVector<StmtUsesPair, 8> UsesByStmt; 1039 for (WeakObjectUseMap::const_iterator I = WeakMap.begin(), E = WeakMap.end(); 1040 I != E; ++I) { 1041 const WeakUseVector &Uses = I->second; 1042 1043 // Find the first read of the weak object. 1044 WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end(); 1045 for ( ; UI != UE; ++UI) { 1046 if (UI->isUnsafe()) 1047 break; 1048 } 1049 1050 // If there were only writes to this object, don't warn. 1051 if (UI == UE) 1052 continue; 1053 1054 // If there was only one read, followed by any number of writes, and the 1055 // read is not within a loop, don't warn. Additionally, don't warn in a 1056 // loop if the base object is a local variable -- local variables are often 1057 // changed in loops. 1058 if (UI == Uses.begin()) { 1059 WeakUseVector::const_iterator UI2 = UI; 1060 for (++UI2; UI2 != UE; ++UI2) 1061 if (UI2->isUnsafe()) 1062 break; 1063 1064 if (UI2 == UE) { 1065 if (!isInLoop(Ctx, PM, UI->getUseExpr())) 1066 continue; 1067 1068 const WeakObjectProfileTy &Profile = I->first; 1069 if (!Profile.isExactProfile()) 1070 continue; 1071 1072 const NamedDecl *Base = Profile.getBase(); 1073 if (!Base) 1074 Base = Profile.getProperty(); 1075 assert(Base && "A profile always has a base or property."); 1076 1077 if (const VarDecl *BaseVar = dyn_cast<VarDecl>(Base)) 1078 if (BaseVar->hasLocalStorage() && !isa<ParmVarDecl>(Base)) 1079 continue; 1080 } 1081 } 1082 1083 UsesByStmt.push_back(StmtUsesPair(UI->getUseExpr(), I)); 1084 } 1085 1086 if (UsesByStmt.empty()) 1087 return; 1088 1089 // Sort by first use so that we emit the warnings in a deterministic order. 1090 std::sort(UsesByStmt.begin(), UsesByStmt.end(), 1091 StmtUseSorter(S.getSourceManager())); 1092 1093 // Classify the current code body for better warning text. 1094 // This enum should stay in sync with the cases in 1095 // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak. 1096 // FIXME: Should we use a common classification enum and the same set of 1097 // possibilities all throughout Sema? 1098 enum { 1099 Function, 1100 Method, 1101 Block, 1102 Lambda 1103 } FunctionKind; 1104 1105 if (isa<sema::BlockScopeInfo>(CurFn)) 1106 FunctionKind = Block; 1107 else if (isa<sema::LambdaScopeInfo>(CurFn)) 1108 FunctionKind = Lambda; 1109 else if (isa<ObjCMethodDecl>(D)) 1110 FunctionKind = Method; 1111 else 1112 FunctionKind = Function; 1113 1114 // Iterate through the sorted problems and emit warnings for each. 1115 for (SmallVectorImpl<StmtUsesPair>::const_iterator I = UsesByStmt.begin(), 1116 E = UsesByStmt.end(); 1117 I != E; ++I) { 1118 const Stmt *FirstRead = I->first; 1119 const WeakObjectProfileTy &Key = I->second->first; 1120 const WeakUseVector &Uses = I->second->second; 1121 1122 // For complicated expressions like 'a.b.c' and 'x.b.c', WeakObjectProfileTy 1123 // may not contain enough information to determine that these are different 1124 // properties. We can only be 100% sure of a repeated use in certain cases, 1125 // and we adjust the diagnostic kind accordingly so that the less certain 1126 // case can be turned off if it is too noisy. 1127 unsigned DiagKind; 1128 if (Key.isExactProfile()) 1129 DiagKind = diag::warn_arc_repeated_use_of_weak; 1130 else 1131 DiagKind = diag::warn_arc_possible_repeated_use_of_weak; 1132 1133 // Classify the weak object being accessed for better warning text. 1134 // This enum should stay in sync with the cases in 1135 // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak. 1136 enum { 1137 Variable, 1138 Property, 1139 ImplicitProperty, 1140 Ivar 1141 } ObjectKind; 1142 1143 const NamedDecl *D = Key.getProperty(); 1144 if (isa<VarDecl>(D)) 1145 ObjectKind = Variable; 1146 else if (isa<ObjCPropertyDecl>(D)) 1147 ObjectKind = Property; 1148 else if (isa<ObjCMethodDecl>(D)) 1149 ObjectKind = ImplicitProperty; 1150 else if (isa<ObjCIvarDecl>(D)) 1151 ObjectKind = Ivar; 1152 else 1153 llvm_unreachable("Unexpected weak object kind!"); 1154 1155 // Show the first time the object was read. 1156 S.Diag(FirstRead->getLocStart(), DiagKind) 1157 << int(ObjectKind) << D << int(FunctionKind) 1158 << FirstRead->getSourceRange(); 1159 1160 // Print all the other accesses as notes. 1161 for (WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end(); 1162 UI != UE; ++UI) { 1163 if (UI->getUseExpr() == FirstRead) 1164 continue; 1165 S.Diag(UI->getUseExpr()->getLocStart(), 1166 diag::note_arc_weak_also_accessed_here) 1167 << UI->getUseExpr()->getSourceRange(); 1168 } 1169 } 1170} 1171 1172 1173namespace { 1174struct SLocSort { 1175 bool operator()(const UninitUse &a, const UninitUse &b) { 1176 // Prefer a more confident report over a less confident one. 1177 if (a.getKind() != b.getKind()) 1178 return a.getKind() > b.getKind(); 1179 SourceLocation aLoc = a.getUser()->getLocStart(); 1180 SourceLocation bLoc = b.getUser()->getLocStart(); 1181 return aLoc.getRawEncoding() < bLoc.getRawEncoding(); 1182 } 1183}; 1184 1185class UninitValsDiagReporter : public UninitVariablesHandler { 1186 Sema &S; 1187 typedef SmallVector<UninitUse, 2> UsesVec; 1188 typedef llvm::PointerIntPair<UsesVec *, 1, bool> MappedType; 1189 // Prefer using MapVector to DenseMap, so that iteration order will be 1190 // the same as insertion order. This is needed to obtain a deterministic 1191 // order of diagnostics when calling flushDiagnostics(). 1192 typedef llvm::MapVector<const VarDecl *, MappedType> UsesMap; 1193 UsesMap *uses; 1194 1195public: 1196 UninitValsDiagReporter(Sema &S) : S(S), uses(0) {} 1197 ~UninitValsDiagReporter() { 1198 flushDiagnostics(); 1199 } 1200 1201 MappedType &getUses(const VarDecl *vd) { 1202 if (!uses) 1203 uses = new UsesMap(); 1204 1205 MappedType &V = (*uses)[vd]; 1206 if (!V.getPointer()) 1207 V.setPointer(new UsesVec()); 1208 1209 return V; 1210 } 1211 1212 void handleUseOfUninitVariable(const VarDecl *vd, const UninitUse &use) { 1213 getUses(vd).getPointer()->push_back(use); 1214 } 1215 1216 void handleSelfInit(const VarDecl *vd) { 1217 getUses(vd).setInt(true); 1218 } 1219 1220 void flushDiagnostics() { 1221 if (!uses) 1222 return; 1223 1224 for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) { 1225 const VarDecl *vd = i->first; 1226 const MappedType &V = i->second; 1227 1228 UsesVec *vec = V.getPointer(); 1229 bool hasSelfInit = V.getInt(); 1230 1231 // Specially handle the case where we have uses of an uninitialized 1232 // variable, but the root cause is an idiomatic self-init. We want 1233 // to report the diagnostic at the self-init since that is the root cause. 1234 if (!vec->empty() && hasSelfInit && hasAlwaysUninitializedUse(vec)) 1235 DiagnoseUninitializedUse(S, vd, 1236 UninitUse(vd->getInit()->IgnoreParenCasts(), 1237 /* isAlwaysUninit */ true), 1238 /* alwaysReportSelfInit */ true); 1239 else { 1240 // Sort the uses by their SourceLocations. While not strictly 1241 // guaranteed to produce them in line/column order, this will provide 1242 // a stable ordering. 1243 std::sort(vec->begin(), vec->end(), SLocSort()); 1244 1245 for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; 1246 ++vi) { 1247 // If we have self-init, downgrade all uses to 'may be uninitialized'. 1248 UninitUse Use = hasSelfInit ? UninitUse(vi->getUser(), false) : *vi; 1249 1250 if (DiagnoseUninitializedUse(S, vd, Use)) 1251 // Skip further diagnostics for this variable. We try to warn only 1252 // on the first point at which a variable is used uninitialized. 1253 break; 1254 } 1255 } 1256 1257 // Release the uses vector. 1258 delete vec; 1259 } 1260 delete uses; 1261 } 1262 1263private: 1264 static bool hasAlwaysUninitializedUse(const UsesVec* vec) { 1265 for (UsesVec::const_iterator i = vec->begin(), e = vec->end(); i != e; ++i) { 1266 if (i->getKind() == UninitUse::Always || 1267 i->getKind() == UninitUse::AfterCall || 1268 i->getKind() == UninitUse::AfterDecl) { 1269 return true; 1270 } 1271 } 1272 return false; 1273} 1274}; 1275} 1276 1277namespace clang { 1278namespace { 1279typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes; 1280typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag; 1281typedef std::list<DelayedDiag> DiagList; 1282 1283struct SortDiagBySourceLocation { 1284 SourceManager &SM; 1285 SortDiagBySourceLocation(SourceManager &SM) : SM(SM) {} 1286 1287 bool operator()(const DelayedDiag &left, const DelayedDiag &right) { 1288 // Although this call will be slow, this is only called when outputting 1289 // multiple warnings. 1290 return SM.isBeforeInTranslationUnit(left.first.first, right.first.first); 1291 } 1292}; 1293}} 1294 1295//===----------------------------------------------------------------------===// 1296// -Wthread-safety 1297//===----------------------------------------------------------------------===// 1298namespace clang { 1299namespace thread_safety { 1300namespace { 1301class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler { 1302 Sema &S; 1303 DiagList Warnings; 1304 SourceLocation FunLocation, FunEndLocation; 1305 1306 // Helper functions 1307 void warnLockMismatch(unsigned DiagID, Name LockName, SourceLocation Loc) { 1308 // Gracefully handle rare cases when the analysis can't get a more 1309 // precise source location. 1310 if (!Loc.isValid()) 1311 Loc = FunLocation; 1312 PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << LockName); 1313 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1314 } 1315 1316 public: 1317 ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL) 1318 : S(S), FunLocation(FL), FunEndLocation(FEL) {} 1319 1320 /// \brief Emit all buffered diagnostics in order of sourcelocation. 1321 /// We need to output diagnostics produced while iterating through 1322 /// the lockset in deterministic order, so this function orders diagnostics 1323 /// and outputs them. 1324 void emitDiagnostics() { 1325 Warnings.sort(SortDiagBySourceLocation(S.getSourceManager())); 1326 for (DiagList::iterator I = Warnings.begin(), E = Warnings.end(); 1327 I != E; ++I) { 1328 S.Diag(I->first.first, I->first.second); 1329 const OptionalNotes &Notes = I->second; 1330 for (unsigned NoteI = 0, NoteN = Notes.size(); NoteI != NoteN; ++NoteI) 1331 S.Diag(Notes[NoteI].first, Notes[NoteI].second); 1332 } 1333 } 1334 1335 void handleInvalidLockExp(SourceLocation Loc) { 1336 PartialDiagnosticAt Warning(Loc, 1337 S.PDiag(diag::warn_cannot_resolve_lock) << Loc); 1338 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1339 } 1340 void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) { 1341 warnLockMismatch(diag::warn_unlock_but_no_lock, LockName, Loc); 1342 } 1343 1344 void handleDoubleLock(Name LockName, SourceLocation Loc) { 1345 warnLockMismatch(diag::warn_double_lock, LockName, Loc); 1346 } 1347 1348 void handleMutexHeldEndOfScope(Name LockName, SourceLocation LocLocked, 1349 SourceLocation LocEndOfScope, 1350 LockErrorKind LEK){ 1351 unsigned DiagID = 0; 1352 switch (LEK) { 1353 case LEK_LockedSomePredecessors: 1354 DiagID = diag::warn_lock_some_predecessors; 1355 break; 1356 case LEK_LockedSomeLoopIterations: 1357 DiagID = diag::warn_expecting_lock_held_on_loop; 1358 break; 1359 case LEK_LockedAtEndOfFunction: 1360 DiagID = diag::warn_no_unlock; 1361 break; 1362 case LEK_NotLockedAtEndOfFunction: 1363 DiagID = diag::warn_expecting_locked; 1364 break; 1365 } 1366 if (LocEndOfScope.isInvalid()) 1367 LocEndOfScope = FunEndLocation; 1368 1369 PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << LockName); 1370 if (LocLocked.isValid()) { 1371 PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here)); 1372 Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); 1373 return; 1374 } 1375 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1376 } 1377 1378 1379 void handleExclusiveAndShared(Name LockName, SourceLocation Loc1, 1380 SourceLocation Loc2) { 1381 PartialDiagnosticAt Warning( 1382 Loc1, S.PDiag(diag::warn_lock_exclusive_and_shared) << LockName); 1383 PartialDiagnosticAt Note( 1384 Loc2, S.PDiag(diag::note_lock_exclusive_and_shared) << LockName); 1385 Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); 1386 } 1387 1388 void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK, 1389 AccessKind AK, SourceLocation Loc) { 1390 assert((POK == POK_VarAccess || POK == POK_VarDereference) 1391 && "Only works for variables"); 1392 unsigned DiagID = POK == POK_VarAccess? 1393 diag::warn_variable_requires_any_lock: 1394 diag::warn_var_deref_requires_any_lock; 1395 PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) 1396 << D->getNameAsString() << getLockKindFromAccessKind(AK)); 1397 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1398 } 1399 1400 void handleMutexNotHeld(const NamedDecl *D, ProtectedOperationKind POK, 1401 Name LockName, LockKind LK, SourceLocation Loc, 1402 Name *PossibleMatch) { 1403 unsigned DiagID = 0; 1404 if (PossibleMatch) { 1405 switch (POK) { 1406 case POK_VarAccess: 1407 DiagID = diag::warn_variable_requires_lock_precise; 1408 break; 1409 case POK_VarDereference: 1410 DiagID = diag::warn_var_deref_requires_lock_precise; 1411 break; 1412 case POK_FunctionCall: 1413 DiagID = diag::warn_fun_requires_lock_precise; 1414 break; 1415 } 1416 PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) 1417 << D->getNameAsString() << LockName << LK); 1418 PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match) 1419 << *PossibleMatch); 1420 Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); 1421 } else { 1422 switch (POK) { 1423 case POK_VarAccess: 1424 DiagID = diag::warn_variable_requires_lock; 1425 break; 1426 case POK_VarDereference: 1427 DiagID = diag::warn_var_deref_requires_lock; 1428 break; 1429 case POK_FunctionCall: 1430 DiagID = diag::warn_fun_requires_lock; 1431 break; 1432 } 1433 PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) 1434 << D->getNameAsString() << LockName << LK); 1435 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1436 } 1437 } 1438 1439 void handleFunExcludesLock(Name FunName, Name LockName, SourceLocation Loc) { 1440 PartialDiagnosticAt Warning(Loc, 1441 S.PDiag(diag::warn_fun_excludes_mutex) << FunName << LockName); 1442 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1443 } 1444}; 1445} 1446} 1447} 1448 1449//===----------------------------------------------------------------------===// 1450// -Wconsumed 1451//===----------------------------------------------------------------------===// 1452 1453namespace clang { 1454namespace consumed { 1455namespace { 1456class ConsumedWarningsHandler : public ConsumedWarningsHandlerBase { 1457 1458 Sema &S; 1459 DiagList Warnings; 1460 1461public: 1462 1463 ConsumedWarningsHandler(Sema &S) : S(S) {} 1464 1465 void emitDiagnostics() { 1466 Warnings.sort(SortDiagBySourceLocation(S.getSourceManager())); 1467 1468 for (DiagList::iterator I = Warnings.begin(), E = Warnings.end(); 1469 I != E; ++I) { 1470 1471 const OptionalNotes &Notes = I->second; 1472 S.Diag(I->first.first, I->first.second); 1473 1474 for (unsigned NoteI = 0, NoteN = Notes.size(); NoteI != NoteN; ++NoteI) { 1475 S.Diag(Notes[NoteI].first, Notes[NoteI].second); 1476 } 1477 } 1478 } 1479 1480 void warnReturnTypestateForUnconsumableType(SourceLocation Loc, 1481 StringRef TypeName) { 1482 PartialDiagnosticAt Warning(Loc, S.PDiag( 1483 diag::warn_return_typestate_for_unconsumable_type) << TypeName); 1484 1485 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1486 } 1487 1488 void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState, 1489 StringRef ObservedState) { 1490 1491 PartialDiagnosticAt Warning(Loc, S.PDiag( 1492 diag::warn_return_typestate_mismatch) << ExpectedState << ObservedState); 1493 1494 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1495 } 1496 1497 void warnUnnecessaryTest(StringRef VariableName, StringRef VariableState, 1498 SourceLocation Loc) { 1499 1500 PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unnecessary_test) << 1501 VariableName << VariableState); 1502 1503 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1504 } 1505 1506 void warnUseOfTempWhileConsumed(StringRef MethodName, SourceLocation Loc) { 1507 1508 PartialDiagnosticAt Warning(Loc, S.PDiag( 1509 diag::warn_use_of_temp_while_consumed) << MethodName); 1510 1511 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1512 } 1513 1514 void warnUseOfTempInUnknownState(StringRef MethodName, SourceLocation Loc) { 1515 1516 PartialDiagnosticAt Warning(Loc, S.PDiag( 1517 diag::warn_use_of_temp_in_unknown_state) << MethodName); 1518 1519 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1520 } 1521 1522 void warnUseWhileConsumed(StringRef MethodName, StringRef VariableName, 1523 SourceLocation Loc) { 1524 1525 PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_while_consumed) << 1526 MethodName << VariableName); 1527 1528 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1529 } 1530 1531 void warnUseInUnknownState(StringRef MethodName, StringRef VariableName, 1532 SourceLocation Loc) { 1533 1534 PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_unknown_state) << 1535 MethodName << VariableName); 1536 1537 Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); 1538 } 1539}; 1540}}} 1541 1542//===----------------------------------------------------------------------===// 1543// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based 1544// warnings on a function, method, or block. 1545//===----------------------------------------------------------------------===// 1546 1547clang::sema::AnalysisBasedWarnings::Policy::Policy() { 1548 enableCheckFallThrough = 1; 1549 enableCheckUnreachable = 0; 1550 enableThreadSafetyAnalysis = 0; 1551 enableConsumedAnalysis = 0; 1552} 1553 1554clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) 1555 : S(s), 1556 NumFunctionsAnalyzed(0), 1557 NumFunctionsWithBadCFGs(0), 1558 NumCFGBlocks(0), 1559 MaxCFGBlocksPerFunction(0), 1560 NumUninitAnalysisFunctions(0), 1561 NumUninitAnalysisVariables(0), 1562 MaxUninitAnalysisVariablesPerFunction(0), 1563 NumUninitAnalysisBlockVisits(0), 1564 MaxUninitAnalysisBlockVisitsPerFunction(0) { 1565 DiagnosticsEngine &D = S.getDiagnostics(); 1566 DefaultPolicy.enableCheckUnreachable = (unsigned) 1567 (D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) != 1568 DiagnosticsEngine::Ignored); 1569 DefaultPolicy.enableThreadSafetyAnalysis = (unsigned) 1570 (D.getDiagnosticLevel(diag::warn_double_lock, SourceLocation()) != 1571 DiagnosticsEngine::Ignored); 1572 DefaultPolicy.enableConsumedAnalysis = (unsigned) 1573 (D.getDiagnosticLevel(diag::warn_use_while_consumed, SourceLocation()) != 1574 DiagnosticsEngine::Ignored); 1575} 1576 1577static void flushDiagnostics(Sema &S, sema::FunctionScopeInfo *fscope) { 1578 for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator 1579 i = fscope->PossiblyUnreachableDiags.begin(), 1580 e = fscope->PossiblyUnreachableDiags.end(); 1581 i != e; ++i) { 1582 const sema::PossiblyUnreachableDiag &D = *i; 1583 S.Diag(D.Loc, D.PD); 1584 } 1585} 1586 1587void clang::sema:: 1588AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 1589 sema::FunctionScopeInfo *fscope, 1590 const Decl *D, const BlockExpr *blkExpr) { 1591 1592 // We avoid doing analysis-based warnings when there are errors for 1593 // two reasons: 1594 // (1) The CFGs often can't be constructed (if the body is invalid), so 1595 // don't bother trying. 1596 // (2) The code already has problems; running the analysis just takes more 1597 // time. 1598 DiagnosticsEngine &Diags = S.getDiagnostics(); 1599 1600 // Do not do any analysis for declarations in system headers if we are 1601 // going to just ignore them. 1602 if (Diags.getSuppressSystemWarnings() && 1603 S.SourceMgr.isInSystemHeader(D->getLocation())) 1604 return; 1605 1606 // For code in dependent contexts, we'll do this at instantiation time. 1607 if (cast<DeclContext>(D)->isDependentContext()) 1608 return; 1609 1610 if (Diags.hasUncompilableErrorOccurred() || Diags.hasFatalErrorOccurred()) { 1611 // Flush out any possibly unreachable diagnostics. 1612 flushDiagnostics(S, fscope); 1613 return; 1614 } 1615 1616 const Stmt *Body = D->getBody(); 1617 assert(Body); 1618 1619 AnalysisDeclContext AC(/* AnalysisDeclContextManager */ 0, D); 1620 1621 // Don't generate EH edges for CallExprs as we'd like to avoid the n^2 1622 // explosion for destructors that can result and the compile time hit. 1623 AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true; 1624 AC.getCFGBuildOptions().AddEHEdges = false; 1625 AC.getCFGBuildOptions().AddInitializers = true; 1626 AC.getCFGBuildOptions().AddImplicitDtors = true; 1627 AC.getCFGBuildOptions().AddTemporaryDtors = true; 1628 1629 // Force that certain expressions appear as CFGElements in the CFG. This 1630 // is used to speed up various analyses. 1631 // FIXME: This isn't the right factoring. This is here for initial 1632 // prototyping, but we need a way for analyses to say what expressions they 1633 // expect to always be CFGElements and then fill in the BuildOptions 1634 // appropriately. This is essentially a layering violation. 1635 if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis || 1636 P.enableConsumedAnalysis) { 1637 // Unreachable code analysis and thread safety require a linearized CFG. 1638 AC.getCFGBuildOptions().setAllAlwaysAdd(); 1639 } 1640 else { 1641 AC.getCFGBuildOptions() 1642 .setAlwaysAdd(Stmt::BinaryOperatorClass) 1643 .setAlwaysAdd(Stmt::CompoundAssignOperatorClass) 1644 .setAlwaysAdd(Stmt::BlockExprClass) 1645 .setAlwaysAdd(Stmt::CStyleCastExprClass) 1646 .setAlwaysAdd(Stmt::DeclRefExprClass) 1647 .setAlwaysAdd(Stmt::ImplicitCastExprClass) 1648 .setAlwaysAdd(Stmt::UnaryOperatorClass) 1649 .setAlwaysAdd(Stmt::AttributedStmtClass); 1650 } 1651 1652 // Construct the analysis context with the specified CFG build options. 1653 1654 // Emit delayed diagnostics. 1655 if (!fscope->PossiblyUnreachableDiags.empty()) { 1656 bool analyzed = false; 1657 1658 // Register the expressions with the CFGBuilder. 1659 for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator 1660 i = fscope->PossiblyUnreachableDiags.begin(), 1661 e = fscope->PossiblyUnreachableDiags.end(); 1662 i != e; ++i) { 1663 if (const Stmt *stmt = i->stmt) 1664 AC.registerForcedBlockExpression(stmt); 1665 } 1666 1667 if (AC.getCFG()) { 1668 analyzed = true; 1669 for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator 1670 i = fscope->PossiblyUnreachableDiags.begin(), 1671 e = fscope->PossiblyUnreachableDiags.end(); 1672 i != e; ++i) 1673 { 1674 const sema::PossiblyUnreachableDiag &D = *i; 1675 bool processed = false; 1676 if (const Stmt *stmt = i->stmt) { 1677 const CFGBlock *block = AC.getBlockForRegisteredExpression(stmt); 1678 CFGReverseBlockReachabilityAnalysis *cra = 1679 AC.getCFGReachablityAnalysis(); 1680 // FIXME: We should be able to assert that block is non-null, but 1681 // the CFG analysis can skip potentially-evaluated expressions in 1682 // edge cases; see test/Sema/vla-2.c. 1683 if (block && cra) { 1684 // Can this block be reached from the entrance? 1685 if (cra->isReachable(&AC.getCFG()->getEntry(), block)) 1686 S.Diag(D.Loc, D.PD); 1687 processed = true; 1688 } 1689 } 1690 if (!processed) { 1691 // Emit the warning anyway if we cannot map to a basic block. 1692 S.Diag(D.Loc, D.PD); 1693 } 1694 } 1695 } 1696 1697 if (!analyzed) 1698 flushDiagnostics(S, fscope); 1699 } 1700 1701 1702 // Warning: check missing 'return' 1703 if (P.enableCheckFallThrough) { 1704 const CheckFallThroughDiagnostics &CD = 1705 (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock() 1706 : (isa<CXXMethodDecl>(D) && 1707 cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call && 1708 cast<CXXMethodDecl>(D)->getParent()->isLambda()) 1709 ? CheckFallThroughDiagnostics::MakeForLambda() 1710 : CheckFallThroughDiagnostics::MakeForFunction(D)); 1711 CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC); 1712 } 1713 1714 // Warning: check for unreachable code 1715 if (P.enableCheckUnreachable) { 1716 // Only check for unreachable code on non-template instantiations. 1717 // Different template instantiations can effectively change the control-flow 1718 // and it is very difficult to prove that a snippet of code in a template 1719 // is unreachable for all instantiations. 1720 bool isTemplateInstantiation = false; 1721 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) 1722 isTemplateInstantiation = Function->isTemplateInstantiation(); 1723 if (!isTemplateInstantiation) 1724 CheckUnreachable(S, AC); 1725 } 1726 1727 // Check for thread safety violations 1728 if (P.enableThreadSafetyAnalysis) { 1729 SourceLocation FL = AC.getDecl()->getLocation(); 1730 SourceLocation FEL = AC.getDecl()->getLocEnd(); 1731 thread_safety::ThreadSafetyReporter Reporter(S, FL, FEL); 1732 if (Diags.getDiagnosticLevel(diag::warn_thread_safety_beta,D->getLocStart()) 1733 != DiagnosticsEngine::Ignored) 1734 Reporter.setIssueBetaWarnings(true); 1735 1736 thread_safety::runThreadSafetyAnalysis(AC, Reporter); 1737 Reporter.emitDiagnostics(); 1738 } 1739 1740 // Check for violations of consumed properties. 1741 if (P.enableConsumedAnalysis) { 1742 consumed::ConsumedWarningsHandler WarningHandler(S); 1743 consumed::ConsumedAnalyzer Analyzer(WarningHandler); 1744 Analyzer.run(AC); 1745 } 1746 1747 if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart()) 1748 != DiagnosticsEngine::Ignored || 1749 Diags.getDiagnosticLevel(diag::warn_sometimes_uninit_var,D->getLocStart()) 1750 != DiagnosticsEngine::Ignored || 1751 Diags.getDiagnosticLevel(diag::warn_maybe_uninit_var, D->getLocStart()) 1752 != DiagnosticsEngine::Ignored) { 1753 if (CFG *cfg = AC.getCFG()) { 1754 UninitValsDiagReporter reporter(S); 1755 UninitVariablesAnalysisStats stats; 1756 std::memset(&stats, 0, sizeof(UninitVariablesAnalysisStats)); 1757 runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC, 1758 reporter, stats); 1759 1760 if (S.CollectStats && stats.NumVariablesAnalyzed > 0) { 1761 ++NumUninitAnalysisFunctions; 1762 NumUninitAnalysisVariables += stats.NumVariablesAnalyzed; 1763 NumUninitAnalysisBlockVisits += stats.NumBlockVisits; 1764 MaxUninitAnalysisVariablesPerFunction = 1765 std::max(MaxUninitAnalysisVariablesPerFunction, 1766 stats.NumVariablesAnalyzed); 1767 MaxUninitAnalysisBlockVisitsPerFunction = 1768 std::max(MaxUninitAnalysisBlockVisitsPerFunction, 1769 stats.NumBlockVisits); 1770 } 1771 } 1772 } 1773 1774 bool FallThroughDiagFull = 1775 Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough, 1776 D->getLocStart()) != DiagnosticsEngine::Ignored; 1777 bool FallThroughDiagPerFunction = 1778 Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough_per_function, 1779 D->getLocStart()) != DiagnosticsEngine::Ignored; 1780 if (FallThroughDiagFull || FallThroughDiagPerFunction) { 1781 DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull); 1782 } 1783 1784 if (S.getLangOpts().ObjCARCWeak && 1785 Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak, 1786 D->getLocStart()) != DiagnosticsEngine::Ignored) 1787 diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap()); 1788 1789 // Collect statistics about the CFG if it was built. 1790 if (S.CollectStats && AC.isCFGBuilt()) { 1791 ++NumFunctionsAnalyzed; 1792 if (CFG *cfg = AC.getCFG()) { 1793 // If we successfully built a CFG for this context, record some more 1794 // detail information about it. 1795 NumCFGBlocks += cfg->getNumBlockIDs(); 1796 MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction, 1797 cfg->getNumBlockIDs()); 1798 } else { 1799 ++NumFunctionsWithBadCFGs; 1800 } 1801 } 1802} 1803 1804void clang::sema::AnalysisBasedWarnings::PrintStats() const { 1805 llvm::errs() << "\n*** Analysis Based Warnings Stats:\n"; 1806 1807 unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs; 1808 unsigned AvgCFGBlocksPerFunction = 1809 !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt; 1810 llvm::errs() << NumFunctionsAnalyzed << " functions analyzed (" 1811 << NumFunctionsWithBadCFGs << " w/o CFGs).\n" 1812 << " " << NumCFGBlocks << " CFG blocks built.\n" 1813 << " " << AvgCFGBlocksPerFunction 1814 << " average CFG blocks per function.\n" 1815 << " " << MaxCFGBlocksPerFunction 1816 << " max CFG blocks per function.\n"; 1817 1818 unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0 1819 : NumUninitAnalysisVariables/NumUninitAnalysisFunctions; 1820 unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0 1821 : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions; 1822 llvm::errs() << NumUninitAnalysisFunctions 1823 << " functions analyzed for uninitialiazed variables\n" 1824 << " " << NumUninitAnalysisVariables << " variables analyzed.\n" 1825 << " " << AvgUninitVariablesPerFunction 1826 << " average variables per function.\n" 1827 << " " << MaxUninitAnalysisVariablesPerFunction 1828 << " max variables per function.\n" 1829 << " " << NumUninitAnalysisBlockVisits << " block visits.\n" 1830 << " " << AvgUninitBlockVisitsPerFunction 1831 << " average block visits per function.\n" 1832 << " " << MaxUninitAnalysisBlockVisitsPerFunction 1833 << " max block visits per function.\n"; 1834} 1835