From: Ted Kremenek Date: Tue, 18 Jan 2011 04:53:25 +0000 (+0000) Subject: Teach UninitializedValuesV2 about "int x = x" and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c104e53639de4424b83955acfadc977773b5883d;p=clang Teach UninitializedValuesV2 about "int x = x" and also properly handle confluence of loops. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123733 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/UninitializedValuesV2.cpp b/lib/Analysis/UninitializedValuesV2.cpp index 209b18c045..3c833cb67b 100644 --- a/lib/Analysis/UninitializedValuesV2.cpp +++ b/lib/Analysis/UninitializedValuesV2.cpp @@ -22,6 +22,11 @@ using namespace clang; +static bool isTrackedVar(const VarDecl *vd) { + return vd->isLocalVarDecl() && !vd->hasGlobalStorage() && + vd->getType()->isScalarType(); +} + //------------------------------------------------------------------------====// // DeclToBit: a mapping from Decls we track to bitvector indices. //====------------------------------------------------------------------------// @@ -49,7 +54,7 @@ void DeclToBit::computeMap(const DeclContext &dc) { E(dc.decls_end()); for ( ; I != E; ++I) { const VarDecl *vd = *I; - if (vd->isLocalVarDecl() && !vd->hasGlobalStorage()) + if (isTrackedVar(vd)) map[vd] = count++; } } @@ -126,7 +131,7 @@ void CFGBlockValues::mergeIntoScratch(llvm::BitVector const &source, if (isFirst) scratch = source; else - scratch &= source; + scratch |= source; } bool CFGBlockValues::updateBitVectorWithScratch(const CFGBlock *block) { @@ -166,6 +171,8 @@ public: } void DataflowWorklist::enqueue(const CFGBlock *block) { + if (!block) + return; unsigned idx = block->getBlockID(); if (enqueuedBlocks[idx]) return; @@ -193,8 +200,8 @@ const CFGBlock *DataflowWorklist::dequeue() { // Transfer function for uninitialized values analysis. //====------------------------------------------------------------------------// -static const bool Initialized = true; -static const bool Uninitialized = false; +static const bool Initialized = false; +static const bool Uninitialized = true; namespace { class FindVarResult { @@ -235,12 +242,11 @@ void TransferFunctions::VisitDeclStmt(DeclStmt *ds) { for (DeclStmt::decl_iterator DI = ds->decl_begin(), DE = ds->decl_end(); DI != DE; ++DI) { if (VarDecl *vd = dyn_cast(*DI)) { - if (vd->isLocalVarDecl() && !vd->hasGlobalStorage()) { + if (isTrackedVar(vd)) if (Stmt *init = vd->getInit()) { - vals[vd] = Initialized; Visit(init); + vals[vd] = Initialized; } - } } } } @@ -248,7 +254,7 @@ void TransferFunctions::VisitDeclStmt(DeclStmt *ds) { static FindVarResult findBlockVarDecl(Expr* ex) { if (DeclRefExpr* dr = dyn_cast(ex->IgnoreParenCasts())) if (VarDecl *vd = dyn_cast(dr->getDecl())) - if (vd->isLocalVarDecl() && !vd->hasGlobalStorage()) + if (isTrackedVar(vd)) return FindVarResult(vd, dr); return FindVarResult(0, 0); diff --git a/test/Sema/uninit-variables.c b/test/Sema/uninit-variables.c index c2d98c40fe..51e66759e0 100644 --- a/test/Sema/uninit-variables.c +++ b/test/Sema/uninit-variables.c @@ -85,4 +85,20 @@ int test13() { return i; // no-warning } +// Simply don't crash on this test case. +void test14() { + const char *p = 0; + for (;;) {} +} + +void test15() { + int x = x; // expected-warning{{use of uninitialized variable 'x'}} +} +// Don't warn in the following example; shows dataflow confluence. +char *test16_aux(); +void test16() { + char *p = test16_aux(); + for (unsigned i = 0 ; i < 100 ; i++) + p[i] = 'a'; // no-warning +}