aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp25
-rw-r--r--clang/test/CoverageMapping/break.c24
2 files changed, 35 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 1a8c6f0..051642bf 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -1087,9 +1087,6 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
// also become the break target.
JumpDest LoopExit = getJumpDestInCurrentScope("while.end");
- // Store the blocks to use for break and continue.
- BreakContinueStack.push_back(BreakContinue(LoopExit, LoopHeader));
-
// C++ [stmt.while]p2:
// When the condition of a while statement is a declaration, the
// scope of the variable that is declared extends from its point
@@ -1158,6 +1155,9 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
<< SourceRange(S.getWhileLoc(), S.getRParenLoc());
}
+ // Store the blocks to use for break and continue.
+ BreakContinueStack.push_back(BreakContinue(LoopExit, LoopHeader));
+
// Emit the loop body. We have to emit this in a cleanup scope
// because it might be a singleton DeclStmt.
{
@@ -1206,8 +1206,6 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
uint64_t ParentCount = getCurrentProfileCount();
- // Store the blocks to use for break and continue.
- BreakContinueStack.push_back(BreakContinue(LoopExit, LoopCond));
// Emit the body of the loop.
llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
@@ -1220,10 +1218,13 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
if (CGM.shouldEmitConvergenceTokens())
ConvergenceTokenStack.push_back(emitConvergenceLoopToken(LoopBody));
+ // Store the blocks to use for break and continue.
+ BreakContinueStack.push_back(BreakContinue(LoopExit, LoopCond));
{
RunCleanupsScope BodyScope(*this);
EmitStmt(S.getBody());
}
+ BreakContinueStack.pop_back();
EmitBlock(LoopCond.getBlock());
// When single byte coverage mode is enabled, add a counter to loop condition.
@@ -1238,8 +1239,6 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
// compares unequal to 0. The condition must be a scalar type.
llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
- BreakContinueStack.pop_back();
-
// "do {} while (0)" is common in macros, avoid extra blocks. Be sure
// to correctly handle break/continue though.
llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal);
@@ -1328,7 +1327,6 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
Continue = CondDest;
else if (!S.getConditionVariable())
Continue = getJumpDestInCurrentScope("for.inc");
- BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
if (S.getCond()) {
// If the for statement has a condition scope, emit the local variable
@@ -1339,7 +1337,6 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
// We have entered the condition variable's scope, so we're now able to
// jump to the continue block.
Continue = S.getInc() ? getJumpDestInCurrentScope("for.inc") : CondDest;
- BreakContinueStack.back().ContinueBlock = Continue;
}
// When single byte coverage mode is enabled, add a counter to loop
@@ -1381,7 +1378,6 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
EmitBlock(ExitBlock);
EmitBranchThroughCleanup(LoopExit);
}
-
EmitBlock(ForBody);
} else {
// Treat it as a non-zero constant. Don't even create a new block for the
@@ -1393,12 +1389,15 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
incrementProfileCounter(S.getBody());
else
incrementProfileCounter(&S);
+
+ BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
{
// Create a separate cleanup scope for the body, in case it is not
// a compound statement.
RunCleanupsScope BodyScope(*this);
EmitStmt(S.getBody());
}
+ BreakContinueStack.pop_back();
// The last block in the loop's body (which unconditionally branches to the
// `inc` block if there is one).
@@ -1412,8 +1411,6 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
incrementProfileCounter(S.getInc());
}
- BreakContinueStack.pop_back();
-
ConditionScope.ForceCleanup();
EmitStopPoint(&S);
@@ -1518,6 +1515,8 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
EmitStmt(S.getLoopVarStmt());
EmitStmt(S.getBody());
}
+ BreakContinueStack.pop_back();
+
// The last block in the loop's body (which unconditionally branches to the
// `inc` block if there is one).
auto *FinalBodyBB = Builder.GetInsertBlock();
@@ -1527,8 +1526,6 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
EmitBlock(Continue.getBlock());
EmitStmt(S.getInc());
- BreakContinueStack.pop_back();
-
EmitBranch(CondBlock);
ForScope.ForceCleanup();
diff --git a/clang/test/CoverageMapping/break.c b/clang/test/CoverageMapping/break.c
index 09d0bd4..86aa2a0 100644
--- a/clang/test/CoverageMapping/break.c
+++ b/clang/test/CoverageMapping/break.c
@@ -31,3 +31,27 @@ int main(void) { // CHECK: File 0, [[@LINE]]:16 -> {{[0-9]+}}:2 = #0
++cnt;
}
}
+
+// CHECK-LABEL: break_continue_in_increment:
+/*
+ 52:41 -> 57:2 = #0
+ 53:10 -> 53:11 = ((#0 + #1) + #2)
+ Branch,File 0, 53:10 -> 53:11 = #1, 0
+
+ 53:13 -> 56:4 = #1
+
+
+
+
+*/
+
+ // CHECK: [[@LINE+6]]:20 -> [[@LINE+6]]:21 = #2
+ // CHECK: [[@LINE+5]]:23 -> [[@LINE+5]]:28 = #3
+ // CHECK: [[@LINE+4]]:35 -> [[@LINE+4]]:43 = (#2 - #3)
+ // CHECK: [[@LINE+4]]:7 -> [[@LINE+4]]:8 = #2
+void break_continue_in_increment(int x) {
+ while (1) {
+ for (;; ({ if (x) break; else continue; }))
+ ;
+ }
+}