]> granicus.if.org Git - clang/commitdiff
Fix infinite loop in -Wuninitialized reported in PR 11069.
authorTed Kremenek <kremenek@apple.com>
Fri, 7 Oct 2011 00:42:48 +0000 (00:42 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 7 Oct 2011 00:42:48 +0000 (00:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141345 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/UninitializedValues.cpp
test/Sema/uninit-variables.c

index b2e664153bc8a6b6532b9c15b71c3514350be827..8d48fffe9f265f1793978e9d624aac7446ee6406 100644 (file)
@@ -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;
index 2398504347d2720f5767b8b0221af692a837f4cc..bcffbd6a3d503075843b52a7fe4d91214dcba38c 100644 (file)
@@ -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
+  }
+}
+
+