Skip to content

[Coverage][Single] Enable Branch coverage for IfStmt #113111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 54 commits into
base: users/chapuni/cov/single/nextcount
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
178b57c
[Coverage] Move SingleByteCoverage out of CountedRegion
chapuni Oct 2, 2024
aacb50d
[Coverage] Make SingleByteCoverage work consistent to merging
chapuni Oct 2, 2024
b9bbc7c
Rework. (Also reverts "[Coverage] Move SingleByteCoverage out of Cou…
chapuni Oct 5, 2024
52f072e
clang/test/CoverageMapping/single-byte-counters.cpp: Rewrite counter …
chapuni Oct 17, 2024
78e33ba
Merge branches 'users/chapuni/cov/single/test' and 'users/chapuni/cov…
chapuni Oct 21, 2024
3ea6383
[Coverage][Single] Enable Branch coverage for IfStmt
chapuni Oct 20, 2024
bc708d5
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Oct 27, 2024
97a4a8f
test/llvm-cov: Transform %.c* tests to {%.test, Inputs/%.c*}
chapuni Nov 20, 2024
c50c492
Introduce test/llvm-cov/Inputs/yaml.makefile for convenience.
chapuni Nov 20, 2024
d7c5b44
Add tests for SingleByteCoverage
chapuni Nov 20, 2024
6675226
Merge branch 'users/chapuni/cov/single/test' into users/chapuni/cov/s…
chapuni Nov 20, 2024
5fc3408
Fix a test to fix linecount=1
chapuni Nov 20, 2024
d086491
Merge branch 'users/chapuni/cov/single/merge' into users/chapuni/cov/…
chapuni Nov 20, 2024
2364252
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Nov 20, 2024
b2f7fdf
Update single tests
chapuni Nov 20, 2024
eb7fff9
threads.c: Fixup on the clean testdir
chapuni Nov 20, 2024
7543095
Rename threads.c to threads.test since it is no longer C source file.
chapuni Nov 21, 2024
00ac90d
llvm/test/tools/llvm-cov/Inputs: Avoid wildcards `rm -rf %t*.dir`
chapuni Nov 21, 2024
fcb3ee8
Merge branch 'main' into users/chapuni/cov/single/test
chapuni Dec 21, 2024
5fa862a
Use `[[#min(C,n)]]` for tests
chapuni Dec 21, 2024
805e9a9
llvm-cov: Introduce `--binary-counters`
chapuni Dec 21, 2024
68d7b3b
Merge branch 'users/chapuni/cov/single/test' into users/chapuni/cov/s…
chapuni Dec 21, 2024
24457a7
Update tests
chapuni Dec 21, 2024
805dbd9
Merge branches 'users/chapuni/cov/single/merge' and 'users/chapuni/co…
chapuni Dec 21, 2024
f96b435
New SingleByteCoverage
chapuni Dec 21, 2024
2968ea6
Merge branch 'users/chapuni/cov/single/refactor' into users/chapuni/c…
chapuni Dec 21, 2024
cb3f959
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Dec 21, 2024
f178bf6
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Dec 21, 2024
47550d1
threads.c => threads.test (following #113114)
chapuni Dec 22, 2024
42c0c26
clang/test: Add tests that we missed while I was updating.
chapuni Dec 23, 2024
c0a93e2
Merge branches 'users/chapuni/cov/single/test' and 'users/chapuni/cov…
chapuni Dec 23, 2024
747478e
Update the test
chapuni Dec 23, 2024
b992ae4
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Dec 23, 2024
f4dc4eb
s/Count1/BinaryCount/
chapuni Dec 23, 2024
822620b
Update desc
chapuni Dec 23, 2024
658bd48
Merge branch 'main' into users/chapuni/cov/binary
chapuni Dec 24, 2024
0780993
Merge branch 'users/chapuni/cov/binary' into users/chapuni/cov/single…
chapuni Dec 24, 2024
5dfe3e7
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Dec 24, 2024
1adf497
Eliminate (rewind) "refactor" changes
chapuni Dec 24, 2024
8169e09
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Dec 24, 2024
dfc99ba
Fix wrong merge resolutions
chapuni Dec 24, 2024
f3c9593
Reorganize CoverageMapping::SingleByteCoverage
chapuni Dec 24, 2024
3780e07
Prune commented-out line
chapuni Dec 24, 2024
894c383
Merge branch 'main' into users/chapuni/cov/single/refactor
chapuni Dec 27, 2024
7c26a2a
Merge branch 'main' into users/chapuni/cov/single/refactor
chapuni Dec 27, 2024
e11930a
Merge branch 'users/chapuni/cov/single/refactor' into users/chapuni/c…
chapuni Dec 27, 2024
ad7b753
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Dec 27, 2024
3069477
Merge branch 'main' into users/chapuni/cov/single/base
chapuni Dec 28, 2024
e19c32e
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Dec 28, 2024
e7fd5cd
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Jan 8, 2025
ed54cbb
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Jan 8, 2025
3c62522
Dissolve assert
chapuni Jan 8, 2025
bdcf47e
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Jan 9, 2025
0e1a753
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Jan 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 13 additions & 18 deletions clang/lib/CodeGen/CGStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,8 +864,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
// If the skipped block has no labels in it, just emit the executed block.
// This avoids emitting dead code and simplifies the CFG substantially.
if (S.isConstexpr() || !ContainsLabel(Skipped)) {
if (CondConstant)
incrementProfileCounter(&S);
incrementProfileCounter(!CondConstant, &S, true);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment for bool parameter for readability?

e.g. /*varname=*/true

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. See also #120930. UseBoth is not classified since I think its usage is rare.

if (Executed) {
RunCleanupsScope ExecutedScope(*this);
EmitStmt(Executed);
Expand All @@ -875,14 +874,14 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
}
}

auto HasSkip = getIsCounterPair(&S);

// Otherwise, the condition did not fold, or we couldn't elide it. Just emit
// the conditional branch.
llvm::BasicBlock *ThenBlock = createBasicBlock("if.then");
llvm::BasicBlock *ContBlock = createBasicBlock("if.end");
llvm::BasicBlock *ElseBlock = ContBlock;
if (Else)
ElseBlock = createBasicBlock("if.else");

llvm::BasicBlock *ElseBlock =
(Else || HasSkip.second ? createBasicBlock("if.else") : ContBlock);
// Prefer the PGO based weights over the likelihood attribute.
// When the build isn't optimized the metadata isn't used, so don't generate
// it.
Expand Down Expand Up @@ -915,10 +914,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {

// Emit the 'then' code.
EmitBlock(ThenBlock);
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(S.getThen());
else
incrementProfileCounter(&S);
incrementProfileCounter(false, &S);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

{
RunCleanupsScope ThenScope(*this);
EmitStmt(S.getThen());
Expand All @@ -932,9 +928,9 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
auto NL = ApplyDebugLocation::CreateEmpty(*this);
EmitBlock(ElseBlock);
}
// When single byte coverage mode is enabled, add a counter to else block.
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(Else);
// Add a counter to else block unless it has CounterExpr.
if (HasSkip.second)
incrementProfileCounter(true, &S);
{
RunCleanupsScope ElseScope(*this);
EmitStmt(Else);
Expand All @@ -944,15 +940,14 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
auto NL = ApplyDebugLocation::CreateEmpty(*this);
EmitBranch(ContBlock);
}
} else if (HasSkip.second) {
EmitBlock(ElseBlock);
incrementProfileCounter(true, &S);
EmitBranch(ContBlock);
}

// Emit the continuation block for code after the if.
EmitBlock(ContBlock, true);

// When single byte coverage mode is enabled, add a counter to continuation
// block.
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(&S);
}

bool CodeGenFunction::checkIfLoopMustProgress(const Expr *ControllingExpression,
Expand Down
12 changes: 0 additions & 12 deletions clang/lib/CodeGen/CodeGenPGO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,18 +365,6 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
if (Hash.getHashVersion() == PGO_HASH_V1)
return Base::TraverseIfStmt(If);

// When single byte coverage mode is enabled, add a counter to then and
// else.
bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
for (Stmt *CS : If->children()) {
if (!CS || NoSingleByteCoverage)
continue;
if (CS == If->getThen())
CounterMap[If->getThen()] = NextCounter++;
else if (CS == If->getElse())
CounterMap[If->getElse()] = NextCounter++;
}

// Otherwise, keep track of which branch we're in while traversing.
VisitStmt(If);

Expand Down
21 changes: 5 additions & 16 deletions clang/lib/CodeGen/CoverageMappingGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2074,12 +2074,7 @@ struct CounterCoverageMappingBuilder
extendRegion(S->getCond());

Counter ParentCount = getRegion().getCounter();
auto [ThenCount, ElseCount] =
(llvm::EnableSingleByteCoverage
? std::make_pair(getRegionCounter(S->getThen()),
(S->getElse() ? getRegionCounter(S->getElse())
: Counter::getZero()))
: getBranchCounterPair(S, ParentCount));
auto [ThenCount, ElseCount] = getBranchCounterPair(S, ParentCount);

// Emitting a counter for the condition makes it easier to interpret the
// counter for the body when looking at the coverage.
Expand All @@ -2104,26 +2099,20 @@ struct CounterCoverageMappingBuilder
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ElseCount);
extendRegion(Else);

Counter ElseOutCount = propagateCounts(ElseCount, Else);
if (!llvm::EnableSingleByteCoverage)
OutCount = addCounters(OutCount, ElseOutCount);
OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));

if (ThenHasTerminateStmt)
HasTerminateStmt = true;
} else if (!llvm::EnableSingleByteCoverage)
} else
OutCount = addCounters(OutCount, ElseCount);

if (llvm::EnableSingleByteCoverage)
OutCount = getRegionCounter(S);

if (!IsCounterEqual(OutCount, ParentCount)) {
pushRegion(OutCount);
GapRegionCounter = OutCount;
}

if (!llvm::EnableSingleByteCoverage)
// Create Branch Region around condition.
createBranchRegion(S->getCond(), ThenCount, ElseCount);
// Create Branch Region around condition.
createBranchRegion(S->getCond(), ThenCount, ElseCount);
}

void VisitCXXTryStmt(const CXXTryStmt *S) {
Expand Down
188 changes: 89 additions & 99 deletions clang/test/CoverageMapping/single-byte-counters.cpp
Original file line number Diff line number Diff line change
@@ -1,169 +1,159 @@
// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -mllvm -enable-single-byte-coverage=true -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name single-byte-counters.cpp %s | FileCheck %s

// CHECK: testIf
int testIf(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> [[@LINE+10]]:2 = #0
// CHECK-NEXT: File 0, [[@LINE+5]]:7 -> [[@LINE+5]]:13 = #0
// CHECK-NEXT: Gap,File 0, [[@LINE+4]]:14 -> [[@LINE+5]]:5 = #1
// CHECK-NEXT: File 0, [[@LINE+4]]:5 -> [[@LINE+4]]:16 = #1
// CHECK-NEXT: File 0, [[@LINE+5]]:3 -> [[@LINE+5]]:16 = #2
int testIf(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> [[@LINE+8]]:2 = [[C00:#0]]
int result = 0;
if (x == 0)
result = -1;
if (x == 0) // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = [[C00]]
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:7 -> [[@LINE-1]]:13 = [[C0T:#1]], [[C0F:#2]]
// CHECK-NEXT: Gap,File 0, [[@LINE-2]]:14 -> [[@LINE+1]]:5 = [[C0T]]
result = -1; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:16 = [[C0T]]

return result;
return result; // #0
}

// CHECK-NEXT: testIfElse
int testIfElse(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+13]]:2 = #0
// CHECK-NEXT: File 0, [[@LINE+7]]:7 -> [[@LINE+7]]:12 = #0
// CHECK-NEXT: Gap,File 0, [[@LINE+6]]:13 -> [[@LINE+7]]:5 = #1
// CHECK-NEXT: File 0, [[@LINE+6]]:5 -> [[@LINE+6]]:15 = #1
// CHECK-NEXT: Gap,File 0, [[@LINE+5]]:16 -> [[@LINE+7]]:5 = #2
// CHECK-NEXT: File 0, [[@LINE+6]]:5 -> [[@LINE+6]]:19 = #2
// CHECK-NEXT: File 0, [[@LINE+6]]:3 -> [[@LINE+6]]:16 = #3
int testIfElse(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+9]]:2 = [[C10:#0]]
int result = 0;
if (x < 0)
result = 0;
else
result = x * x;
return result;
if (x < 0) // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:12 = [[C10]]
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:7 -> [[@LINE-1]]:12 = [[C1T:#1]], [[C1F:#2]]
// CHECK-NEXT: Gap,File 0, [[@LINE-2]]:13 -> [[@LINE+1]]:5 = [[C1T]]
result = 0; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:15 = [[C1T]]
else // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:5 = [[C1F]]
result = x * x; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:19 = [[C1F]]
return result; // #0
}

// CHECK-NEXT: testIfElseReturn
int testIfElseReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+14]]:2 = #0
// CHECK-NEXT: File 0, [[@LINE+8]]:7 -> [[@LINE+8]]:12 = #0
// CHECK-NEXT: Gap,File 0, [[@LINE+7]]:13 -> [[@LINE+8]]:5 = #1
// CHECK-NEXT: File 0, [[@LINE+7]]:5 -> [[@LINE+7]]:19 = #1
// CHECK-NEXT: Gap,File 0, [[@LINE+6]]:20 -> [[@LINE+8]]:5 = #2
// CHECK-NEXT: File 0, [[@LINE+7]]:5 -> [[@LINE+7]]:13 = #2
// CHECK-NEXT: Gap,File 0, [[@LINE+6]]:14 -> [[@LINE+7]]:3 = #3
// CHECK-NEXT: File 0, [[@LINE+6]]:3 -> [[@LINE+6]]:16 = #3
int testIfElseReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+10]]:2 = [[C20:#0]]
int result = 0;
if (x > 0) // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:12 = [[C20]]
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:7 -> [[@LINE-1]]:12 = [[C2T:#1]], [[C2F:#2]]
// CHECK-NEXT: Gap,File 0, [[@LINE-2]]:13 -> [[@LINE+1]]:5 = [[C2T]]
result = x * x; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:19 = [[C2T]]
else // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:20 -> [[@LINE+1]]:5 = [[C2F]]
return 0; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:13 = [[C2F]]
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:3 = [[C2T]]
return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C2T]]
}

// CHECK-NEXT: testIfBothReturn
int testIfBothReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+10]]:2 = [[C20:#0]]
int result = 0;
if (x > 0)
result = x * x;
else
return 0;
return result;
if (x > 0) // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:12 = [[C20]]
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:7 -> [[@LINE-1]]:12 = [[C2T:#1]], [[C2F:#2]]
// CHECK-NEXT: Gap,File 0, [[@LINE-2]]:13 -> [[@LINE+1]]:5 = [[C2T]]
return 42; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:14 = [[C2T]]
else // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:15 -> [[@LINE+1]]:5 = [[C2F]]
return 0; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:13 = [[C2F]]
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:3 = 0
return -1; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:12 = 0
}

// CHECK-NEXT: testSwitch
int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+22]]:2 = #0
// CHECK-NEXT: Gap,File 0, [[@LINE+9]]:14 -> [[@LINE+17]]:15 = 0
// CHECK-NEXT: File 0, [[@LINE+9]]:3 -> [[@LINE+11]]:10 = #2
// CHECK-NEXT: Gap,File 0, [[@LINE+10]]:11 -> [[@LINE+11]]:3 = 0
// CHECK-NEXT: File 0, [[@LINE+10]]:3 -> [[@LINE+12]]:10 = #3
// CHECK-NEXT: Gap,File 0, [[@LINE+11]]:11 -> [[@LINE+12]]:3 = 0
// CHECK-NEXT: File 0, [[@LINE+11]]:3 -> [[@LINE+12]]:15 = #4
// CHECK-NEXT: Gap,File 0, [[@LINE+12]]:4 -> [[@LINE+14]]:3 = #1
// CHECK-NEXT: File 0, [[@LINE+13]]:3 -> [[@LINE+13]]:16 = #1
int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+17]]:2 = [[C30:#0]]
int result;
switch (x) {
case 1:
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+10]]:15 = 0
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = [[C31:#2]]
result = 1;
break;
case 2:
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = 0
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = [[C32:#3]]
result = 2;
break;
default:
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = 0
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:15 = [[C3D:#4]]
result = 0;
}

return result;
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = [[C3E:#1]]
return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C3E]]
}

// CHECK-NEXT: testWhile
int testWhile() { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+13]]:2 = #0
// CHECK-NEXT: File 0, [[@LINE+6]]:10 -> [[@LINE+6]]:16 = #1
// CHECK-NEXT: Gap,File 0, [[@LINE+5]]:17 -> [[@LINE+5]]:18 = #2
// CHECK-NEXT: File 0, [[@LINE+4]]:18 -> [[@LINE+7]]:4 = #2
// CHECK-NEXT: File 0, [[@LINE+8]]:3 -> [[@LINE+8]]:13 = #3
int testWhile() { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+11]]:2 = [[C40:#0]]
int i = 0;
int sum = 0;
while (i < 10) {
while (i < 10) { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:16 = [[C4C:#1]]
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:17 -> [[@LINE-1]]:18 = [[C4T:#2]]
// CHECK-NEXT: File 0, [[@LINE-2]]:18 -> [[@LINE+3]]:4 = [[C4T]]
sum += i;
i++;
}

return sum;
return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C4E:#3]]
}

// CHECK-NEXT: testContinue
int testContinue() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+21]]:2 = #0
// CHECK-NEXT: File 0, [[@LINE+12]]:10 -> [[@LINE+12]]:16 = #1
// CHECK-NEXT: Gap,File 0, [[@LINE+11]]:17 -> [[@LINE+11]]:18 = #2
// CHECK-NEXT: File 0, [[@LINE+10]]:18 -> [[@LINE+15]]:4 = #2
// CHECK-NEXT: File 0, [[@LINE+10]]:9 -> [[@LINE+10]]:15 = #2
// CHECK-NEXT: Gap,File 0, [[@LINE+9]]:16 -> [[@LINE+10]]:7 = #4
// CHECK-NEXT: File 0, [[@LINE+9]]:7 -> [[@LINE+9]]:15 = #4
// CHECK-NEXT: Gap,File 0, [[@LINE+8]]:16 -> [[@LINE+9]]:5 = #5
// CHECK-NEXT: File 0, [[@LINE+8]]:5 -> [[@LINE+10]]:4 = #5
// CHECK-NEXT: Gap,File 0, [[@LINE+9]]:4 -> [[@LINE+11]]:3 = #3
// CHECK-NEXT: File 0, [[@LINE+10]]:3 -> [[@LINE+10]]:13 = #3
// CHECK-NEXT: testContinueBreak
int testContinueBreak() { // CHECK-NEXT: File 0, [[@LINE]]:25 -> [[@LINE+22]]:2 = #0
int i = 0;
int sum = 0;
while (i < 10) {
if (i == 4)
continue;
sum += i;
while (i < 10) { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:16 = [[C5C:#1]]
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:17 -> [[@LINE-1]]:18 = [[C5B:#2]]
// CHECK-NEXT: File 0, [[@LINE-2]]:18 -> [[@LINE+14]]:4 = [[C5B]]
if (i == 4) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = [[C5B]]
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:9 -> [[@LINE-1]]:15 = [[C5T:#4]], [[C5F:#6]]
// CHECK-NEXT: Gap,File 0, [[@LINE-2]]:16 -> [[@LINE+1]]:7 = [[C5T]]
continue; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = [[C5T]]
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+2]]:5 = [[C5F]]
// CHECK-NEXT: File 0, [[@LINE+1]]:5 -> [[@LINE+8]]:4 = [[C5F]]
if (i == 5) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = [[C5F]]
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:9 -> [[@LINE-1]]:15 = [[C5T1:#5]], [[C5F1:#7]]
// CHECK-NEXT: Gap,File 0, [[@LINE-2]]:16 -> [[@LINE+1]]:7 = [[C5T1]]
break; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:12 = [[C5T1]]
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+1]]:5 = [[C5F1]]
sum += i; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = [[C5F1]]
i++;
}

return sum;
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = [[C5E:#3]]
return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C5E]]
}

// CHECK-NEXT: testFor
int testFor() { // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+13]]:2 = #0
// CHECK-NEXT: File 0, [[@LINE+7]]:19 -> [[@LINE+7]]:25 = #1
// CHECK-NEXT: File 0, [[@LINE+6]]:27 -> [[@LINE+6]]:30 = #2
// CHECK-NEXT: Gap,File 0, [[@LINE+5]]:31 -> [[@LINE+5]]:32 = #3
// CHECK-NEXT: File 0, [[@LINE+4]]:32 -> [[@LINE+6]]:4 = #3
// CHECK-NEXT: File 0, [[@LINE+7]]:3 -> [[@LINE+7]]:13 = #4
int testFor() { // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+12]]:2 = [[C60:#0]]
int i;
int sum = 0;
// CHECK-NEXT: File 0, [[@LINE+2]]:19 -> [[@LINE+2]]:25 = [[C61:#1]]
// CHECK-NEXT: File 0, [[@LINE+1]]:27 -> [[@LINE+1]]:30 = [[C6C:#2]]
for (int i = 0; i < 10; i++) {
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:31 -> [[@LINE-1]]:32 = [[C6B:#3]]
// CHECK-NEXT: File 0, [[@LINE-2]]:32 -> [[@LINE+2]]:4 = [[C6B]]
sum += i;
}

return sum;
return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C6E:#4]]
}

// CHECK-NEXT: testForRange
int testForRange() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+12]]:2 = #0
// CHECK-NEXT: Gap,File 0, [[@LINE+6]]:28 -> [[@LINE+6]]:29 = #1
// CHECK-NEXT: File 0, [[@LINE+5]]:29 -> [[@LINE+7]]:4 = #1
// CHECK-NEXT: File 0, [[@LINE+8]]:3 -> [[@LINE+8]]:13 = #2
int testForRange() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+11]]:2 = [[C70:#0]]
int sum = 0;
int array[] = {1, 2, 3, 4, 5};

for (int element : array) {
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:28 -> [[@LINE-1]]:29 = [[C7B:#1]]
// CHECK-NEXT: File 0, [[@LINE-2]]:29 -> [[@LINE+2]]:4 = [[C7B]]
sum += element;
}

return sum;
return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C7E:#2]]
}

// CHECK-NEXT: testDo
int testDo() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+12]]:2 = #0
// CHECK-NEXT: File 0, [[@LINE+5]]:6 -> [[@LINE+8]]:4 = #1
// CHECK-NEXT: File 0, [[@LINE+7]]:12 -> [[@LINE+7]]:17 = #2
// CHECK-NEXT: File 0, [[@LINE+8]]:3 -> [[@LINE+8]]:13 = #3
int testDo() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+9]]:2 = [[C80:#0]]
int i = 0;
int sum = 0;
do {
do { // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE+3]]:4 = [[C8B:#1]]
sum += i;
i++;
} while (i < 5);
} while (i < 5); // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE]]:17 = [[C8C:#2]]

return sum;
return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C8E:#3]]
}

// CHECK-NEXT: testConditional
int testConditional(int x) { // CHECK-NEXT: File 0, [[@LINE]]:28 -> [[@LINE+8]]:2 = #0
// CHECK-NEXT: File 0, [[@LINE+5]]:15 -> [[@LINE+5]]:22 = #0
// CHECK-NEXT: Gap,File 0, [[@LINE+4]]:24 -> [[@LINE+4]]:25 = #2
// CHECK-NEXT: File 0, [[@LINE+3]]:25 -> [[@LINE+3]]:26 = #2
// CHECK-NEXT: File 0, [[@LINE+2]]:29 -> [[@LINE+2]]:31 = #3
// CHECK-NEXT: File 0, [[@LINE+2]]:2 -> [[@LINE+2]]:15 = #1
int result = (x > 0) ? 1 : -1;
return result;
int testConditional(int x) { // CHECK-NEXT: File 0, [[@LINE]]:28 -> [[@LINE+6]]:2 = [[C90:#0]]
int result = (x > 0) ? 1 : -1; // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE]]:22 = [[C90]]
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:24 -> [[@LINE-1]]:25 = [[C9T:#2]]
// CHECK-NEXT: File 0, [[@LINE-2]]:25 -> [[@LINE-2]]:26 = [[C9T]]
// CHECK-NEXT: File 0, [[@LINE-3]]:29 -> [[@LINE-3]]:31 = [[C9F:#3]]
return result; // CHECK-NEXT: File 0, [[@LINE]]:2 -> [[@LINE]]:15 = [[C9E:#1]]
}
Loading
Loading