зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
a59956b473
Коммит
c5f740ecdb
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче