AnalysisBasedWarnings.cpp revision 0d381810da19dd7677b9a79fca516d298fa5addb
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/Sema/SemaInternal.h" 18#include "clang/Sema/ScopeInfo.h" 19#include "clang/Basic/SourceManager.h" 20#include "clang/Basic/SourceLocation.h" 21#include "clang/Lex/Preprocessor.h" 22#include "clang/AST/DeclObjC.h" 23#include "clang/AST/DeclCXX.h" 24#include "clang/AST/ExprObjC.h" 25#include "clang/AST/ExprCXX.h" 26#include "clang/AST/StmtObjC.h" 27#include "clang/AST/StmtCXX.h" 28#include "clang/AST/EvaluatedExprVisitor.h" 29#include "clang/AST/StmtVisitor.h" 30#include "clang/Analysis/AnalysisContext.h" 31#include "clang/Analysis/CFG.h" 32#include "clang/Analysis/Analyses/ReachableCode.h" 33#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h" 34#include "clang/Analysis/Analyses/ThreadSafety.h" 35#include "clang/Analysis/CFGStmtMap.h" 36#include "clang/Analysis/Analyses/UninitializedValues.h" 37#include "llvm/ADT/BitVector.h" 38#include "llvm/ADT/FoldingSet.h" 39#include "llvm/ADT/ImmutableMap.h" 40#include "llvm/ADT/PostOrderIterator.h" 41#include "llvm/ADT/SmallVector.h" 42#include "llvm/ADT/StringRef.h" 43#include "llvm/Support/Casting.h" 44#include <algorithm> 45#include <vector> 46 47using namespace clang; 48 49//===----------------------------------------------------------------------===// 50// Unreachable code analysis. 51//===----------------------------------------------------------------------===// 52 53namespace { 54 class UnreachableCodeHandler : public reachable_code::Callback { 55 Sema &S; 56 public: 57 UnreachableCodeHandler(Sema &s) : S(s) {} 58 59 void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) { 60 S.Diag(L, diag::warn_unreachable) << R1 << R2; 61 } 62 }; 63} 64 65/// CheckUnreachable - Check for unreachable code. 66static void CheckUnreachable(Sema &S, AnalysisContext &AC) { 67 UnreachableCodeHandler UC(S); 68 reachable_code::FindUnreachableCode(AC, UC); 69} 70 71//===----------------------------------------------------------------------===// 72// Check for missing return value. 73//===----------------------------------------------------------------------===// 74 75enum ControlFlowKind { 76 UnknownFallThrough, 77 NeverFallThrough, 78 MaybeFallThrough, 79 AlwaysFallThrough, 80 NeverFallThroughOrReturn 81}; 82 83/// CheckFallThrough - Check that we don't fall off the end of a 84/// Statement that should return a value. 85/// 86/// \returns AlwaysFallThrough iff we always fall off the end of the statement, 87/// MaybeFallThrough iff we might or might not fall off the end, 88/// NeverFallThroughOrReturn iff we never fall off the end of the statement or 89/// return. We assume NeverFallThrough iff we never fall off the end of the 90/// statement but we may return. We assume that functions not marked noreturn 91/// will return. 92static ControlFlowKind CheckFallThrough(AnalysisContext &AC) { 93 CFG *cfg = AC.getCFG(); 94 if (cfg == 0) return UnknownFallThrough; 95 96 // The CFG leaves in dead things, and we don't want the dead code paths to 97 // confuse us, so we mark all live things first. 98 llvm::BitVector live(cfg->getNumBlockIDs()); 99 unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(), 100 live); 101 102 bool AddEHEdges = AC.getAddEHEdges(); 103 if (!AddEHEdges && count != cfg->getNumBlockIDs()) 104 // When there are things remaining dead, and we didn't add EH edges 105 // from CallExprs to the catch clauses, we have to go back and 106 // mark them as live. 107 for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) { 108 CFGBlock &b = **I; 109 if (!live[b.getBlockID()]) { 110 if (b.pred_begin() == b.pred_end()) { 111 if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator())) 112 // When not adding EH edges from calls, catch clauses 113 // can otherwise seem dead. Avoid noting them as dead. 114 count += reachable_code::ScanReachableFromBlock(&b, live); 115 continue; 116 } 117 } 118 } 119 120 // Now we know what is live, we check the live precessors of the exit block 121 // and look for fall through paths, being careful to ignore normal returns, 122 // and exceptional paths. 123 bool HasLiveReturn = false; 124 bool HasFakeEdge = false; 125 bool HasPlainEdge = false; 126 bool HasAbnormalEdge = false; 127 128 // Ignore default cases that aren't likely to be reachable because all 129 // enums in a switch(X) have explicit case statements. 130 CFGBlock::FilterOptions FO; 131 FO.IgnoreDefaultsWithCoveredEnums = 1; 132 133 for (CFGBlock::filtered_pred_iterator 134 I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) { 135 const CFGBlock& B = **I; 136 if (!live[B.getBlockID()]) 137 continue; 138 139 // Skip blocks which contain an element marked as no-return. They don't 140 // represent actually viable edges into the exit block, so mark them as 141 // abnormal. 142 if (B.hasNoReturnElement()) { 143 HasAbnormalEdge = true; 144 continue; 145 } 146 147 // Destructors can appear after the 'return' in the CFG. This is 148 // normal. We need to look pass the destructors for the return 149 // statement (if it exists). 150 CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend(); 151 152 for ( ; ri != re ; ++ri) 153 if (isa<CFGStmt>(*ri)) 154 break; 155 156 // No more CFGElements in the block? 157 if (ri == re) { 158 if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) { 159 HasAbnormalEdge = true; 160 continue; 161 } 162 // A labeled empty statement, or the entry block... 163 HasPlainEdge = true; 164 continue; 165 } 166 167 CFGStmt CS = cast<CFGStmt>(*ri); 168 const Stmt *S = CS.getStmt(); 169 if (isa<ReturnStmt>(S)) { 170 HasLiveReturn = true; 171 continue; 172 } 173 if (isa<ObjCAtThrowStmt>(S)) { 174 HasFakeEdge = true; 175 continue; 176 } 177 if (isa<CXXThrowExpr>(S)) { 178 HasFakeEdge = true; 179 continue; 180 } 181 if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) { 182 if (AS->isMSAsm()) { 183 HasFakeEdge = true; 184 HasLiveReturn = true; 185 continue; 186 } 187 } 188 if (isa<CXXTryStmt>(S)) { 189 HasAbnormalEdge = true; 190 continue; 191 } 192 if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit()) 193 == B.succ_end()) { 194 HasAbnormalEdge = true; 195 continue; 196 } 197 198 HasPlainEdge = true; 199 } 200 if (!HasPlainEdge) { 201 if (HasLiveReturn) 202 return NeverFallThrough; 203 return NeverFallThroughOrReturn; 204 } 205 if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn) 206 return MaybeFallThrough; 207 // This says AlwaysFallThrough for calls to functions that are not marked 208 // noreturn, that don't return. If people would like this warning to be more 209 // accurate, such functions should be marked as noreturn. 210 return AlwaysFallThrough; 211} 212 213namespace { 214 215struct CheckFallThroughDiagnostics { 216 unsigned diag_MaybeFallThrough_HasNoReturn; 217 unsigned diag_MaybeFallThrough_ReturnsNonVoid; 218 unsigned diag_AlwaysFallThrough_HasNoReturn; 219 unsigned diag_AlwaysFallThrough_ReturnsNonVoid; 220 unsigned diag_NeverFallThroughOrReturn; 221 bool funMode; 222 SourceLocation FuncLoc; 223 224 static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { 225 CheckFallThroughDiagnostics D; 226 D.FuncLoc = Func->getLocation(); 227 D.diag_MaybeFallThrough_HasNoReturn = 228 diag::warn_falloff_noreturn_function; 229 D.diag_MaybeFallThrough_ReturnsNonVoid = 230 diag::warn_maybe_falloff_nonvoid_function; 231 D.diag_AlwaysFallThrough_HasNoReturn = 232 diag::warn_falloff_noreturn_function; 233 D.diag_AlwaysFallThrough_ReturnsNonVoid = 234 diag::warn_falloff_nonvoid_function; 235 236 // Don't suggest that virtual functions be marked "noreturn", since they 237 // might be overridden by non-noreturn functions. 238 bool isVirtualMethod = false; 239 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func)) 240 isVirtualMethod = Method->isVirtual(); 241 242 // Don't suggest that template instantiations be marked "noreturn" 243 bool isTemplateInstantiation = false; 244 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func)) { 245 switch (Function->getTemplateSpecializationKind()) { 246 case TSK_Undeclared: 247 case TSK_ExplicitSpecialization: 248 break; 249 250 case TSK_ImplicitInstantiation: 251 case TSK_ExplicitInstantiationDeclaration: 252 case TSK_ExplicitInstantiationDefinition: 253 isTemplateInstantiation = true; 254 break; 255 } 256 } 257 258 if (!isVirtualMethod && !isTemplateInstantiation) 259 D.diag_NeverFallThroughOrReturn = 260 diag::warn_suggest_noreturn_function; 261 else 262 D.diag_NeverFallThroughOrReturn = 0; 263 264 D.funMode = true; 265 return D; 266 } 267 268 static CheckFallThroughDiagnostics MakeForBlock() { 269 CheckFallThroughDiagnostics D; 270 D.diag_MaybeFallThrough_HasNoReturn = 271 diag::err_noreturn_block_has_return_expr; 272 D.diag_MaybeFallThrough_ReturnsNonVoid = 273 diag::err_maybe_falloff_nonvoid_block; 274 D.diag_AlwaysFallThrough_HasNoReturn = 275 diag::err_noreturn_block_has_return_expr; 276 D.diag_AlwaysFallThrough_ReturnsNonVoid = 277 diag::err_falloff_nonvoid_block; 278 D.diag_NeverFallThroughOrReturn = 279 diag::warn_suggest_noreturn_block; 280 D.funMode = false; 281 return D; 282 } 283 284 bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid, 285 bool HasNoReturn) const { 286 if (funMode) { 287 return (ReturnsVoid || 288 D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function, 289 FuncLoc) == DiagnosticsEngine::Ignored) 290 && (!HasNoReturn || 291 D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr, 292 FuncLoc) == DiagnosticsEngine::Ignored) 293 && (!ReturnsVoid || 294 D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 295 == DiagnosticsEngine::Ignored); 296 } 297 298 // For blocks. 299 return ReturnsVoid && !HasNoReturn 300 && (!ReturnsVoid || 301 D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) 302 == DiagnosticsEngine::Ignored); 303 } 304}; 305 306} 307 308/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a 309/// function that should return a value. Check that we don't fall off the end 310/// of a noreturn function. We assume that functions and blocks not marked 311/// noreturn will return. 312static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, 313 const BlockExpr *blkExpr, 314 const CheckFallThroughDiagnostics& CD, 315 AnalysisContext &AC) { 316 317 bool ReturnsVoid = false; 318 bool HasNoReturn = false; 319 320 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 321 ReturnsVoid = FD->getResultType()->isVoidType(); 322 HasNoReturn = FD->hasAttr<NoReturnAttr>() || 323 FD->getType()->getAs<FunctionType>()->getNoReturnAttr(); 324 } 325 else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 326 ReturnsVoid = MD->getResultType()->isVoidType(); 327 HasNoReturn = MD->hasAttr<NoReturnAttr>(); 328 } 329 else if (isa<BlockDecl>(D)) { 330 QualType BlockTy = blkExpr->getType(); 331 if (const FunctionType *FT = 332 BlockTy->getPointeeType()->getAs<FunctionType>()) { 333 if (FT->getResultType()->isVoidType()) 334 ReturnsVoid = true; 335 if (FT->getNoReturnAttr()) 336 HasNoReturn = true; 337 } 338 } 339 340 DiagnosticsEngine &Diags = S.getDiagnostics(); 341 342 // Short circuit for compilation speed. 343 if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn)) 344 return; 345 346 // FIXME: Function try block 347 if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { 348 switch (CheckFallThrough(AC)) { 349 case UnknownFallThrough: 350 break; 351 352 case MaybeFallThrough: 353 if (HasNoReturn) 354 S.Diag(Compound->getRBracLoc(), 355 CD.diag_MaybeFallThrough_HasNoReturn); 356 else if (!ReturnsVoid) 357 S.Diag(Compound->getRBracLoc(), 358 CD.diag_MaybeFallThrough_ReturnsNonVoid); 359 break; 360 case AlwaysFallThrough: 361 if (HasNoReturn) 362 S.Diag(Compound->getRBracLoc(), 363 CD.diag_AlwaysFallThrough_HasNoReturn); 364 else if (!ReturnsVoid) 365 S.Diag(Compound->getRBracLoc(), 366 CD.diag_AlwaysFallThrough_ReturnsNonVoid); 367 break; 368 case NeverFallThroughOrReturn: 369 if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) { 370 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 371 S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn) 372 << 0 << FD; 373 } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 374 S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn) 375 << 1 << MD; 376 } else { 377 S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn); 378 } 379 } 380 break; 381 case NeverFallThrough: 382 break; 383 } 384 } 385} 386 387//===----------------------------------------------------------------------===// 388// -Wuninitialized 389//===----------------------------------------------------------------------===// 390 391namespace { 392/// ContainsReference - A visitor class to search for references to 393/// a particular declaration (the needle) within any evaluated component of an 394/// expression (recursively). 395class ContainsReference : public EvaluatedExprVisitor<ContainsReference> { 396 bool FoundReference; 397 const DeclRefExpr *Needle; 398 399public: 400 ContainsReference(ASTContext &Context, const DeclRefExpr *Needle) 401 : EvaluatedExprVisitor<ContainsReference>(Context), 402 FoundReference(false), Needle(Needle) {} 403 404 void VisitExpr(Expr *E) { 405 // Stop evaluating if we already have a reference. 406 if (FoundReference) 407 return; 408 409 EvaluatedExprVisitor<ContainsReference>::VisitExpr(E); 410 } 411 412 void VisitDeclRefExpr(DeclRefExpr *E) { 413 if (E == Needle) 414 FoundReference = true; 415 else 416 EvaluatedExprVisitor<ContainsReference>::VisitDeclRefExpr(E); 417 } 418 419 bool doesContainReference() const { return FoundReference; } 420}; 421} 422 423static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) { 424 // Don't issue a fixit if there is already an initializer. 425 if (VD->getInit()) 426 return false; 427 428 // Suggest possible initialization (if any). 429 const char *initialization = 0; 430 QualType VariableTy = VD->getType().getCanonicalType(); 431 432 if (VariableTy->isObjCObjectPointerType() || 433 VariableTy->isBlockPointerType()) { 434 // Check if 'nil' is defined. 435 if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil"))) 436 initialization = " = nil"; 437 else 438 initialization = " = 0"; 439 } 440 else if (VariableTy->isRealFloatingType()) 441 initialization = " = 0.0"; 442 else if (VariableTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus) 443 initialization = " = false"; 444 else if (VariableTy->isEnumeralType()) 445 return false; 446 else if (VariableTy->isPointerType() || VariableTy->isMemberPointerType()) { 447 if (S.Context.getLangOptions().CPlusPlus0x) 448 initialization = " = nullptr"; 449 // Check if 'NULL' is defined. 450 else if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("NULL"))) 451 initialization = " = NULL"; 452 else 453 initialization = " = 0"; 454 } 455 else if (VariableTy->isScalarType()) 456 initialization = " = 0"; 457 458 if (initialization) { 459 SourceLocation loc = S.PP.getLocForEndOfToken(VD->getLocEnd()); 460 S.Diag(loc, diag::note_var_fixit_add_initialization) << VD->getDeclName() 461 << FixItHint::CreateInsertion(loc, initialization); 462 return true; 463 } 464 return false; 465} 466 467/// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an 468/// uninitialized variable. This manages the different forms of diagnostic 469/// emitted for particular types of uses. Returns true if the use was diagnosed 470/// as a warning. If a pariticular use is one we omit warnings for, returns 471/// false. 472static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD, 473 const Expr *E, bool isAlwaysUninit, 474 bool alwaysReportSelfInit = false) { 475 bool isSelfInit = false; 476 477 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { 478 if (isAlwaysUninit) { 479 // Inspect the initializer of the variable declaration which is 480 // being referenced prior to its initialization. We emit 481 // specialized diagnostics for self-initialization, and we 482 // specifically avoid warning about self references which take the 483 // form of: 484 // 485 // int x = x; 486 // 487 // This is used to indicate to GCC that 'x' is intentionally left 488 // uninitialized. Proven code paths which access 'x' in 489 // an uninitialized state after this will still warn. 490 // 491 // TODO: Should we suppress maybe-uninitialized warnings for 492 // variables initialized in this way? 493 if (const Expr *Initializer = VD->getInit()) { 494 if (!alwaysReportSelfInit && DRE == Initializer->IgnoreParenImpCasts()) 495 return false; 496 497 ContainsReference CR(S.Context, DRE); 498 CR.Visit(const_cast<Expr*>(Initializer)); 499 isSelfInit = CR.doesContainReference(); 500 } 501 if (isSelfInit) { 502 S.Diag(DRE->getLocStart(), 503 diag::warn_uninit_self_reference_in_init) 504 << VD->getDeclName() << VD->getLocation() << DRE->getSourceRange(); 505 } else { 506 S.Diag(DRE->getLocStart(), diag::warn_uninit_var) 507 << VD->getDeclName() << DRE->getSourceRange(); 508 } 509 } else { 510 S.Diag(DRE->getLocStart(), diag::warn_maybe_uninit_var) 511 << VD->getDeclName() << DRE->getSourceRange(); 512 } 513 } else { 514 const BlockExpr *BE = cast<BlockExpr>(E); 515 S.Diag(BE->getLocStart(), 516 isAlwaysUninit ? diag::warn_uninit_var_captured_by_block 517 : diag::warn_maybe_uninit_var_captured_by_block) 518 << VD->getDeclName(); 519 } 520 521 // Report where the variable was declared when the use wasn't within 522 // the initializer of that declaration & we didn't already suggest 523 // an initialization fixit. 524 if (!isSelfInit && !SuggestInitializationFixit(S, VD)) 525 S.Diag(VD->getLocStart(), diag::note_uninit_var_def) 526 << VD->getDeclName(); 527 528 return true; 529} 530 531typedef std::pair<const Expr*, bool> UninitUse; 532 533namespace { 534struct SLocSort { 535 bool operator()(const UninitUse &a, const UninitUse &b) { 536 SourceLocation aLoc = a.first->getLocStart(); 537 SourceLocation bLoc = b.first->getLocStart(); 538 return aLoc.getRawEncoding() < bLoc.getRawEncoding(); 539 } 540}; 541 542class UninitValsDiagReporter : public UninitVariablesHandler { 543 Sema &S; 544 typedef SmallVector<UninitUse, 2> UsesVec; 545 typedef llvm::DenseMap<const VarDecl *, std::pair<UsesVec*, bool> > UsesMap; 546 UsesMap *uses; 547 548public: 549 UninitValsDiagReporter(Sema &S) : S(S), uses(0) {} 550 ~UninitValsDiagReporter() { 551 flushDiagnostics(); 552 } 553 554 std::pair<UsesVec*, bool> &getUses(const VarDecl *vd) { 555 if (!uses) 556 uses = new UsesMap(); 557 558 UsesMap::mapped_type &V = (*uses)[vd]; 559 UsesVec *&vec = V.first; 560 if (!vec) 561 vec = new UsesVec(); 562 563 return V; 564 } 565 566 void handleUseOfUninitVariable(const Expr *ex, const VarDecl *vd, 567 bool isAlwaysUninit) { 568 getUses(vd).first->push_back(std::make_pair(ex, isAlwaysUninit)); 569 } 570 571 void handleSelfInit(const VarDecl *vd) { 572 getUses(vd).second = true; 573 } 574 575 void flushDiagnostics() { 576 if (!uses) 577 return; 578 579 for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) { 580 const VarDecl *vd = i->first; 581 const UsesMap::mapped_type &V = i->second; 582 583 UsesVec *vec = V.first; 584 bool hasSelfInit = V.second; 585 586 // Specially handle the case where we have uses of an uninitialized 587 // variable, but the root cause is an idiomatic self-init. We want 588 // to report the diagnostic at the self-init since that is the root cause. 589 if (!vec->empty() && hasSelfInit && hasAlwaysUninitializedUse(vec)) 590 DiagnoseUninitializedUse(S, vd, vd->getInit()->IgnoreParenCasts(), 591 /* isAlwaysUninit */ true, 592 /* alwaysReportSelfInit */ true); 593 else { 594 // Sort the uses by their SourceLocations. While not strictly 595 // guaranteed to produce them in line/column order, this will provide 596 // a stable ordering. 597 std::sort(vec->begin(), vec->end(), SLocSort()); 598 599 for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; 600 ++vi) { 601 if (DiagnoseUninitializedUse(S, vd, vi->first, 602 /*isAlwaysUninit=*/vi->second)) 603 // Skip further diagnostics for this variable. We try to warn only 604 // on the first point at which a variable is used uninitialized. 605 break; 606 } 607 } 608 609 // Release the uses vector. 610 delete vec; 611 } 612 delete uses; 613 } 614 615private: 616 static bool hasAlwaysUninitializedUse(const UsesVec* vec) { 617 for (UsesVec::const_iterator i = vec->begin(), e = vec->end(); i != e; ++i) { 618 if (i->second) { 619 return true; 620 } 621 } 622 return false; 623} 624}; 625} 626 627 628//===----------------------------------------------------------------------===// 629// -Wthread-safety 630//===----------------------------------------------------------------------===// 631namespace clang { 632namespace thread_safety { 633typedef std::pair<SourceLocation, PartialDiagnostic> DelayedDiag; 634typedef llvm::SmallVector<DelayedDiag, 4> DiagList; 635 636struct SortDiagBySourceLocation { 637 Sema &S; 638 SortDiagBySourceLocation(Sema &S) : S(S) {} 639 640 bool operator()(const DelayedDiag &left, const DelayedDiag &right) { 641 // Although this call will be slow, this is only called when outputting 642 // multiple warnings. 643 return S.getSourceManager().isBeforeInTranslationUnit(left.first, 644 right.first); 645 } 646}; 647 648class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler { 649 Sema &S; 650 DiagList Warnings; 651 652 // Helper functions 653 void warnLockMismatch(unsigned DiagID, Name LockName, SourceLocation Loc) { 654 PartialDiagnostic Warning = S.PDiag(DiagID) << LockName; 655 Warnings.push_back(DelayedDiag(Loc, Warning)); 656 } 657 658 public: 659 ThreadSafetyReporter(Sema &S) : S(S) {} 660 661 /// \brief Emit all buffered diagnostics in order of sourcelocation. 662 /// We need to output diagnostics produced while iterating through 663 /// the lockset in deterministic order, so this function orders diagnostics 664 /// and outputs them. 665 void emitDiagnostics() { 666 SortDiagBySourceLocation SortDiagBySL(S); 667 sort(Warnings.begin(), Warnings.end(), SortDiagBySL); 668 for (DiagList::iterator I = Warnings.begin(), E = Warnings.end(); 669 I != E; ++I) 670 S.Diag(I->first, I->second); 671 } 672 673 void handleInvalidLockExp(SourceLocation Loc) { 674 PartialDiagnostic Warning = S.PDiag(diag::warn_cannot_resolve_lock) << Loc; 675 Warnings.push_back(DelayedDiag(Loc, Warning)); 676 } 677 void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) { 678 warnLockMismatch(diag::warn_unlock_but_no_lock, LockName, Loc); 679 } 680 681 void handleDoubleLock(Name LockName, SourceLocation Loc) { 682 warnLockMismatch(diag::warn_double_lock, LockName, Loc); 683 } 684 685 void handleMutexHeldEndOfScope(Name LockName, SourceLocation Loc, 686 LockErrorKind LEK){ 687 unsigned DiagID = 0; 688 switch (LEK) { 689 case LEK_LockedSomePredecessors: 690 DiagID = diag::warn_lock_at_end_of_scope; 691 break; 692 case LEK_LockedSomeLoopIterations: 693 DiagID = diag::warn_expecting_lock_held_on_loop; 694 break; 695 case LEK_LockedAtEndOfFunction: 696 DiagID = diag::warn_no_unlock; 697 break; 698 } 699 warnLockMismatch(DiagID, LockName, Loc); 700 } 701 702 703 void handleExclusiveAndShared(Name LockName, SourceLocation Loc1, 704 SourceLocation Loc2) { 705 PartialDiagnostic Warning = 706 S.PDiag(diag::warn_lock_exclusive_and_shared) << LockName; 707 PartialDiagnostic Note = 708 S.PDiag(diag::note_lock_exclusive_and_shared) << LockName; 709 Warnings.push_back(DelayedDiag(Loc1, Warning)); 710 Warnings.push_back(DelayedDiag(Loc2, Note)); 711 } 712 713 void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK, 714 AccessKind AK, SourceLocation Loc) { 715 assert((POK == POK_VarAccess || POK == POK_VarDereference) 716 && "Only works for variables"); 717 unsigned DiagID = POK == POK_VarAccess? 718 diag::warn_variable_requires_any_lock: 719 diag::warn_var_deref_requires_any_lock; 720 PartialDiagnostic Warning = S.PDiag(DiagID) 721 << D->getName() << getLockKindFromAccessKind(AK); 722 Warnings.push_back(DelayedDiag(Loc, Warning)); 723 } 724 725 void handleMutexNotHeld(const NamedDecl *D, ProtectedOperationKind POK, 726 Name LockName, LockKind LK, SourceLocation Loc) { 727 unsigned DiagID = 0; 728 switch (POK) { 729 case POK_VarAccess: 730 DiagID = diag::warn_variable_requires_lock; 731 break; 732 case POK_VarDereference: 733 DiagID = diag::warn_var_deref_requires_lock; 734 break; 735 case POK_FunctionCall: 736 DiagID = diag::warn_fun_requires_lock; 737 break; 738 } 739 PartialDiagnostic Warning = S.PDiag(DiagID) 740 << D->getName() << LockName << LK; 741 Warnings.push_back(DelayedDiag(Loc, Warning)); 742 } 743 744 void handleFunExcludesLock(Name FunName, Name LockName, SourceLocation Loc) { 745 PartialDiagnostic Warning = 746 S.PDiag(diag::warn_fun_excludes_mutex) << FunName << LockName; 747 Warnings.push_back(DelayedDiag(Loc, Warning)); 748 } 749}; 750} 751} 752 753//===----------------------------------------------------------------------===// 754// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based 755// warnings on a function, method, or block. 756//===----------------------------------------------------------------------===// 757 758clang::sema::AnalysisBasedWarnings::Policy::Policy() { 759 enableCheckFallThrough = 1; 760 enableCheckUnreachable = 0; 761 enableThreadSafetyAnalysis = 0; 762} 763 764clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) 765 : S(s), 766 NumFunctionsAnalyzed(0), 767 NumFunctionsWithBadCFGs(0), 768 NumCFGBlocks(0), 769 MaxCFGBlocksPerFunction(0), 770 NumUninitAnalysisFunctions(0), 771 NumUninitAnalysisVariables(0), 772 MaxUninitAnalysisVariablesPerFunction(0), 773 NumUninitAnalysisBlockVisits(0), 774 MaxUninitAnalysisBlockVisitsPerFunction(0) { 775 DiagnosticsEngine &D = S.getDiagnostics(); 776 DefaultPolicy.enableCheckUnreachable = (unsigned) 777 (D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) != 778 DiagnosticsEngine::Ignored); 779 DefaultPolicy.enableThreadSafetyAnalysis = (unsigned) 780 (D.getDiagnosticLevel(diag::warn_double_lock, SourceLocation()) != 781 DiagnosticsEngine::Ignored); 782 783} 784 785static void flushDiagnostics(Sema &S, sema::FunctionScopeInfo *fscope) { 786 for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator 787 i = fscope->PossiblyUnreachableDiags.begin(), 788 e = fscope->PossiblyUnreachableDiags.end(); 789 i != e; ++i) { 790 const sema::PossiblyUnreachableDiag &D = *i; 791 S.Diag(D.Loc, D.PD); 792 } 793} 794 795void clang::sema:: 796AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, 797 sema::FunctionScopeInfo *fscope, 798 const Decl *D, const BlockExpr *blkExpr) { 799 800 // We avoid doing analysis-based warnings when there are errors for 801 // two reasons: 802 // (1) The CFGs often can't be constructed (if the body is invalid), so 803 // don't bother trying. 804 // (2) The code already has problems; running the analysis just takes more 805 // time. 806 DiagnosticsEngine &Diags = S.getDiagnostics(); 807 808 // Do not do any analysis for declarations in system headers if we are 809 // going to just ignore them. 810 if (Diags.getSuppressSystemWarnings() && 811 S.SourceMgr.isInSystemHeader(D->getLocation())) 812 return; 813 814 // For code in dependent contexts, we'll do this at instantiation time. 815 if (cast<DeclContext>(D)->isDependentContext()) 816 return; 817 818 if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) { 819 // Flush out any possibly unreachable diagnostics. 820 flushDiagnostics(S, fscope); 821 return; 822 } 823 824 const Stmt *Body = D->getBody(); 825 assert(Body); 826 827 AnalysisContext AC(D, 0); 828 829 // Don't generate EH edges for CallExprs as we'd like to avoid the n^2 830 // explosion for destrutors that can result and the compile time hit. 831 AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true; 832 AC.getCFGBuildOptions().AddEHEdges = false; 833 AC.getCFGBuildOptions().AddInitializers = true; 834 AC.getCFGBuildOptions().AddImplicitDtors = true; 835 836 // Force that certain expressions appear as CFGElements in the CFG. This 837 // is used to speed up various analyses. 838 // FIXME: This isn't the right factoring. This is here for initial 839 // prototyping, but we need a way for analyses to say what expressions they 840 // expect to always be CFGElements and then fill in the BuildOptions 841 // appropriately. This is essentially a layering violation. 842 if (P.enableCheckUnreachable) { 843 // Unreachable code analysis requires a linearized CFG. 844 AC.getCFGBuildOptions().setAllAlwaysAdd(); 845 } 846 else { 847 AC.getCFGBuildOptions() 848 .setAlwaysAdd(Stmt::BinaryOperatorClass) 849 .setAlwaysAdd(Stmt::BlockExprClass) 850 .setAlwaysAdd(Stmt::CStyleCastExprClass) 851 .setAlwaysAdd(Stmt::DeclRefExprClass) 852 .setAlwaysAdd(Stmt::ImplicitCastExprClass) 853 .setAlwaysAdd(Stmt::UnaryOperatorClass); 854 } 855 856 // Construct the analysis context with the specified CFG build options. 857 858 // Emit delayed diagnostics. 859 if (!fscope->PossiblyUnreachableDiags.empty()) { 860 bool analyzed = false; 861 862 // Register the expressions with the CFGBuilder. 863 for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator 864 i = fscope->PossiblyUnreachableDiags.begin(), 865 e = fscope->PossiblyUnreachableDiags.end(); 866 i != e; ++i) { 867 if (const Stmt *stmt = i->stmt) 868 AC.registerForcedBlockExpression(stmt); 869 } 870 871 if (AC.getCFG()) { 872 analyzed = true; 873 for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator 874 i = fscope->PossiblyUnreachableDiags.begin(), 875 e = fscope->PossiblyUnreachableDiags.end(); 876 i != e; ++i) 877 { 878 const sema::PossiblyUnreachableDiag &D = *i; 879 bool processed = false; 880 if (const Stmt *stmt = i->stmt) { 881 const CFGBlock *block = AC.getBlockForRegisteredExpression(stmt); 882 assert(block); 883 if (CFGReverseBlockReachabilityAnalysis *cra = AC.getCFGReachablityAnalysis()) { 884 // Can this block be reached from the entrance? 885 if (cra->isReachable(&AC.getCFG()->getEntry(), block)) 886 S.Diag(D.Loc, D.PD); 887 processed = true; 888 } 889 } 890 if (!processed) { 891 // Emit the warning anyway if we cannot map to a basic block. 892 S.Diag(D.Loc, D.PD); 893 } 894 } 895 } 896 897 if (!analyzed) 898 flushDiagnostics(S, fscope); 899 } 900 901 902 // Warning: check missing 'return' 903 if (P.enableCheckFallThrough) { 904 const CheckFallThroughDiagnostics &CD = 905 (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock() 906 : CheckFallThroughDiagnostics::MakeForFunction(D)); 907 CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC); 908 } 909 910 // Warning: check for unreachable code 911 if (P.enableCheckUnreachable) 912 CheckUnreachable(S, AC); 913 914 // Check for thread safety violations 915 if (P.enableThreadSafetyAnalysis) { 916 thread_safety::ThreadSafetyReporter Reporter(S); 917 thread_safety::runThreadSafetyAnalysis(AC, Reporter); 918 Reporter.emitDiagnostics(); 919 } 920 921 if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart()) 922 != DiagnosticsEngine::Ignored || 923 Diags.getDiagnosticLevel(diag::warn_maybe_uninit_var, D->getLocStart()) 924 != DiagnosticsEngine::Ignored) { 925 if (CFG *cfg = AC.getCFG()) { 926 UninitValsDiagReporter reporter(S); 927 UninitVariablesAnalysisStats stats; 928 std::memset(&stats, 0, sizeof(UninitVariablesAnalysisStats)); 929 runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC, 930 reporter, stats); 931 932 if (S.CollectStats && stats.NumVariablesAnalyzed > 0) { 933 ++NumUninitAnalysisFunctions; 934 NumUninitAnalysisVariables += stats.NumVariablesAnalyzed; 935 NumUninitAnalysisBlockVisits += stats.NumBlockVisits; 936 MaxUninitAnalysisVariablesPerFunction = 937 std::max(MaxUninitAnalysisVariablesPerFunction, 938 stats.NumVariablesAnalyzed); 939 MaxUninitAnalysisBlockVisitsPerFunction = 940 std::max(MaxUninitAnalysisBlockVisitsPerFunction, 941 stats.NumBlockVisits); 942 } 943 } 944 } 945 946 // Collect statistics about the CFG if it was built. 947 if (S.CollectStats && AC.isCFGBuilt()) { 948 ++NumFunctionsAnalyzed; 949 if (CFG *cfg = AC.getCFG()) { 950 // If we successfully built a CFG for this context, record some more 951 // detail information about it. 952 NumCFGBlocks += cfg->getNumBlockIDs(); 953 MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction, 954 cfg->getNumBlockIDs()); 955 } else { 956 ++NumFunctionsWithBadCFGs; 957 } 958 } 959} 960 961void clang::sema::AnalysisBasedWarnings::PrintStats() const { 962 llvm::errs() << "\n*** Analysis Based Warnings Stats:\n"; 963 964 unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs; 965 unsigned AvgCFGBlocksPerFunction = 966 !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt; 967 llvm::errs() << NumFunctionsAnalyzed << " functions analyzed (" 968 << NumFunctionsWithBadCFGs << " w/o CFGs).\n" 969 << " " << NumCFGBlocks << " CFG blocks built.\n" 970 << " " << AvgCFGBlocksPerFunction 971 << " average CFG blocks per function.\n" 972 << " " << MaxCFGBlocksPerFunction 973 << " max CFG blocks per function.\n"; 974 975 unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0 976 : NumUninitAnalysisVariables/NumUninitAnalysisFunctions; 977 unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0 978 : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions; 979 llvm::errs() << NumUninitAnalysisFunctions 980 << " functions analyzed for uninitialiazed variables\n" 981 << " " << NumUninitAnalysisVariables << " variables analyzed.\n" 982 << " " << AvgUninitVariablesPerFunction 983 << " average variables per function.\n" 984 << " " << MaxUninitAnalysisVariablesPerFunction 985 << " max variables per function.\n" 986 << " " << NumUninitAnalysisBlockVisits << " block visits.\n" 987 << " " << AvgUninitBlockVisitsPerFunction 988 << " average block visits per function.\n" 989 << " " << MaxUninitAnalysisBlockVisitsPerFunction 990 << " max block visits per function.\n"; 991} 992