From c5f740ecdbc21d5ba08f97b89cc05c9d4f230fda Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 7 Oct 2011 00:42:48 +0000 Subject: [PATCH] Fix infinite loop in -Wuninitialized reported in PR 11069. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141345 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/UninitializedValues.cpp | 45 ++++++++++++++++------------ test/Sema/uninit-variables.c | 14 +++++++++ 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp index b2e664153b..8d48fffe9f 100644 --- a/lib/Analysis/UninitializedValues.cpp +++ b/lib/Analysis/UninitializedValues.cpp @@ -212,13 +212,6 @@ BVPair &CFGBlockValues::getValueVectors(const clang::CFGBlock *block, return vals[idx]; } -void CFGBlockValues::mergeIntoScratch(ValueVector const &source, - bool isFirst) { - if (isFirst) - scratch = source; - else - scratch |= source; -} #if 0 static void printVector(const CFGBlock *block, ValueVector &bv, unsigned num) { @@ -229,8 +222,24 @@ static void printVector(const CFGBlock *block, ValueVector &bv, } llvm::errs() << " : " << num << '\n'; } + +static void printVector(const char *name, ValueVector const &bv) { + llvm::errs() << name << " : "; + for (unsigned i = 0; i < bv.size(); ++i) { + llvm::errs() << ' ' << bv[i]; + } + llvm::errs() << "\n"; +} #endif +void CFGBlockValues::mergeIntoScratch(ValueVector const &source, + bool isFirst) { + if (isFirst) + scratch = source; + else + scratch |= source; +} + bool CFGBlockValues::updateValueVectorWithScratch(const CFGBlock *block) { ValueVector &dst = getValueVector(block, 0); bool changed = (dst != scratch); @@ -529,14 +538,9 @@ void TransferFunctions::VisitUnaryOperator(clang::UnaryOperator *uo) { void TransferFunctions::VisitCastExpr(clang::CastExpr *ce) { if (ce->getCastKind() == CK_LValueToRValue) { const FindVarResult &res = findBlockVarDecl(ce->getSubExpr()); - if (const VarDecl *vd = res.getDecl()) { + if (res.getDecl()) { assert(res.getDeclRefExpr() == lastDR); - if (isUninitialized(vals[vd])) { - // Record this load of an uninitialized value. Normally this - // results in a warning, but we delay reporting the issue - // in case it is wrapped in a void cast, etc. - lastLoad = ce; - } + lastLoad = ce; } } else if (ce->getCastKind() == CK_NoOp || @@ -573,16 +577,19 @@ void TransferFunctions::ProcessUses(Stmt *s) { if (lastLoad == s) return; - // If we reach here, we have seen a load of an uninitialized value - // and it hasn't been casted to void or otherwise handled. In this - // situation, report the incident. const DeclRefExpr *DR = cast(stripCasts(ac.getASTContext(), lastLoad->getSubExpr())); const VarDecl *VD = cast(DR->getDecl()); - reportUninit(DR, VD, isAlwaysUninit(vals[VD])); + + // If we reach here, we may have seen a load of an uninitialized value + // and it hasn't been casted to void or otherwise handled. In this + // situation, report the incident. + if (isUninitialized(vals[VD])) + reportUninit(DR, VD, isAlwaysUninit(vals[VD])); + lastLoad = 0; - + if (DR == lastDR) { lastDR = 0; return; diff --git a/test/Sema/uninit-variables.c b/test/Sema/uninit-variables.c index 2398504347..bcffbd6a3d 100644 --- a/test/Sema/uninit-variables.c +++ b/test/Sema/uninit-variables.c @@ -391,3 +391,17 @@ int test_block_and_dead_code() { return x; // no-warning } +// This previously triggered an infinite loop in the analysis. +void PR11069(int a, int b) { + unsigned long flags; + for (;;) { + if (a && !b) + break; + } + for (;;) { + // This does not trigger a warning because it isn't a real use. + (void)(flags); // no-warning + } +} + +