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
This commit is contained in:
Ted Kremenek 2011-10-07 00:42:48 +00:00
Родитель a59956b473
Коммит c5f740ecdb
2 изменённых файлов: 40 добавлений и 19 удалений

Просмотреть файл

@ -212,13 +212,6 @@ BVPair &CFGBlockValues::getValueVectors(const clang::CFGBlock *block,
return vals[idx]; return vals[idx];
} }
void CFGBlockValues::mergeIntoScratch(ValueVector const &source,
bool isFirst) {
if (isFirst)
scratch = source;
else
scratch |= source;
}
#if 0 #if 0
static void printVector(const CFGBlock *block, ValueVector &bv, static void printVector(const CFGBlock *block, ValueVector &bv,
unsigned num) { unsigned num) {
@ -229,8 +222,24 @@ static void printVector(const CFGBlock *block, ValueVector &bv,
} }
llvm::errs() << " : " << num << '\n'; 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 #endif
void CFGBlockValues::mergeIntoScratch(ValueVector const &source,
bool isFirst) {
if (isFirst)
scratch = source;
else
scratch |= source;
}
bool CFGBlockValues::updateValueVectorWithScratch(const CFGBlock *block) { bool CFGBlockValues::updateValueVectorWithScratch(const CFGBlock *block) {
ValueVector &dst = getValueVector(block, 0); ValueVector &dst = getValueVector(block, 0);
bool changed = (dst != scratch); bool changed = (dst != scratch);
@ -529,14 +538,9 @@ void TransferFunctions::VisitUnaryOperator(clang::UnaryOperator *uo) {
void TransferFunctions::VisitCastExpr(clang::CastExpr *ce) { void TransferFunctions::VisitCastExpr(clang::CastExpr *ce) {
if (ce->getCastKind() == CK_LValueToRValue) { if (ce->getCastKind() == CK_LValueToRValue) {
const FindVarResult &res = findBlockVarDecl(ce->getSubExpr()); const FindVarResult &res = findBlockVarDecl(ce->getSubExpr());
if (const VarDecl *vd = res.getDecl()) { if (res.getDecl()) {
assert(res.getDeclRefExpr() == lastDR); assert(res.getDeclRefExpr() == lastDR);
if (isUninitialized(vals[vd])) { lastLoad = ce;
// 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;
}
} }
} }
else if (ce->getCastKind() == CK_NoOp || else if (ce->getCastKind() == CK_NoOp ||
@ -573,16 +577,19 @@ void TransferFunctions::ProcessUses(Stmt *s) {
if (lastLoad == s) if (lastLoad == s)
return; 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 = const DeclRefExpr *DR =
cast<DeclRefExpr>(stripCasts(ac.getASTContext(), cast<DeclRefExpr>(stripCasts(ac.getASTContext(),
lastLoad->getSubExpr())); lastLoad->getSubExpr()));
const VarDecl *VD = cast<VarDecl>(DR->getDecl()); const VarDecl *VD = cast<VarDecl>(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; lastLoad = 0;
if (DR == lastDR) { if (DR == lastDR) {
lastDR = 0; lastDR = 0;
return; return;

Просмотреть файл

@ -391,3 +391,17 @@ int test_block_and_dead_code() {
return x; // no-warning 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
}
}