Skip to content

Commit 747b0e2

Browse files
committedSep 8, 2017
[Coverage] Precise region termination with deferred regions (reapply)
The current coverage implementation doesn't handle region termination very precisely. Take for example an `if' statement with a `return': void f() { if (true) { return; // The `if' body's region is terminated here. } // This line gets the same coverage as the `if' condition. } If the function `f' is called, the line containing the comment will be marked as having executed once, which is not correct. The solution here is to create a deferred region after terminating a region. The deferred region is completed once the start location of the next statement is known, and is then pushed onto the region stack. In the cases where it's not possible to complete a deferred region, it can safely be dropped. Testing: lit test updates, a stage2 coverage-enabled build of clang This is a reapplication but there are no changes from the original commit. With D36813, the segment builder in llvm will be able to handle deferred regions correctly. llvm-svn: 312818
1 parent 79a1b5e commit 747b0e2

File tree

8 files changed

+276
-22
lines changed

8 files changed

+276
-22
lines changed
 

‎clang/lib/CodeGen/CoverageMappingGen.cpp

+86-5
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,14 @@ class SourceMappingRegion {
4545
/// \brief The region's ending location.
4646
Optional<SourceLocation> LocEnd;
4747

48+
/// Whether this region should be emitted after its parent is emitted.
49+
bool DeferRegion;
50+
4851
public:
4952
SourceMappingRegion(Counter Count, Optional<SourceLocation> LocStart,
50-
Optional<SourceLocation> LocEnd)
51-
: Count(Count), LocStart(LocStart), LocEnd(LocEnd) {}
53+
Optional<SourceLocation> LocEnd, bool DeferRegion = false)
54+
: Count(Count), LocStart(LocStart), LocEnd(LocEnd),
55+
DeferRegion(DeferRegion) {}
5256

5357
const Counter &getCounter() const { return Count; }
5458

@@ -71,6 +75,10 @@ class SourceMappingRegion {
7175
assert(LocEnd && "Region has no end location");
7276
return *LocEnd;
7377
}
78+
79+
bool isDeferred() const { return DeferRegion; }
80+
81+
void setDeferred(bool Deferred) { DeferRegion = Deferred; }
7482
};
7583

7684
/// Spelling locations for the start and end of a source region.
@@ -409,6 +417,10 @@ struct CounterCoverageMappingBuilder
409417
/// \brief A stack of currently live regions.
410418
std::vector<SourceMappingRegion> RegionStack;
411419

420+
/// The currently deferred region: its end location and count can be set once
421+
/// its parent has been popped from the region stack.
422+
Optional<SourceMappingRegion> DeferredRegion;
423+
412424
CounterExpressionBuilder Builder;
413425

414426
/// \brief A location in the most recently visited file or macro.
@@ -444,19 +456,60 @@ struct CounterCoverageMappingBuilder
444456
/// used with popRegions to exit a "scope", ending the region that was pushed.
445457
size_t pushRegion(Counter Count, Optional<SourceLocation> StartLoc = None,
446458
Optional<SourceLocation> EndLoc = None) {
447-
if (StartLoc)
459+
if (StartLoc) {
448460
MostRecentLocation = *StartLoc;
461+
completeDeferred(Count, MostRecentLocation);
462+
}
449463
RegionStack.emplace_back(Count, StartLoc, EndLoc);
450464

451465
return RegionStack.size() - 1;
452466
}
453467

468+
/// Complete any pending deferred region by setting its end location and
469+
/// count, and then pushing it onto the region stack.
470+
size_t completeDeferred(Counter Count, SourceLocation DeferredEndLoc) {
471+
size_t Index = RegionStack.size();
472+
if (!DeferredRegion)
473+
return Index;
474+
475+
// Consume the pending region.
476+
SourceMappingRegion DR = DeferredRegion.getValue();
477+
DeferredRegion = None;
478+
479+
// If the region ends in an expansion, find the expansion site.
480+
if (SM.getFileID(DeferredEndLoc) != SM.getMainFileID()) {
481+
FileID StartFile = SM.getFileID(DR.getStartLoc());
482+
if (isNestedIn(DeferredEndLoc, StartFile)) {
483+
do {
484+
DeferredEndLoc = getIncludeOrExpansionLoc(DeferredEndLoc);
485+
} while (StartFile != SM.getFileID(DeferredEndLoc));
486+
}
487+
}
488+
489+
// The parent of this deferred region ends where the containing decl ends,
490+
// so the region isn't useful.
491+
if (DR.getStartLoc() == DeferredEndLoc)
492+
return Index;
493+
494+
// If we're visiting statements in non-source order (e.g switch cases or
495+
// a loop condition) we can't construct a sensible deferred region.
496+
if (!SpellingRegion(SM, DR.getStartLoc(), DeferredEndLoc).isInSourceOrder())
497+
return Index;
498+
499+
DR.setCounter(Count);
500+
DR.setEndLoc(DeferredEndLoc);
501+
handleFileExit(DeferredEndLoc);
502+
RegionStack.push_back(DR);
503+
return Index;
504+
}
505+
454506
/// \brief Pop regions from the stack into the function's list of regions.
455507
///
456508
/// Adds all regions from \c ParentIndex to the top of the stack to the
457509
/// function's \c SourceRegions.
458510
void popRegions(size_t ParentIndex) {
459511
assert(RegionStack.size() >= ParentIndex && "parent not in stack");
512+
bool ParentOfDeferredRegion = false;
460513
while (RegionStack.size() > ParentIndex) {
461514
SourceMappingRegion &Region = RegionStack.back();
462515
if (Region.hasStartLoc()) {
@@ -488,9 +541,26 @@ struct CounterCoverageMappingBuilder
488541

489542
assert(SM.isWrittenInSameFile(Region.getStartLoc(), EndLoc));
490543
SourceRegions.push_back(Region);
544+
545+
if (ParentOfDeferredRegion) {
546+
ParentOfDeferredRegion = false;
547+
548+
// If there's an existing deferred region, keep the old one, because
549+
// it means there are two consecutive returns (or a similar pattern).
550+
if (!DeferredRegion.hasValue() &&
551+
// File IDs aren't gathered within macro expansions, so it isn't
552+
// useful to try and create a deferred region inside of one.
553+
(SM.getFileID(EndLoc) == SM.getMainFileID()))
554+
DeferredRegion =
555+
SourceMappingRegion(Counter::getZero(), EndLoc, None);
556+
}
557+
} else if (Region.isDeferred()) {
558+
assert(!ParentOfDeferredRegion && "Consecutive deferred regions");
559+
ParentOfDeferredRegion = true;
491560
}
492561
RegionStack.pop_back();
493562
}
563+
assert(!ParentOfDeferredRegion && "Deferred region with no parent");
494564
}
495565

496566
/// \brief Return the currently active region.
@@ -617,6 +687,8 @@ struct CounterCoverageMappingBuilder
617687
handleFileExit(StartLoc);
618688
if (!Region.hasStartLoc())
619689
Region.setStartLoc(StartLoc);
690+
691+
completeDeferred(Region.getCounter(), StartLoc);
620692
}
621693

622694
/// \brief Mark \c S as a terminator, starting a zero region.
@@ -626,6 +698,7 @@ struct CounterCoverageMappingBuilder
626698
if (!Region.hasEndLoc())
627699
Region.setEndLoc(getEnd(S));
628700
pushRegion(Counter::getZero());
701+
getRegion().setDeferred(true);
629702
}
630703

631704
/// \brief Keep counts of breaks and continues inside loops.
@@ -639,13 +712,15 @@ struct CounterCoverageMappingBuilder
639712
CoverageMappingModuleGen &CVM,
640713
llvm::DenseMap<const Stmt *, unsigned> &CounterMap, SourceManager &SM,
641714
const LangOptions &LangOpts)
642-
: CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {}
715+
: CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap),
716+
DeferredRegion(None) {}
643717

644718
/// \brief Write the mapping data to the output stream
645719
void write(llvm::raw_ostream &OS) {
646720
llvm::SmallVector<unsigned, 8> VirtualFileMapping;
647721
gatherFileIDs(VirtualFileMapping);
648722
SourceRegionFilter Filter = emitExpansionRegions();
723+
assert(!DeferredRegion && "Deferred region never completed");
649724
emitSourceRegions(Filter);
650725
gatherSkippedRegions();
651726

@@ -667,13 +742,19 @@ struct CounterCoverageMappingBuilder
667742
}
668743

669744
void VisitDecl(const Decl *D) {
745+
assert(!DeferredRegion && "Deferred region never completed");
746+
670747
Stmt *Body = D->getBody();
671748

672749
// Do not propagate region counts into system headers.
673750
if (Body && SM.isInSystemHeader(SM.getSpellingLoc(getStart(Body))))
674751
return;
675752

676-
propagateCounts(getRegionCounter(Body), Body);
753+
Counter ExitCount = propagateCounts(getRegionCounter(Body), Body);
754+
assert(RegionStack.empty() && "Regions entered but never exited");
755+
756+
// Complete any deferred regions introduced by the last statement in a decl.
757+
popRegions(completeDeferred(ExitCount, getEnd(Body)));
677758
}
678759

679760
void VisitReturnStmt(const ReturnStmt *S) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// RUN: %clang_cc1 -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -fexceptions -fcxx-exceptions -emit-llvm-only -triple %itanium_abi_triple -main-file-name deferred-region.cpp %s | FileCheck %s
2+
3+
#define IF if
4+
#define STMT(S) S
5+
6+
// CHECK-LABEL: _Z3fooi:
7+
void foo(int x) {
8+
if (x == 0) {
9+
return;
10+
} // CHECK: [[@LINE]]:4 -> [[@LINE+2]]:2 = (#0 - #1)
11+
12+
}
13+
14+
// CHECK-NEXT: _Z4foooi:
15+
void fooo(int x) {
16+
if (x == 0) {
17+
return;
18+
} // CHECK: [[@LINE]]:4 -> [[@LINE+2]]:3 = (#0 - #1)
19+
20+
if (x == 1) {
21+
return;
22+
} // CHECK: [[@LINE]]:4 -> [[@LINE+2]]:2 = ((#0 - #1) - #2)
23+
24+
}
25+
26+
// CHECK-LABEL: _Z3bazv:
27+
void baz() { // CHECK: [[@LINE]]:12 -> [[@LINE+2]]:2
28+
return; // CHECK-NOT: File
29+
}
30+
31+
// CHECK-LABEL: _Z3bari:
32+
void bar(int x) {
33+
IF (x)
34+
return; // CHECK: [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
35+
36+
IF (!x)
37+
return; // CHECK: [[@LINE]]:11 -> [[@LINE+2]]:3 = ((#0 - #1) - #2)
38+
39+
foo(x);
40+
}
41+
42+
// CHECK-LABEL: _Z4quuxi:
43+
// Deferred regions are not emitted within macro expansions.
44+
void quux(int x) {
45+
STMT(
46+
if (x == 0)
47+
return;)
48+
49+
// CHECK-NOT: [[@LINE-2]]:{{.*}} -> [[@LINE+2]]
50+
51+
if (x == 1)
52+
STMT(return;)
53+
54+
// CHECK-NOT: [[@LINE-2]]:{{.*}} -> [[@LINE+3]]
55+
56+
STMT(
57+
if (x == 2)
58+
return;
59+
60+
// CHECK-NOT: [[@LINE-2]]:{{.*}} -> [[@LINE+2]]
61+
62+
if (x == 3)
63+
return;
64+
)
65+
}
66+
67+
// CHECK-LABEL: _Z8weird_ifv:
68+
void weird_if() {
69+
int i = 0;
70+
71+
if (false)
72+
return; // CHECK: [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
73+
74+
if (false)
75+
i++;
76+
77+
if (i + 100 > 0) { // CHECK: [[@LINE]]:20 -> [[@LINE+6]]:4 = #3
78+
if (false) // CHECK: [[@LINE+1]]:7 -> [[@LINE+1]]:13 = #4
79+
return; // CHECK: [[@LINE]]:13 -> [[@LINE+2]]:5 = (#3 - #4)
80+
// CHECK: [[@LINE+1]]:5 -> [[@LINE+3]]:4 = (#3 - #4)
81+
return; // CHECK: [[@LINE]]:5 -> [[@LINE+4]]:3 = ((#0 - #1) - #3)
82+
83+
}
84+
85+
if (false)
86+
return;
87+
}
88+
89+
// CHECK-LABEL: _Z8for_loopv:
90+
void for_loop() {
91+
if (false)
92+
return; // CHECK: [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
93+
94+
for (int i = 0; i < 10; ++i) {
95+
if (i % 2 == 0)
96+
continue; // CHECK: [[@LINE]]:15 -> [[@LINE+2]]:5 = (#2 - #3)
97+
98+
if (i % 5 == 0)
99+
break; // CHECK: [[@LINE]]:12 -> [[@LINE+2]]:5 = ((#2 - #3) - #4)
100+
101+
int x = i; // CHECK: [[@LINE]]:5 -> [[@LINE+3]]:4 = ((#2 - #3) - #4)
102+
return; // CHECK-NOT: [[@LINE]]:11 -> [[@LINE+2]]
103+
104+
}
105+
}
106+
107+
struct Error {};
108+
109+
// CHECK-LABEL: _Z10while_loopv:
110+
void while_loop() {
111+
if (false)
112+
return; // CHECK: [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
113+
114+
int x = 0;
115+
while (++x < 10) {
116+
if (x == 1)
117+
continue; // CHECK: [[@LINE]]:15 -> [[@LINE+2]]:5 = (#2 - #3)
118+
119+
while (++x < 4) {
120+
if (x == 3)
121+
break; // CHECK: [[@LINE]]:14 -> [[@LINE+2]]:7 = (#4 - #5)
122+
123+
while (++x < 5) {}
124+
}
125+
126+
if (x == 0)
127+
throw Error(); // CHECK: [[@LINE]]:20 -> [[@LINE+2]]:5 = ((#2 - #3) - #7)
128+
129+
while (++x < 9) {
130+
if (x == 0)
131+
break; // CHECK-NOT: [[@LINE]]:14 -> [[@LINE+2]]
132+
133+
}
134+
}
135+
}
136+
137+
// CHECK-LABEL: _Z5gotosv:
138+
void gotos() {
139+
if (false)
140+
goto out; // CHECK: [[@LINE]]:13 -> [[@LINE+2]]:3 = (#0 - #1)
141+
142+
return; // CHECK: [[@LINE]]:3 -> [[@LINE+4]]:2 = (#0 - #1)
143+
144+
out:
145+
return; // CHECK: [[@LINE]]:8 -> [[@LINE+1]]:2 = 0
146+
}
147+
148+
int main() {
149+
foo(0);
150+
foo(1);
151+
fooo(0);
152+
fooo(1);
153+
baz();
154+
bar(0);
155+
bar(1);
156+
quux(0);
157+
quux(1);
158+
quux(2);
159+
quux(3);
160+
weird_if();
161+
for_loop();
162+
while_loop();
163+
gotos();
164+
return 0;
165+
}

‎clang/test/CoverageMapping/label.cpp

+16-9
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,22 @@ void func() { // CHECK-NEXT: File 0, [[@LINE]]:13 -> {{[0-9]+}}:2
1414
int m = 2;
1515
} else
1616
goto x; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = (#1 - #2)
17-
int k = 3; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+1]]:4 = #3
18-
}
19-
static int j = 0; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+4]]:2 = ((#0 + #3) - #1)
17+
int k = 3; // CHECK-NEXT: File 0, [[@LINE-1]]:13 -> [[@LINE]]:5 = #3
18+
} // CHECK-NEXT: File 0, [[@LINE-1]]:5 -> [[@LINE]]:4 = #3
19+
static int j = 0; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+5]]:2 = ((#0 + #3) - #1)
2020
++j;
2121
if(j == 1) // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:12 = ((#0 + #3) - #1)
2222
goto x; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #4
23+
// CHECK-NEXT: File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:2 = (((#0 + #3) - #1) - #4)
2324
}
2425

2526
// CHECK-NEXT: test1
2627
void test1(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> {{[0-9]+}}:2 = #0
2728
if(x == 0) // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:12 = #0
2829
goto a; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #1
29-
goto b; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:9 = (#0 - #1)
30+
// CHECK-NEXT: File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = (#0 - #1)
31+
goto b; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+5]]:2 = (#0 - #1)
32+
// CHECK-NEXT: File 0, [[@LINE-1]]:3 -> [[@LINE+4]]:2 = #3
3033
a: // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+3]]:2 = #2
3134
b: // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+2]]:2 = #3
3235
x = x + 1;
@@ -36,9 +39,11 @@ void test1(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> {{[0-9]+}}:2
3639
void test2(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> {{[0-9]+}}:2 = #0
3740
if(x == 0) // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:12 = #0
3841
goto a; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #1
39-
// CHECK-NEXT: File 0, [[@LINE+2]]:8 -> [[@LINE+2]]:25 = (#0 - #1)
42+
// CHECK-NEXT: File 0, [[@LINE-1]]:11 -> [[@LINE+3]]:8 = #0
43+
// CHECK-NEXT: File 0, [[@LINE+2]]:8 -> [[@LINE+3]]:11 = (#0 - #1)
4044
// CHECK-NEXT: File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:17 = (#0 - #1)
41-
else if(x == 1) goto b; // CHECK-NEXT: File 0, [[@LINE]]:19 -> [[@LINE]]:25 = #2
45+
else if(x == 1) // CHECK-NEXT: File 0, [[@LINE+1]]:5 -> [[@LINE+1]]:11 = #2
46+
goto b; // CHECK-NEXT: File 0, [[@LINE]]:11 -> [[@LINE+1]]:1 = #3
4247
a: // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+3]]:2 = #3
4348
b: // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+2]]:2 = #4
4449
x = x + 1;
@@ -47,11 +52,13 @@ void test2(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> {{[0-9]+}}:2
4752
// CHECK-NEXT: main
4853
int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0
4954
int j = 0;
50-
for(int i = 0; i < 10; ++i) { // CHECK: File 0, [[@LINE]]:31 -> [[@LINE+11]]:4 = #1
51-
a: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+10]]:4 = #2
55+
for(int i = 0; i < 10; ++i) { // CHECK: File 0, [[@LINE]]:31 -> [[@LINE+13]]:4 = #1
56+
a: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+12]]:4 = #2
5257
if(i < 3) // CHECK-NEXT: File 0, [[@LINE]]:8 -> [[@LINE]]:13 = #2
5358
goto e; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = #3
54-
goto c; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = (#2 - #3)
59+
// CHECK-NEXT: File 0, [[@LINE-1]]:13 -> [[@LINE+1]]:5 = (#2 - #3)
60+
goto c; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+8]]:4 = (#2 - #3)
61+
5562
b: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+6]]:4 = #4
5663
j = 2;
5764
c: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+4]]:4 = #5

‎clang/test/CoverageMapping/moremacros.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,23 @@ int main(int argc, const char *argv[]) {
1515
if (!argc) LBRAC
1616
return 0;
1717
// CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #2
18-
RBRAC
18+
RBRAC // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE+6]]:3 = (#0 - #2)
1919

2020
// CHECK-NEXT: File 0, [[@LINE+4]]:3 -> [[@LINE+15]]:2 = (#0 - #2)
2121
// CHECK-NEXT: File 0, [[@LINE+3]]:7 -> [[@LINE+3]]:12 = (#0 - #2)
2222
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:19 = #3
2323
// CHECK-NEXT: File 0, [[@LINE+1]]:19 -> [[@LINE+3]]:4 = #3
2424
if (!argc) LBRAC
2525
return 0;
26-
}
26+
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+5]]:3 = ((#0 - #2) - #3)
2727

2828
// CHECK-NEXT: File 0, [[@LINE+3]]:3 -> [[@LINE+7]]:2 = ((#0 - #2) - #3)
2929
// CHECK-NEXT: File 0, [[@LINE+2]]:7 -> [[@LINE+2]]:12 = ((#0 - #2) - #3)
3030
// CHECK-NEXT: File 0, [[@LINE+1]]:14 -> [[@LINE+4]]:8 = #4
3131
if (!argc) {
3232
return 0;
3333
// CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #4
34-
RBRAC
34+
RBRAC // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE+1]]:2 = (((#0 - #2) - #3) - #4)
3535
}
3636

3737
// CHECK-NEXT: File 1, 3:15 -> 3:16 = #2

‎clang/test/CoverageMapping/return.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ void func2() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> {{[0-9]+}
1313
for(int i = 0; i < 10; ++i) { // CHECK-NEXT: File 0, [[@LINE]]:31 -> {{[0-9]+}}:4 = #1
1414
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:13 = #1
1515
if(i > 2) { // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+2]]:6 = #2
16-
return;
16+
return; // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+3]]:5 = (#1 - #2)
1717
} // CHECK-NEXT: File 0, [[@LINE+2]]:5 -> {{[0-9]+}}:4 = (#1 - #2)
1818
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:14 = (#1 - #2)
1919
if(i == 3) { // CHECK-NEXT: File 0, [[@LINE]]:16 -> [[@LINE+2]]:6 = #3

‎clang/test/CoverageMapping/switch.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ void foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+8]]:2 = #0
66
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:11 = #2
77
return;
88
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #3
9-
break;
9+
break; // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+2]]:3 = #1
1010
}
1111
int x = 0; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:2 = #1
1212
}
@@ -55,7 +55,7 @@ int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+35]]:2 = #0
5555
i = 2;
5656
break;
5757
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #4
58-
break;
58+
break; // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+2]]:3 = #1
5959
}
6060
switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+23]]:2 = #1
6161
case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #6
@@ -64,7 +64,7 @@ int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+35]]:2 = #0
6464
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = #7
6565
i = 2;
6666
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = (#7 + #8)
67-
break;
67+
break; // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+3]]:3 = #5
6868
}
6969

7070
switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+13]]:2 = #5

‎clang/test/CoverageMapping/switchmacro.c

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ int foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:16 -> {{[0-9]+}}:2 = #0
88
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> {{[0-9]+}}:11 = #2
99
if (i == 1) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = #2
1010
return 0; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = #3
11+
// CHECK-NEXT: File 0, [[@LINE-1]]:15 -> [[@LINE+3]]:5 = (#2 - #3)
1112
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:5 -> [[@LINE+2]]:8 = (#2 - #3) (Expanded file = 1)
1213
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> {{[0-9]+}}:11 = (#2 - #3)
1314
FOO(1);

‎clang/test/CoverageMapping/trycatch.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ void func(int i) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> {{[
1818
// CHECK-NEXT: File 0, [[@LINE+1]]:10 -> [[@LINE+2]]:27 = (#0 - #1)
1919
} else if(i == 8) // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE]]:19 = (#0 - #1)
2020
throw ImportantError(); // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:27 = #2
21-
}
21+
} // CHECK-NEXT: File 0, [[@LINE-1]]:27 -> [[@LINE]]:2 = ((#0 - #1) - #2)
2222

2323
// CHECK-NEXT: main
2424
int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+13]]:2 = #0

0 commit comments

Comments
 (0)
Please sign in to comment.