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