]> granicus.if.org Git - clang/commitdiff
Consumed analysis: fix ICE in handling of loop source locations.
authorDeLesley Hutchins <delesley@google.com>
Thu, 17 Oct 2013 18:19:31 +0000 (18:19 +0000)
committerDeLesley Hutchins <delesley@google.com>
Thu, 17 Oct 2013 18:19:31 +0000 (18:19 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192911 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/Consumed.cpp
test/SemaCXX/warn-consumed-analysis.cpp

index c51c02335c5f92cdf6bb81d6ec2154d41a5b4936..b06fb155d5b8ec06720c200c33be840d8c1157d0 100644 (file)
@@ -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(const CFGBlock *Block) {
   } 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();
     }
   }
+
+  // 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;
   
-  // 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 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(AnalysisDeclContext &AC) {
   CFG *CFGraph = AC.getCFG();
   if (!CFGraph)
     return;
-  
+
   determineExpectedReturnState(AC, D);
 
   PostOrderCFGView *SortedGraph = AC.getAnalysis<PostOrderCFGView>();
index 8a55c8820a230b9bcd5f849188e76b895caf7a94..e7380b97feb215c5531130dc9739c5a67cb31614 100644 (file)
@@ -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
+