clang API Documentation

AnalysisBasedWarnings.cpp
Go to the documentation of this file.
00001 //=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis -*- C++ -*-=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines analysis_warnings::[Policy,Executor].
00011 // Together they are used by Sema to issue warnings based on inexpensive
00012 // static analysis algorithms in libAnalysis.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #include "clang/Sema/AnalysisBasedWarnings.h"
00017 #include "clang/Sema/SemaInternal.h"
00018 #include "clang/Sema/ScopeInfo.h"
00019 #include "clang/Basic/SourceManager.h"
00020 #include "clang/Basic/SourceLocation.h"
00021 #include "clang/Lex/Preprocessor.h"
00022 #include "clang/AST/DeclObjC.h"
00023 #include "clang/AST/DeclCXX.h"
00024 #include "clang/AST/ExprObjC.h"
00025 #include "clang/AST/ExprCXX.h"
00026 #include "clang/AST/StmtObjC.h"
00027 #include "clang/AST/StmtCXX.h"
00028 #include "clang/AST/EvaluatedExprVisitor.h"
00029 #include "clang/AST/StmtVisitor.h"
00030 #include "clang/AST/RecursiveASTVisitor.h"
00031 #include "clang/Analysis/AnalysisContext.h"
00032 #include "clang/Analysis/CFG.h"
00033 #include "clang/Analysis/Analyses/ReachableCode.h"
00034 #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
00035 #include "clang/Analysis/Analyses/ThreadSafety.h"
00036 #include "clang/Analysis/CFGStmtMap.h"
00037 #include "clang/Analysis/Analyses/UninitializedValues.h"
00038 #include "llvm/ADT/BitVector.h"
00039 #include "llvm/ADT/FoldingSet.h"
00040 #include "llvm/ADT/ImmutableMap.h"
00041 #include "llvm/ADT/PostOrderIterator.h"
00042 #include "llvm/ADT/SmallVector.h"
00043 #include "llvm/ADT/StringRef.h"
00044 #include "llvm/Support/Casting.h"
00045 #include <algorithm>
00046 #include <iterator>
00047 #include <vector>
00048 #include <deque>
00049 
00050 using namespace clang;
00051 
00052 //===----------------------------------------------------------------------===//
00053 // Unreachable code analysis.
00054 //===----------------------------------------------------------------------===//
00055 
00056 namespace {
00057   class UnreachableCodeHandler : public reachable_code::Callback {
00058     Sema &S;
00059   public:
00060     UnreachableCodeHandler(Sema &s) : S(s) {}
00061 
00062     void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) {
00063       S.Diag(L, diag::warn_unreachable) << R1 << R2;
00064     }
00065   };
00066 }
00067 
00068 /// CheckUnreachable - Check for unreachable code.
00069 static void CheckUnreachable(Sema &S, AnalysisDeclContext &AC) {
00070   UnreachableCodeHandler UC(S);
00071   reachable_code::FindUnreachableCode(AC, UC);
00072 }
00073 
00074 //===----------------------------------------------------------------------===//
00075 // Check for missing return value.
00076 //===----------------------------------------------------------------------===//
00077 
00078 enum ControlFlowKind {
00079   UnknownFallThrough,
00080   NeverFallThrough,
00081   MaybeFallThrough,
00082   AlwaysFallThrough,
00083   NeverFallThroughOrReturn
00084 };
00085 
00086 /// CheckFallThrough - Check that we don't fall off the end of a
00087 /// Statement that should return a value.
00088 ///
00089 /// \returns AlwaysFallThrough iff we always fall off the end of the statement,
00090 /// MaybeFallThrough iff we might or might not fall off the end,
00091 /// NeverFallThroughOrReturn iff we never fall off the end of the statement or
00092 /// return.  We assume NeverFallThrough iff we never fall off the end of the
00093 /// statement but we may return.  We assume that functions not marked noreturn
00094 /// will return.
00095 static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) {
00096   CFG *cfg = AC.getCFG();
00097   if (cfg == 0) return UnknownFallThrough;
00098 
00099   // The CFG leaves in dead things, and we don't want the dead code paths to
00100   // confuse us, so we mark all live things first.
00101   llvm::BitVector live(cfg->getNumBlockIDs());
00102   unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(),
00103                                                           live);
00104 
00105   bool AddEHEdges = AC.getAddEHEdges();
00106   if (!AddEHEdges && count != cfg->getNumBlockIDs())
00107     // When there are things remaining dead, and we didn't add EH edges
00108     // from CallExprs to the catch clauses, we have to go back and
00109     // mark them as live.
00110     for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
00111       CFGBlock &b = **I;
00112       if (!live[b.getBlockID()]) {
00113         if (b.pred_begin() == b.pred_end()) {
00114           if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator()))
00115             // When not adding EH edges from calls, catch clauses
00116             // can otherwise seem dead.  Avoid noting them as dead.
00117             count += reachable_code::ScanReachableFromBlock(&b, live);
00118           continue;
00119         }
00120       }
00121     }
00122 
00123   // Now we know what is live, we check the live precessors of the exit block
00124   // and look for fall through paths, being careful to ignore normal returns,
00125   // and exceptional paths.
00126   bool HasLiveReturn = false;
00127   bool HasFakeEdge = false;
00128   bool HasPlainEdge = false;
00129   bool HasAbnormalEdge = false;
00130 
00131   // Ignore default cases that aren't likely to be reachable because all
00132   // enums in a switch(X) have explicit case statements.
00133   CFGBlock::FilterOptions FO;
00134   FO.IgnoreDefaultsWithCoveredEnums = 1;
00135 
00136   for (CFGBlock::filtered_pred_iterator
00137    I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) {
00138     const CFGBlock& B = **I;
00139     if (!live[B.getBlockID()])
00140       continue;
00141 
00142     // Skip blocks which contain an element marked as no-return. They don't
00143     // represent actually viable edges into the exit block, so mark them as
00144     // abnormal.
00145     if (B.hasNoReturnElement()) {
00146       HasAbnormalEdge = true;
00147       continue;
00148     }
00149 
00150     // Destructors can appear after the 'return' in the CFG.  This is
00151     // normal.  We need to look pass the destructors for the return
00152     // statement (if it exists).
00153     CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend();
00154 
00155     for ( ; ri != re ; ++ri)
00156       if (isa<CFGStmt>(*ri))
00157         break;
00158 
00159     // No more CFGElements in the block?
00160     if (ri == re) {
00161       if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) {
00162         HasAbnormalEdge = true;
00163         continue;
00164       }
00165       // A labeled empty statement, or the entry block...
00166       HasPlainEdge = true;
00167       continue;
00168     }
00169 
00170     CFGStmt CS = cast<CFGStmt>(*ri);
00171     const Stmt *S = CS.getStmt();
00172     if (isa<ReturnStmt>(S)) {
00173       HasLiveReturn = true;
00174       continue;
00175     }
00176     if (isa<ObjCAtThrowStmt>(S)) {
00177       HasFakeEdge = true;
00178       continue;
00179     }
00180     if (isa<CXXThrowExpr>(S)) {
00181       HasFakeEdge = true;
00182       continue;
00183     }
00184     if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) {
00185       if (AS->isMSAsm()) {
00186         HasFakeEdge = true;
00187         HasLiveReturn = true;
00188         continue;
00189       }
00190     }
00191     if (isa<CXXTryStmt>(S)) {
00192       HasAbnormalEdge = true;
00193       continue;
00194     }
00195     if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit())
00196         == B.succ_end()) {
00197       HasAbnormalEdge = true;
00198       continue;
00199     }
00200 
00201     HasPlainEdge = true;
00202   }
00203   if (!HasPlainEdge) {
00204     if (HasLiveReturn)
00205       return NeverFallThrough;
00206     return NeverFallThroughOrReturn;
00207   }
00208   if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn)
00209     return MaybeFallThrough;
00210   // This says AlwaysFallThrough for calls to functions that are not marked
00211   // noreturn, that don't return.  If people would like this warning to be more
00212   // accurate, such functions should be marked as noreturn.
00213   return AlwaysFallThrough;
00214 }
00215 
00216 namespace {
00217 
00218 struct CheckFallThroughDiagnostics {
00219   unsigned diag_MaybeFallThrough_HasNoReturn;
00220   unsigned diag_MaybeFallThrough_ReturnsNonVoid;
00221   unsigned diag_AlwaysFallThrough_HasNoReturn;
00222   unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
00223   unsigned diag_NeverFallThroughOrReturn;
00224   enum { Function, Block, Lambda } funMode;
00225   SourceLocation FuncLoc;
00226 
00227   static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
00228     CheckFallThroughDiagnostics D;
00229     D.FuncLoc = Func->getLocation();
00230     D.diag_MaybeFallThrough_HasNoReturn =
00231       diag::warn_falloff_noreturn_function;
00232     D.diag_MaybeFallThrough_ReturnsNonVoid =
00233       diag::warn_maybe_falloff_nonvoid_function;
00234     D.diag_AlwaysFallThrough_HasNoReturn =
00235       diag::warn_falloff_noreturn_function;
00236     D.diag_AlwaysFallThrough_ReturnsNonVoid =
00237       diag::warn_falloff_nonvoid_function;
00238 
00239     // Don't suggest that virtual functions be marked "noreturn", since they
00240     // might be overridden by non-noreturn functions.
00241     bool isVirtualMethod = false;
00242     if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func))
00243       isVirtualMethod = Method->isVirtual();
00244     
00245     // Don't suggest that template instantiations be marked "noreturn"
00246     bool isTemplateInstantiation = false;
00247     if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func))
00248       isTemplateInstantiation = Function->isTemplateInstantiation();
00249         
00250     if (!isVirtualMethod && !isTemplateInstantiation)
00251       D.diag_NeverFallThroughOrReturn =
00252         diag::warn_suggest_noreturn_function;
00253     else
00254       D.diag_NeverFallThroughOrReturn = 0;
00255     
00256     D.funMode = Function;
00257     return D;
00258   }
00259 
00260   static CheckFallThroughDiagnostics MakeForBlock() {
00261     CheckFallThroughDiagnostics D;
00262     D.diag_MaybeFallThrough_HasNoReturn =
00263       diag::err_noreturn_block_has_return_expr;
00264     D.diag_MaybeFallThrough_ReturnsNonVoid =
00265       diag::err_maybe_falloff_nonvoid_block;
00266     D.diag_AlwaysFallThrough_HasNoReturn =
00267       diag::err_noreturn_block_has_return_expr;
00268     D.diag_AlwaysFallThrough_ReturnsNonVoid =
00269       diag::err_falloff_nonvoid_block;
00270     D.diag_NeverFallThroughOrReturn =
00271       diag::warn_suggest_noreturn_block;
00272     D.funMode = Block;
00273     return D;
00274   }
00275 
00276   static CheckFallThroughDiagnostics MakeForLambda() {
00277     CheckFallThroughDiagnostics D;
00278     D.diag_MaybeFallThrough_HasNoReturn =
00279       diag::err_noreturn_lambda_has_return_expr;
00280     D.diag_MaybeFallThrough_ReturnsNonVoid =
00281       diag::warn_maybe_falloff_nonvoid_lambda;
00282     D.diag_AlwaysFallThrough_HasNoReturn =
00283       diag::err_noreturn_lambda_has_return_expr;
00284     D.diag_AlwaysFallThrough_ReturnsNonVoid =
00285       diag::warn_falloff_nonvoid_lambda;
00286     D.diag_NeverFallThroughOrReturn = 0;
00287     D.funMode = Lambda;
00288     return D;
00289   }
00290 
00291   bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid,
00292                         bool HasNoReturn) const {
00293     if (funMode == Function) {
00294       return (ReturnsVoid ||
00295               D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function,
00296                                    FuncLoc) == DiagnosticsEngine::Ignored)
00297         && (!HasNoReturn ||
00298             D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr,
00299                                  FuncLoc) == DiagnosticsEngine::Ignored)
00300         && (!ReturnsVoid ||
00301             D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
00302               == DiagnosticsEngine::Ignored);
00303     }
00304 
00305     // For blocks / lambdas.
00306     return ReturnsVoid && !HasNoReturn
00307             && ((funMode == Lambda) ||
00308                 D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
00309                   == DiagnosticsEngine::Ignored);
00310   }
00311 };
00312 
00313 }
00314 
00315 /// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
00316 /// function that should return a value.  Check that we don't fall off the end
00317 /// of a noreturn function.  We assume that functions and blocks not marked
00318 /// noreturn will return.
00319 static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
00320                                     const BlockExpr *blkExpr,
00321                                     const CheckFallThroughDiagnostics& CD,
00322                                     AnalysisDeclContext &AC) {
00323 
00324   bool ReturnsVoid = false;
00325   bool HasNoReturn = false;
00326 
00327   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
00328     ReturnsVoid = FD->getResultType()->isVoidType();
00329     HasNoReturn = FD->hasAttr<NoReturnAttr>() ||
00330        FD->getType()->getAs<FunctionType>()->getNoReturnAttr();
00331   }
00332   else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
00333     ReturnsVoid = MD->getResultType()->isVoidType();
00334     HasNoReturn = MD->hasAttr<NoReturnAttr>();
00335   }
00336   else if (isa<BlockDecl>(D)) {
00337     QualType BlockTy = blkExpr->getType();
00338     if (const FunctionType *FT =
00339           BlockTy->getPointeeType()->getAs<FunctionType>()) {
00340       if (FT->getResultType()->isVoidType())
00341         ReturnsVoid = true;
00342       if (FT->getNoReturnAttr())
00343         HasNoReturn = true;
00344     }
00345   }
00346 
00347   DiagnosticsEngine &Diags = S.getDiagnostics();
00348 
00349   // Short circuit for compilation speed.
00350   if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
00351       return;
00352 
00353   // FIXME: Function try block
00354   if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) {
00355     switch (CheckFallThrough(AC)) {
00356       case UnknownFallThrough:
00357         break;
00358 
00359       case MaybeFallThrough:
00360         if (HasNoReturn)
00361           S.Diag(Compound->getRBracLoc(),
00362                  CD.diag_MaybeFallThrough_HasNoReturn);
00363         else if (!ReturnsVoid)
00364           S.Diag(Compound->getRBracLoc(),
00365                  CD.diag_MaybeFallThrough_ReturnsNonVoid);
00366         break;
00367       case AlwaysFallThrough:
00368         if (HasNoReturn)
00369           S.Diag(Compound->getRBracLoc(),
00370                  CD.diag_AlwaysFallThrough_HasNoReturn);
00371         else if (!ReturnsVoid)
00372           S.Diag(Compound->getRBracLoc(),
00373                  CD.diag_AlwaysFallThrough_ReturnsNonVoid);
00374         break;
00375       case NeverFallThroughOrReturn:
00376         if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
00377           if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
00378             S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn)
00379               << 0 << FD;
00380           } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
00381             S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn)
00382               << 1 << MD;
00383           } else {
00384             S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn);
00385           }
00386         }
00387         break;
00388       case NeverFallThrough:
00389         break;
00390     }
00391   }
00392 }
00393 
00394 //===----------------------------------------------------------------------===//
00395 // -Wuninitialized
00396 //===----------------------------------------------------------------------===//
00397 
00398 namespace {
00399 /// ContainsReference - A visitor class to search for references to
00400 /// a particular declaration (the needle) within any evaluated component of an
00401 /// expression (recursively).
00402 class ContainsReference : public EvaluatedExprVisitor<ContainsReference> {
00403   bool FoundReference;
00404   const DeclRefExpr *Needle;
00405 
00406 public:
00407   ContainsReference(ASTContext &Context, const DeclRefExpr *Needle)
00408     : EvaluatedExprVisitor<ContainsReference>(Context),
00409       FoundReference(false), Needle(Needle) {}
00410 
00411   void VisitExpr(Expr *E) {
00412     // Stop evaluating if we already have a reference.
00413     if (FoundReference)
00414       return;
00415 
00416     EvaluatedExprVisitor<ContainsReference>::VisitExpr(E);
00417   }
00418 
00419   void VisitDeclRefExpr(DeclRefExpr *E) {
00420     if (E == Needle)
00421       FoundReference = true;
00422     else
00423       EvaluatedExprVisitor<ContainsReference>::VisitDeclRefExpr(E);
00424   }
00425 
00426   bool doesContainReference() const { return FoundReference; }
00427 };
00428 }
00429 
00430 static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
00431   QualType VariableTy = VD->getType().getCanonicalType();
00432   if (VariableTy->isBlockPointerType() &&
00433       !VD->hasAttr<BlocksAttr>()) {
00434     S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization) << VD->getDeclName()
00435     << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
00436     return true;
00437   }
00438   
00439   // Don't issue a fixit if there is already an initializer.
00440   if (VD->getInit())
00441     return false;
00442   
00443   // Suggest possible initialization (if any).
00444   std::string Init = S.getFixItZeroInitializerForType(VariableTy);
00445   if (Init.empty())
00446     return false;
00447 
00448   // Don't suggest a fixit inside macros.
00449   if (VD->getLocEnd().isMacroID())
00450     return false;
00451 
00452   SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
00453   
00454   S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
00455     << FixItHint::CreateInsertion(Loc, Init);
00456   return true;
00457 }
00458 
00459 /// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an
00460 /// uninitialized variable. This manages the different forms of diagnostic
00461 /// emitted for particular types of uses. Returns true if the use was diagnosed
00462 /// as a warning. If a pariticular use is one we omit warnings for, returns
00463 /// false.
00464 static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
00465                                      const Expr *E, bool isAlwaysUninit,
00466                                      bool alwaysReportSelfInit = false) {
00467 
00468   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
00469     // Inspect the initializer of the variable declaration which is
00470     // being referenced prior to its initialization. We emit
00471     // specialized diagnostics for self-initialization, and we
00472     // specifically avoid warning about self references which take the
00473     // form of:
00474     //
00475     //   int x = x;
00476     //
00477     // This is used to indicate to GCC that 'x' is intentionally left
00478     // uninitialized. Proven code paths which access 'x' in
00479     // an uninitialized state after this will still warn.
00480     if (const Expr *Initializer = VD->getInit()) {
00481       if (!alwaysReportSelfInit && DRE == Initializer->IgnoreParenImpCasts())
00482         return false;
00483 
00484       ContainsReference CR(S.Context, DRE);
00485       CR.Visit(const_cast<Expr*>(Initializer));
00486       if (CR.doesContainReference()) {
00487         S.Diag(DRE->getLocStart(),
00488                diag::warn_uninit_self_reference_in_init)
00489           << VD->getDeclName() << VD->getLocation() << DRE->getSourceRange();
00490         return true;
00491       }
00492     }
00493 
00494     S.Diag(DRE->getLocStart(), isAlwaysUninit ? diag::warn_uninit_var
00495                                               : diag::warn_maybe_uninit_var)
00496       << VD->getDeclName() << DRE->getSourceRange();
00497   } else {
00498     const BlockExpr *BE = cast<BlockExpr>(E);
00499     if (VD->getType()->isBlockPointerType() &&
00500         !VD->hasAttr<BlocksAttr>())
00501       S.Diag(BE->getLocStart(), diag::warn_uninit_byref_blockvar_captured_by_block)
00502         << VD->getDeclName();
00503     else
00504       S.Diag(BE->getLocStart(),
00505              isAlwaysUninit ? diag::warn_uninit_var_captured_by_block
00506                             : diag::warn_maybe_uninit_var_captured_by_block)
00507         << VD->getDeclName();
00508   }
00509 
00510   // Report where the variable was declared when the use wasn't within
00511   // the initializer of that declaration & we didn't already suggest
00512   // an initialization fixit.
00513   if (!SuggestInitializationFixit(S, VD))
00514     S.Diag(VD->getLocStart(), diag::note_uninit_var_def)
00515       << VD->getDeclName();
00516 
00517   return true;
00518 }
00519 
00520 namespace {
00521   class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> {
00522   public:
00523     FallthroughMapper(Sema &S)
00524       : FoundSwitchStatements(false),
00525         S(S) {
00526     }
00527 
00528     bool foundSwitchStatements() const { return FoundSwitchStatements; }
00529 
00530     void markFallthroughVisited(const AttributedStmt *Stmt) {
00531       bool Found = FallthroughStmts.erase(Stmt);
00532       assert(Found);
00533       (void)Found;
00534     }
00535 
00536     typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts;
00537 
00538     const AttrStmts &getFallthroughStmts() const {
00539       return FallthroughStmts;
00540     }
00541 
00542     bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) {
00543       int UnannotatedCnt = 0;
00544       AnnotatedCnt = 0;
00545 
00546       std::deque<const CFGBlock*> BlockQueue;
00547 
00548       std::copy(B.pred_begin(), B.pred_end(), std::back_inserter(BlockQueue));
00549 
00550       while (!BlockQueue.empty()) {
00551         const CFGBlock *P = BlockQueue.front();
00552         BlockQueue.pop_front();
00553 
00554         const Stmt *Term = P->getTerminator();
00555         if (Term && isa<SwitchStmt>(Term))
00556           continue; // Switch statement, good.
00557 
00558         const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel());
00559         if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end())
00560           continue; // Previous case label has no statements, good.
00561 
00562         if (P->pred_begin() == P->pred_end()) {  // The block is unreachable.
00563           // This only catches trivially unreachable blocks.
00564           for (CFGBlock::const_iterator ElIt = P->begin(), ElEnd = P->end();
00565                ElIt != ElEnd; ++ElIt) {
00566             if (const CFGStmt *CS = ElIt->getAs<CFGStmt>()){
00567               if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) {
00568                 S.Diag(AS->getLocStart(),
00569                        diag::warn_fallthrough_attr_unreachable);
00570                 markFallthroughVisited(AS);
00571                 ++AnnotatedCnt;
00572               }
00573               // Don't care about other unreachable statements.
00574             }
00575           }
00576           // If there are no unreachable statements, this may be a special
00577           // case in CFG:
00578           // case X: {
00579           //    A a;  // A has a destructor.
00580           //    break;
00581           // }
00582           // // <<<< This place is represented by a 'hanging' CFG block.
00583           // case Y:
00584           continue;
00585         }
00586 
00587         const Stmt *LastStmt = getLastStmt(*P);
00588         if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
00589           markFallthroughVisited(AS);
00590           ++AnnotatedCnt;
00591           continue; // Fallthrough annotation, good.
00592         }
00593 
00594         if (!LastStmt) { // This block contains no executable statements.
00595           // Traverse its predecessors.
00596           std::copy(P->pred_begin(), P->pred_end(),
00597                     std::back_inserter(BlockQueue));
00598           continue;
00599         }
00600 
00601         ++UnannotatedCnt;
00602       }
00603       return !!UnannotatedCnt;
00604     }
00605 
00606     // RecursiveASTVisitor setup.
00607     bool shouldWalkTypesOfTypeLocs() const { return false; }
00608 
00609     bool VisitAttributedStmt(AttributedStmt *S) {
00610       if (asFallThroughAttr(S))
00611         FallthroughStmts.insert(S);
00612       return true;
00613     }
00614 
00615     bool VisitSwitchStmt(SwitchStmt *S) {
00616       FoundSwitchStatements = true;
00617       return true;
00618     }
00619 
00620   private:
00621 
00622     static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
00623       if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {
00624         if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
00625           return AS;
00626       }
00627       return 0;
00628     }
00629 
00630     static const Stmt *getLastStmt(const CFGBlock &B) {
00631       if (const Stmt *Term = B.getTerminator())
00632         return Term;
00633       for (CFGBlock::const_reverse_iterator ElemIt = B.rbegin(),
00634                                             ElemEnd = B.rend();
00635                                             ElemIt != ElemEnd; ++ElemIt) {
00636         if (const CFGStmt *CS = ElemIt->getAs<CFGStmt>())
00637           return CS->getStmt();
00638       }
00639       // Workaround to detect a statement thrown out by CFGBuilder:
00640       //   case X: {} case Y:
00641       //   case X: ; case Y:
00642       if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))
00643         if (!isa<SwitchCase>(SW->getSubStmt()))
00644           return SW->getSubStmt();
00645 
00646       return 0;
00647     }
00648 
00649     bool FoundSwitchStatements;
00650     AttrStmts FallthroughStmts;
00651     Sema &S;
00652   };
00653 }
00654 
00655 static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC) {
00656   FallthroughMapper FM(S);
00657   FM.TraverseStmt(AC.getBody());
00658 
00659   if (!FM.foundSwitchStatements())
00660     return;
00661 
00662   CFG *Cfg = AC.getCFG();
00663 
00664   if (!Cfg)
00665     return;
00666 
00667   int AnnotatedCnt;
00668 
00669   for (CFG::reverse_iterator I = Cfg->rbegin(), E = Cfg->rend(); I != E; ++I) {
00670     const CFGBlock &B = **I;
00671     const Stmt *Label = B.getLabel();
00672 
00673     if (!Label || !isa<SwitchCase>(Label))
00674       continue;
00675 
00676     if (!FM.checkFallThroughIntoBlock(B, AnnotatedCnt))
00677       continue;
00678 
00679     S.Diag(Label->getLocStart(), diag::warn_unannotated_fallthrough);
00680 
00681     if (!AnnotatedCnt) {
00682       SourceLocation L = Label->getLocStart();
00683       if (L.isMacroID())
00684         continue;
00685       if (S.getLangOpts().CPlusPlus0x) {
00686         S.Diag(L, diag::note_insert_fallthrough_fixit) <<
00687           FixItHint::CreateInsertion(L, "[[clang::fallthrough]]; ");
00688       }
00689       S.Diag(L, diag::note_insert_break_fixit) <<
00690         FixItHint::CreateInsertion(L, "break; ");
00691     }
00692   }
00693 
00694   const FallthroughMapper::AttrStmts &Fallthroughs = FM.getFallthroughStmts();
00695   for (FallthroughMapper::AttrStmts::const_iterator I = Fallthroughs.begin(),
00696                                                     E = Fallthroughs.end();
00697                                                     I != E; ++I) {
00698     S.Diag((*I)->getLocStart(), diag::warn_fallthrough_attr_invalid_placement);
00699   }
00700 
00701 }
00702 
00703 typedef std::pair<const Expr*, bool> UninitUse;
00704 
00705 namespace {
00706 struct SLocSort {
00707   bool operator()(const UninitUse &a, const UninitUse &b) {
00708     SourceLocation aLoc = a.first->getLocStart();
00709     SourceLocation bLoc = b.first->getLocStart();
00710     return aLoc.getRawEncoding() < bLoc.getRawEncoding();
00711   }
00712 };
00713 
00714 class UninitValsDiagReporter : public UninitVariablesHandler {
00715   Sema &S;
00716   typedef SmallVector<UninitUse, 2> UsesVec;
00717   typedef llvm::DenseMap<const VarDecl *, std::pair<UsesVec*, bool> > UsesMap;
00718   UsesMap *uses;
00719   
00720 public:
00721   UninitValsDiagReporter(Sema &S) : S(S), uses(0) {}
00722   ~UninitValsDiagReporter() { 
00723     flushDiagnostics();
00724   }
00725 
00726   std::pair<UsesVec*, bool> &getUses(const VarDecl *vd) {
00727     if (!uses)
00728       uses = new UsesMap();
00729 
00730     UsesMap::mapped_type &V = (*uses)[vd];
00731     UsesVec *&vec = V.first;
00732     if (!vec)
00733       vec = new UsesVec();
00734     
00735     return V;
00736   }
00737   
00738   void handleUseOfUninitVariable(const Expr *ex, const VarDecl *vd,
00739                                  bool isAlwaysUninit) {
00740     getUses(vd).first->push_back(std::make_pair(ex, isAlwaysUninit));
00741   }
00742   
00743   void handleSelfInit(const VarDecl *vd) {
00744     getUses(vd).second = true;    
00745   }
00746   
00747   void flushDiagnostics() {
00748     if (!uses)
00749       return;
00750     
00751     for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) {
00752       const VarDecl *vd = i->first;
00753       const UsesMap::mapped_type &V = i->second;
00754 
00755       UsesVec *vec = V.first;
00756       bool hasSelfInit = V.second;
00757 
00758       // Specially handle the case where we have uses of an uninitialized 
00759       // variable, but the root cause is an idiomatic self-init.  We want
00760       // to report the diagnostic at the self-init since that is the root cause.
00761       if (!vec->empty() && hasSelfInit && hasAlwaysUninitializedUse(vec))
00762         DiagnoseUninitializedUse(S, vd, vd->getInit()->IgnoreParenCasts(),
00763                                  /* isAlwaysUninit */ true,
00764                                  /* alwaysReportSelfInit */ true);
00765       else {
00766         // Sort the uses by their SourceLocations.  While not strictly
00767         // guaranteed to produce them in line/column order, this will provide
00768         // a stable ordering.
00769         std::sort(vec->begin(), vec->end(), SLocSort());
00770         
00771         for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve;
00772              ++vi) {
00773           if (DiagnoseUninitializedUse(S, vd, vi->first,
00774                                         /*isAlwaysUninit=*/vi->second))
00775             // Skip further diagnostics for this variable. We try to warn only
00776             // on the first point at which a variable is used uninitialized.
00777             break;
00778         }
00779       }
00780       
00781       // Release the uses vector.
00782       delete vec;
00783     }
00784     delete uses;
00785   }
00786 
00787 private:
00788   static bool hasAlwaysUninitializedUse(const UsesVec* vec) {
00789   for (UsesVec::const_iterator i = vec->begin(), e = vec->end(); i != e; ++i) {
00790     if (i->second) {
00791       return true;
00792     }
00793   }
00794   return false;
00795 }
00796 };
00797 }
00798 
00799 
00800 //===----------------------------------------------------------------------===//
00801 // -Wthread-safety
00802 //===----------------------------------------------------------------------===//
00803 namespace clang {
00804 namespace thread_safety {
00805 typedef llvm::SmallVector<PartialDiagnosticAt, 1> OptionalNotes;
00806 typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;
00807 typedef std::list<DelayedDiag> DiagList;
00808 
00809 struct SortDiagBySourceLocation {
00810   SourceManager &SM;
00811   SortDiagBySourceLocation(SourceManager &SM) : SM(SM) {}
00812 
00813   bool operator()(const DelayedDiag &left, const DelayedDiag &right) {
00814     // Although this call will be slow, this is only called when outputting
00815     // multiple warnings.
00816     return SM.isBeforeInTranslationUnit(left.first.first, right.first.first);
00817   }
00818 };
00819 
00820 namespace {
00821 class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {
00822   Sema &S;
00823   DiagList Warnings;
00824   SourceLocation FunLocation, FunEndLocation;
00825 
00826   // Helper functions
00827   void warnLockMismatch(unsigned DiagID, Name LockName, SourceLocation Loc) {
00828     // Gracefully handle rare cases when the analysis can't get a more
00829     // precise source location.
00830     if (!Loc.isValid())
00831       Loc = FunLocation;
00832     PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << LockName);
00833     Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
00834   }
00835 
00836  public:
00837   ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL)
00838     : S(S), FunLocation(FL), FunEndLocation(FEL) {}
00839 
00840   /// \brief Emit all buffered diagnostics in order of sourcelocation.
00841   /// We need to output diagnostics produced while iterating through
00842   /// the lockset in deterministic order, so this function orders diagnostics
00843   /// and outputs them.
00844   void emitDiagnostics() {
00845     Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));
00846     for (DiagList::iterator I = Warnings.begin(), E = Warnings.end();
00847          I != E; ++I) {
00848       S.Diag(I->first.first, I->first.second);
00849       const OptionalNotes &Notes = I->second;
00850       for (unsigned NoteI = 0, NoteN = Notes.size(); NoteI != NoteN; ++NoteI)
00851         S.Diag(Notes[NoteI].first, Notes[NoteI].second);
00852     }
00853   }
00854 
00855   void handleInvalidLockExp(SourceLocation Loc) {
00856     PartialDiagnosticAt Warning(Loc,
00857                                 S.PDiag(diag::warn_cannot_resolve_lock) << Loc);
00858     Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
00859   }
00860   void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) {
00861     warnLockMismatch(diag::warn_unlock_but_no_lock, LockName, Loc);
00862   }
00863 
00864   void handleDoubleLock(Name LockName, SourceLocation Loc) {
00865     warnLockMismatch(diag::warn_double_lock, LockName, Loc);
00866   }
00867 
00868   void handleMutexHeldEndOfScope(Name LockName, SourceLocation LocLocked,
00869                                  SourceLocation LocEndOfScope,
00870                                  LockErrorKind LEK){
00871     unsigned DiagID = 0;
00872     switch (LEK) {
00873       case LEK_LockedSomePredecessors:
00874         DiagID = diag::warn_lock_some_predecessors;
00875         break;
00876       case LEK_LockedSomeLoopIterations:
00877         DiagID = diag::warn_expecting_lock_held_on_loop;
00878         break;
00879       case LEK_LockedAtEndOfFunction:
00880         DiagID = diag::warn_no_unlock;
00881         break;
00882     }
00883     if (LocEndOfScope.isInvalid())
00884       LocEndOfScope = FunEndLocation;
00885 
00886     PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << LockName);
00887     PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here));
00888     Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
00889   }
00890 
00891 
00892   void handleExclusiveAndShared(Name LockName, SourceLocation Loc1,
00893                                 SourceLocation Loc2) {
00894     PartialDiagnosticAt Warning(
00895       Loc1, S.PDiag(diag::warn_lock_exclusive_and_shared) << LockName);
00896     PartialDiagnosticAt Note(
00897       Loc2, S.PDiag(diag::note_lock_exclusive_and_shared) << LockName);
00898     Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
00899   }
00900 
00901   void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK,
00902                          AccessKind AK, SourceLocation Loc) {
00903     assert((POK == POK_VarAccess || POK == POK_VarDereference)
00904              && "Only works for variables");
00905     unsigned DiagID = POK == POK_VarAccess?
00906                         diag::warn_variable_requires_any_lock:
00907                         diag::warn_var_deref_requires_any_lock;
00908     PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
00909       << D->getName() << getLockKindFromAccessKind(AK));
00910     Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
00911   }
00912 
00913   void handleMutexNotHeld(const NamedDecl *D, ProtectedOperationKind POK,
00914                           Name LockName, LockKind LK, SourceLocation Loc) {
00915     unsigned DiagID = 0;
00916     switch (POK) {
00917       case POK_VarAccess:
00918         DiagID = diag::warn_variable_requires_lock;
00919         break;
00920       case POK_VarDereference:
00921         DiagID = diag::warn_var_deref_requires_lock;
00922         break;
00923       case POK_FunctionCall:
00924         DiagID = diag::warn_fun_requires_lock;
00925         break;
00926     }
00927     PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
00928       << D->getName() << LockName << LK);
00929     Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
00930   }
00931 
00932   void handleFunExcludesLock(Name FunName, Name LockName, SourceLocation Loc) {
00933     PartialDiagnosticAt Warning(Loc,
00934       S.PDiag(diag::warn_fun_excludes_mutex) << FunName << LockName);
00935     Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
00936   }
00937 };
00938 }
00939 }
00940 }
00941 
00942 //===----------------------------------------------------------------------===//
00943 // AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based
00944 //  warnings on a function, method, or block.
00945 //===----------------------------------------------------------------------===//
00946 
00947 clang::sema::AnalysisBasedWarnings::Policy::Policy() {
00948   enableCheckFallThrough = 1;
00949   enableCheckUnreachable = 0;
00950   enableThreadSafetyAnalysis = 0;
00951 }
00952 
00953 clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
00954   : S(s),
00955     NumFunctionsAnalyzed(0),
00956     NumFunctionsWithBadCFGs(0),
00957     NumCFGBlocks(0),
00958     MaxCFGBlocksPerFunction(0),
00959     NumUninitAnalysisFunctions(0),
00960     NumUninitAnalysisVariables(0),
00961     MaxUninitAnalysisVariablesPerFunction(0),
00962     NumUninitAnalysisBlockVisits(0),
00963     MaxUninitAnalysisBlockVisitsPerFunction(0) {
00964   DiagnosticsEngine &D = S.getDiagnostics();
00965   DefaultPolicy.enableCheckUnreachable = (unsigned)
00966     (D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) !=
00967         DiagnosticsEngine::Ignored);
00968   DefaultPolicy.enableThreadSafetyAnalysis = (unsigned)
00969     (D.getDiagnosticLevel(diag::warn_double_lock, SourceLocation()) !=
00970      DiagnosticsEngine::Ignored);
00971 
00972 }
00973 
00974 static void flushDiagnostics(Sema &S, sema::FunctionScopeInfo *fscope) {
00975   for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
00976        i = fscope->PossiblyUnreachableDiags.begin(),
00977        e = fscope->PossiblyUnreachableDiags.end();
00978        i != e; ++i) {
00979     const sema::PossiblyUnreachableDiag &D = *i;
00980     S.Diag(D.Loc, D.PD);
00981   }
00982 }
00983 
00984 void clang::sema::
00985 AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
00986                                      sema::FunctionScopeInfo *fscope,
00987                                      const Decl *D, const BlockExpr *blkExpr) {
00988 
00989   // We avoid doing analysis-based warnings when there are errors for
00990   // two reasons:
00991   // (1) The CFGs often can't be constructed (if the body is invalid), so
00992   //     don't bother trying.
00993   // (2) The code already has problems; running the analysis just takes more
00994   //     time.
00995   DiagnosticsEngine &Diags = S.getDiagnostics();
00996 
00997   // Do not do any analysis for declarations in system headers if we are
00998   // going to just ignore them.
00999   if (Diags.getSuppressSystemWarnings() &&
01000       S.SourceMgr.isInSystemHeader(D->getLocation()))
01001     return;
01002 
01003   // For code in dependent contexts, we'll do this at instantiation time.
01004   if (cast<DeclContext>(D)->isDependentContext())
01005     return;
01006 
01007   if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) {
01008     // Flush out any possibly unreachable diagnostics.
01009     flushDiagnostics(S, fscope);
01010     return;
01011   }
01012   
01013   const Stmt *Body = D->getBody();
01014   assert(Body);
01015 
01016   AnalysisDeclContext AC(/* AnalysisDeclContextManager */ 0, D);
01017 
01018   // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
01019   // explosion for destrutors that can result and the compile time hit.
01020   AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true;
01021   AC.getCFGBuildOptions().AddEHEdges = false;
01022   AC.getCFGBuildOptions().AddInitializers = true;
01023   AC.getCFGBuildOptions().AddImplicitDtors = true;
01024   
01025   // Force that certain expressions appear as CFGElements in the CFG.  This
01026   // is used to speed up various analyses.
01027   // FIXME: This isn't the right factoring.  This is here for initial
01028   // prototyping, but we need a way for analyses to say what expressions they
01029   // expect to always be CFGElements and then fill in the BuildOptions
01030   // appropriately.  This is essentially a layering violation.
01031   if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis) {
01032     // Unreachable code analysis and thread safety require a linearized CFG.
01033     AC.getCFGBuildOptions().setAllAlwaysAdd();
01034   }
01035   else {
01036     AC.getCFGBuildOptions()
01037       .setAlwaysAdd(Stmt::BinaryOperatorClass)
01038       .setAlwaysAdd(Stmt::BlockExprClass)
01039       .setAlwaysAdd(Stmt::CStyleCastExprClass)
01040       .setAlwaysAdd(Stmt::DeclRefExprClass)
01041       .setAlwaysAdd(Stmt::ImplicitCastExprClass)
01042       .setAlwaysAdd(Stmt::UnaryOperatorClass)
01043       .setAlwaysAdd(Stmt::AttributedStmtClass);
01044   }
01045 
01046   // Construct the analysis context with the specified CFG build options.
01047   
01048   // Emit delayed diagnostics.
01049   if (!fscope->PossiblyUnreachableDiags.empty()) {
01050     bool analyzed = false;
01051 
01052     // Register the expressions with the CFGBuilder.
01053     for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
01054          i = fscope->PossiblyUnreachableDiags.begin(),
01055          e = fscope->PossiblyUnreachableDiags.end();
01056          i != e; ++i) {
01057       if (const Stmt *stmt = i->stmt)
01058         AC.registerForcedBlockExpression(stmt);
01059     }
01060 
01061     if (AC.getCFG()) {
01062       analyzed = true;
01063       for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
01064             i = fscope->PossiblyUnreachableDiags.begin(),
01065             e = fscope->PossiblyUnreachableDiags.end();
01066             i != e; ++i)
01067       {
01068         const sema::PossiblyUnreachableDiag &D = *i;
01069         bool processed = false;
01070         if (const Stmt *stmt = i->stmt) {
01071           const CFGBlock *block = AC.getBlockForRegisteredExpression(stmt);
01072           CFGReverseBlockReachabilityAnalysis *cra =
01073               AC.getCFGReachablityAnalysis();
01074           // FIXME: We should be able to assert that block is non-null, but
01075           // the CFG analysis can skip potentially-evaluated expressions in
01076           // edge cases; see test/Sema/vla-2.c.
01077           if (block && cra) {
01078             // Can this block be reached from the entrance?
01079             if (cra->isReachable(&AC.getCFG()->getEntry(), block))
01080               S.Diag(D.Loc, D.PD);
01081             processed = true;
01082           }
01083         }
01084         if (!processed) {
01085           // Emit the warning anyway if we cannot map to a basic block.
01086           S.Diag(D.Loc, D.PD);
01087         }
01088       }
01089     }
01090 
01091     if (!analyzed)
01092       flushDiagnostics(S, fscope);
01093   }
01094   
01095   
01096   // Warning: check missing 'return'
01097   if (P.enableCheckFallThrough) {
01098     const CheckFallThroughDiagnostics &CD =
01099       (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
01100        : (isa<CXXMethodDecl>(D) &&
01101           cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call &&
01102           cast<CXXMethodDecl>(D)->getParent()->isLambda())
01103             ? CheckFallThroughDiagnostics::MakeForLambda()
01104             : CheckFallThroughDiagnostics::MakeForFunction(D));
01105     CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC);
01106   }
01107 
01108   // Warning: check for unreachable code
01109   if (P.enableCheckUnreachable) {
01110     // Only check for unreachable code on non-template instantiations.
01111     // Different template instantiations can effectively change the control-flow
01112     // and it is very difficult to prove that a snippet of code in a template
01113     // is unreachable for all instantiations.
01114     bool isTemplateInstantiation = false;
01115     if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
01116       isTemplateInstantiation = Function->isTemplateInstantiation();
01117     if (!isTemplateInstantiation)
01118       CheckUnreachable(S, AC);
01119   }
01120 
01121   // Check for thread safety violations
01122   if (P.enableThreadSafetyAnalysis) {
01123     SourceLocation FL = AC.getDecl()->getLocation();
01124     SourceLocation FEL = AC.getDecl()->getLocEnd();
01125     thread_safety::ThreadSafetyReporter Reporter(S, FL, FEL);
01126     thread_safety::runThreadSafetyAnalysis(AC, Reporter);
01127     Reporter.emitDiagnostics();
01128   }
01129 
01130   if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart())
01131       != DiagnosticsEngine::Ignored ||
01132       Diags.getDiagnosticLevel(diag::warn_maybe_uninit_var, D->getLocStart())
01133       != DiagnosticsEngine::Ignored) {
01134     if (CFG *cfg = AC.getCFG()) {
01135       UninitValsDiagReporter reporter(S);
01136       UninitVariablesAnalysisStats stats;
01137       std::memset(&stats, 0, sizeof(UninitVariablesAnalysisStats));
01138       runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC,
01139                                         reporter, stats);
01140 
01141       if (S.CollectStats && stats.NumVariablesAnalyzed > 0) {
01142         ++NumUninitAnalysisFunctions;
01143         NumUninitAnalysisVariables += stats.NumVariablesAnalyzed;
01144         NumUninitAnalysisBlockVisits += stats.NumBlockVisits;
01145         MaxUninitAnalysisVariablesPerFunction =
01146             std::max(MaxUninitAnalysisVariablesPerFunction,
01147                      stats.NumVariablesAnalyzed);
01148         MaxUninitAnalysisBlockVisitsPerFunction =
01149             std::max(MaxUninitAnalysisBlockVisitsPerFunction,
01150                      stats.NumBlockVisits);
01151       }
01152     }
01153   }
01154 
01155   if (Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough,
01156                               D->getLocStart()) != DiagnosticsEngine::Ignored) {
01157     DiagnoseSwitchLabelsFallthrough(S, AC);
01158   }
01159 
01160   // Collect statistics about the CFG if it was built.
01161   if (S.CollectStats && AC.isCFGBuilt()) {
01162     ++NumFunctionsAnalyzed;
01163     if (CFG *cfg = AC.getCFG()) {
01164       // If we successfully built a CFG for this context, record some more
01165       // detail information about it.
01166       NumCFGBlocks += cfg->getNumBlockIDs();
01167       MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction,
01168                                          cfg->getNumBlockIDs());
01169     } else {
01170       ++NumFunctionsWithBadCFGs;
01171     }
01172   }
01173 }
01174 
01175 void clang::sema::AnalysisBasedWarnings::PrintStats() const {
01176   llvm::errs() << "\n*** Analysis Based Warnings Stats:\n";
01177 
01178   unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs;
01179   unsigned AvgCFGBlocksPerFunction =
01180       !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt;
01181   llvm::errs() << NumFunctionsAnalyzed << " functions analyzed ("
01182                << NumFunctionsWithBadCFGs << " w/o CFGs).\n"
01183                << "  " << NumCFGBlocks << " CFG blocks built.\n"
01184                << "  " << AvgCFGBlocksPerFunction
01185                << " average CFG blocks per function.\n"
01186                << "  " << MaxCFGBlocksPerFunction
01187                << " max CFG blocks per function.\n";
01188 
01189   unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0
01190       : NumUninitAnalysisVariables/NumUninitAnalysisFunctions;
01191   unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0
01192       : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions;
01193   llvm::errs() << NumUninitAnalysisFunctions
01194                << " functions analyzed for uninitialiazed variables\n"
01195                << "  " << NumUninitAnalysisVariables << " variables analyzed.\n"
01196                << "  " << AvgUninitVariablesPerFunction
01197                << " average variables per function.\n"
01198                << "  " << MaxUninitAnalysisVariablesPerFunction
01199                << " max variables per function.\n"
01200                << "  " << NumUninitAnalysisBlockVisits << " block visits.\n"
01201                << "  " << AvgUninitBlockVisitsPerFunction
01202                << " average block visits per function.\n"
01203                << "  " << MaxUninitAnalysisBlockVisitsPerFunction
01204                << " max block visits per function.\n";
01205 }