diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/UninitializedValuesV2.cpp | 39 | ||||
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 27 |
2 files changed, 48 insertions, 18 deletions
diff --git a/lib/Analysis/UninitializedValuesV2.cpp b/lib/Analysis/UninitializedValuesV2.cpp index 4c54885413..4edc1a965b 100644 --- a/lib/Analysis/UninitializedValuesV2.cpp +++ b/lib/Analysis/UninitializedValuesV2.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/DenseMap.h" #include "clang/AST/Decl.h" #include "clang/Analysis/CFG.h" +#include "clang/Analysis/AnalysisContext.h" #include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h" #include "clang/Analysis/Analyses/UninitializedValuesV2.h" #include "clang/Analysis/Support/SaveAndRestore.h" @@ -287,16 +288,22 @@ public: class TransferFunctions : public CFGRecStmtVisitor<TransferFunctions> { CFGBlockValues &vals; const CFG &cfg; + AnalysisContext ∾ UninitVariablesHandler *handler; const DeclRefExpr *currentDR; + const bool flagBlockUses; public: TransferFunctions(CFGBlockValues &vals, const CFG &cfg, - UninitVariablesHandler *handler) - : vals(vals), cfg(cfg), handler(handler), currentDR(0) {} + AnalysisContext &ac, + UninitVariablesHandler *handler, + bool flagBlockUses) + : vals(vals), cfg(cfg), ac(ac), handler(handler), currentDR(0), + flagBlockUses(flagBlockUses) {} const CFG &getCFG() { return cfg; } void reportUninit(const DeclRefExpr *ex, const VarDecl *vd); - + + void VisitBlockExpr(BlockExpr *be); void VisitDeclStmt(DeclStmt *ds); void VisitDeclRefExpr(DeclRefExpr *dr); void VisitUnaryOperator(UnaryOperator *uo); @@ -311,6 +318,20 @@ void TransferFunctions::reportUninit(const DeclRefExpr *ex, if (handler) handler->handleUseOfUninitVariable(ex, vd); } +void TransferFunctions::VisitBlockExpr(BlockExpr *be) { + if (!flagBlockUses || !handler) + return; + AnalysisContext::referenced_decls_iterator i, e; + llvm::tie(i, e) = ac.getReferencedBlockVars(be->getBlockDecl()); + for ( ; i != e; ++i) { + const VarDecl *vd = *i; + if (vd->getAttr<BlocksAttr>() || !vd->hasLocalStorage()) + continue; + if (vals[vd] == Uninitialized) + handler->handleUseOfUninitVariable(be, vd); + } +} + void TransferFunctions::VisitDeclStmt(DeclStmt *ds) { for (DeclStmt::decl_iterator DI = ds->decl_begin(), DE = ds->decl_end(); DI != DE; ++DI) { @@ -450,8 +471,9 @@ void TransferFunctions::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *se) { //====------------------------------------------------------------------------// static bool runOnBlock(const CFGBlock *block, const CFG &cfg, - CFGBlockValues &vals, - UninitVariablesHandler *handler = 0) { + AnalysisContext &ac, CFGBlockValues &vals, + UninitVariablesHandler *handler = 0, + bool flagBlockUses = false) { if (const BinaryOperator *b = getLogicalOperatorInChain(block)) { if (block->pred_size() == 2 && block->succ_size() == 2) { @@ -478,7 +500,7 @@ static bool runOnBlock(const CFGBlock *block, const CFG &cfg, isFirst = false; } // Apply the transfer function. - TransferFunctions tf(vals, cfg, handler); + TransferFunctions tf(vals, cfg, ac, handler, flagBlockUses); for (CFGBlock::const_iterator I = block->begin(), E = block->end(); I != E; ++I) { if (const CFGStmt *cs = dyn_cast<CFGStmt>(&*I)) { @@ -490,6 +512,7 @@ static bool runOnBlock(const CFGBlock *block, const CFG &cfg, void clang::runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg, + AnalysisContext &ac, UninitVariablesHandler &handler) { CFGBlockValues vals(cfg); vals.computeSetOfDeclarations(dc); @@ -502,7 +525,7 @@ void clang::runUninitializedVariablesAnalysis(const DeclContext &dc, while (const CFGBlock *block = worklist.dequeue()) { // Did the block change? - bool changed = runOnBlock(block, cfg, vals); + bool changed = runOnBlock(block, cfg, ac, vals); if (changed || !previouslyVisited[block->getBlockID()]) worklist.enqueueSuccessors(block); previouslyVisited[block->getBlockID()] = true; @@ -510,7 +533,7 @@ void clang::runUninitializedVariablesAnalysis(const DeclContext &dc, // Run through the blocks one more time, and report uninitialized variabes. for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI) { - runOnBlock(*BI, cfg, vals, &handler); + runOnBlock(*BI, cfg, ac, vals, &handler, /* flagBlockUses */ true); } } diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 38284f6627..4866c8fb3d 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -366,7 +366,7 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, namespace { struct SLocSort { - bool operator()(const DeclRefExpr *a, const DeclRefExpr *b) { + bool operator()(const Expr *a, const Expr *b) { SourceLocation aLoc = a->getLocStart(); SourceLocation bLoc = b->getLocStart(); return aLoc.getRawEncoding() < bLoc.getRawEncoding(); @@ -375,7 +375,7 @@ struct SLocSort { class UninitValsDiagReporter : public UninitVariablesHandler { Sema &S; - typedef llvm::SmallVector<const DeclRefExpr *, 2> UsesVec; + typedef llvm::SmallVector<const Expr *, 2> UsesVec; typedef llvm::DenseMap<const VarDecl *, UsesVec*> UsesMap; UsesMap *uses; @@ -385,7 +385,7 @@ public: flushDiagnostics(); } - void handleUseOfUninitVariable(const DeclRefExpr *dr, const VarDecl *vd) { + void handleUseOfUninitVariable(const Expr *ex, const VarDecl *vd) { if (!uses) uses = new UsesMap(); @@ -393,7 +393,7 @@ public: if (!vec) vec = new UsesVec(); - vec->push_back(dr); + vec->push_back(ex); } void flushDiagnostics() { @@ -404,7 +404,7 @@ public: const VarDecl *vd = i->first; UsesVec *vec = i->second; - S.Diag(vd->getLocStart(), diag::warn_var_is_uninit) + S.Diag(vd->getLocStart(), diag::warn_uninit_var) << vd->getDeclName() << vd->getSourceRange(); // Sort the uses by their SourceLocations. While not strictly @@ -414,9 +414,15 @@ public: for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi) { - const DeclRefExpr *dr = *vi; - S.Diag(dr->getLocStart(), diag::note_var_is_uninit) - << vd->getDeclName() << dr->getSourceRange(); + if (const DeclRefExpr *dr = dyn_cast<DeclRefExpr>(*vi)) { + S.Diag(dr->getLocStart(), diag::note_uninit_var) + << vd->getDeclName() << dr->getSourceRange(); + } + else { + const BlockExpr *be = cast<BlockExpr>(*vi); + S.Diag(be->getLocStart(), diag::note_uninit_var_captured_by_block) + << vd->getDeclName(); + } } // Suggest possible initialization (if any). @@ -514,11 +520,12 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, if (P.enableCheckUnreachable) CheckUnreachable(S, AC); - if (Diags.getDiagnosticLevel(diag::warn_var_is_uninit, D->getLocStart()) + if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart()) != Diagnostic::Ignored) { if (CFG *cfg = AC.getCFG()) { UninitValsDiagReporter reporter(S); - runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, reporter); + runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC, + reporter); } } } |