зеркало из 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];
|
||||
}
|
||||
|
||||
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<DeclRefExpr>(stripCasts(ac.getASTContext(),
|
||||
lastLoad->getSubExpr()));
|
||||
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;
|
||||
|
||||
|
||||
if (DR == lastDR) {
|
||||
lastDR = 0;
|
||||
return;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче