r192911 - Consumed analysis: fix ICE in handling of loop source locations.

DeLesley Hutchins delesley at google.com
Thu Oct 17 11:19:31 PDT 2013


Author: delesley
Date: Thu Oct 17 13:19:31 2013
New Revision: 192911

URL: http://llvm.org/viewvc/llvm-project?rev=192911&view=rev
Log:
Consumed analysis: fix ICE in handling of loop source locations.

Modified:
    cfe/trunk/lib/Analysis/Consumed.cpp
    cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp

Modified: cfe/trunk/lib/Analysis/Consumed.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Consumed.cpp?rev=192911&r1=192910&r2=192911&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/Consumed.cpp (original)
+++ cfe/trunk/lib/Analysis/Consumed.cpp Thu Oct 17 13:19:31 2013
@@ -51,6 +51,23 @@ using namespace consumed;
 // Key method definition
 ConsumedWarningsHandlerBase::~ConsumedWarningsHandlerBase() {}
 
+static SourceLocation getFirstStmtLoc(const CFGBlock *Block) {
+  // Find the source location of the first statement in the block, if the block
+  // is not empty.
+  for (CFGBlock::const_iterator BI = Block->begin(), BE = Block->end();
+       BI != BE; ++BI) {
+    if (Optional<CFGStmt> CS = BI->getAs<CFGStmt>())
+      return CS->getStmt()->getLocStart();
+  }
+
+  // Block is empty.
+  // If we have one successor, return the first statement in that block
+  if (Block->succ_size() == 1 && *Block->succ_begin())
+    return getFirstStmtLoc(*Block->succ_begin());
+
+  return SourceLocation();
+}
+
 static SourceLocation getLastStmtLoc(const CFGBlock *Block) {
   // Find the source location of the last statement in the block, if the block
   // is not empty.
@@ -59,17 +76,23 @@ static SourceLocation getLastStmtLoc(con
   } else {
     for (CFGBlock::const_reverse_iterator BI = Block->rbegin(),
          BE = Block->rend(); BI != BE; ++BI) {
-      // FIXME: Handle other CFGElement kinds.
       if (Optional<CFGStmt> CS = BI->getAs<CFGStmt>())
         return CS->getStmt()->getLocStart();
     }
   }
-  
-  // The block is empty, and has a single predecessor. Use its exit location.
-  assert(Block->pred_size() == 1 && *Block->pred_begin() &&
-         Block->succ_size() != 0);
-    
-  return getLastStmtLoc(*Block->pred_begin());
+
+  // If we have one successor, return the first statement in that block
+  SourceLocation Loc;
+  if (Block->succ_size() == 1 && *Block->succ_begin())
+    Loc = getFirstStmtLoc(*Block->succ_begin());
+  if (Loc.isValid())
+    return Loc;
+  
+  // If we have one predecessor, return the last statement in that block
+  if (Block->pred_size() == 1 && *Block->pred_begin())
+    return getLastStmtLoc(*Block->pred_begin());
+
+  return Loc;
 }
 
 static ConsumedState invertConsumedUnconsumed(ConsumedState State) {
@@ -1237,7 +1260,7 @@ void ConsumedAnalyzer::run(AnalysisDeclC
   CFG *CFGraph = AC.getCFG();
   if (!CFGraph)
     return;
-  
+
   determineExpectedReturnState(AC, D);
 
   PostOrderCFGView *SortedGraph = AC.getAnalysis<PostOrderCFGView>();

Modified: cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp?rev=192911&r1=192910&r2=192911&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp Thu Oct 17 13:19:31 2013
@@ -546,14 +546,36 @@ void testWhileLoop1() {
   
   ConsumableClass<int> var0, var1(42);
   
-  while (i-- > 0) {
+  while (i-- > 0) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
     
     *var1;
     var1.consume();
-    *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} \
-           // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
+    *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
   }
   
   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
 }
+
+
+namespace ContinueICETest {
+
+bool cond1();
+bool cond2();
+
+static void foo1() {
+  while (cond1()) {
+    if (cond2())
+      continue;
+  }
+}
+
+static void foo2() {
+  while (true) {
+    if (false)
+      continue;
+  }
+}
+
+} // end namespace ContinueICETest
+





More information about the cfe-commits mailing list