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