Skip to content

Commit 0931874

Browse files
authored
[Coverage] Add testing to validate code coverage for exceptions (#133463)
While investigating an issue with code coverage reporting around exceptions it was useful to have a baseline of what works today. This change adds end-to-end testing to validate code coverage behavior that is currently working with regards to exception handling.
1 parent 51e222e commit 0931874

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// REQUIRES: lld-available
2+
// XFAIL: powerpc64-target-arch
3+
4+
// RUN: %clangxx_profgen -std=c++17 -fuse-ld=lld -fcoverage-mapping -o %t %s
5+
// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
6+
// RUN: llvm-profdata merge -o %t.profdata %t.profraw
7+
// RUN: llvm-cov show %t -instr-profile=%t.profdata 2>&1 | FileCheck %s
8+
9+
#include <stdio.h>
10+
#include <stdlib.h>
11+
12+
#define TRY_AND_CATCH_ALL(x) \
13+
try { \
14+
(x); \
15+
} catch (...) { \
16+
}
17+
18+
#define TRY_MAYBE_CRASH(x) \
19+
try { \
20+
if ((x)) { \
21+
printf("no crash\n"); \
22+
} else { \
23+
abort(); \
24+
} \
25+
} catch (...) { \
26+
}
27+
28+
#define TRY_AND_CATCH_CRASHES(x) \
29+
try { \
30+
(x); \
31+
} catch (...) { \
32+
abort(); \
33+
}
34+
35+
static __attribute__((noinline)) int do_throw(bool b) {
36+
if (b)
37+
throw b;
38+
return 1;
39+
}
40+
41+
// clang-format off
42+
static
43+
int test_no_exception() { // CHECK: [[@LINE]]| 1|int test_no_exception()
44+
try { // CHECK: [[@LINE]]| 1| try {
45+
do_throw(false); // CHECK: [[@LINE]]| 1| do_throw(
46+
} catch (...) { // CHECK: [[@LINE]]| 1| } catch (
47+
abort(); // CHECK: [[@LINE]]| 0| abort(
48+
} // CHECK: [[@LINE]]| 0| }
49+
printf("%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
50+
return 0; // CHECK: [[@LINE]]| 1| return
51+
} // CHECK: [[@LINE]]| 1|}
52+
53+
static
54+
int test_no_exception_macro() { // CHECK: [[@LINE]]| 1|int test_no_exception_macro()
55+
TRY_AND_CATCH_ALL(do_throw(false)); // CHECK: [[@LINE]]| 1| TRY_AND_CATCH_ALL(
56+
printf("%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
57+
return 0; // CHECK: [[@LINE]]| 1| return
58+
} // CHECK: [[@LINE]]| 1|}
59+
60+
static
61+
int test_exception() { // CHECK: [[@LINE]]| 1|int test_exception()
62+
try { // CHECK: [[@LINE]]| 1| try {
63+
do_throw(true); // CHECK: [[@LINE]]| 1| do_throw(
64+
} catch (...) { // CHECK: [[@LINE]]| 1| } catch (
65+
printf("%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
66+
} // CHECK: [[@LINE]]| 1| }
67+
return 0; // CHECK: [[@LINE]]| 1| return
68+
} // CHECK: [[@LINE]]| 1|}
69+
70+
static
71+
int test_exception_macro() { // CHECK: [[@LINE]]| 1|int test_exception_macro()
72+
TRY_AND_CATCH_ALL(do_throw(true)); // CHECK: [[@LINE]]| 1| TRY_AND_CATCH_ALL(
73+
printf("%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
74+
return 0; // CHECK: [[@LINE]]| 1| return
75+
} // CHECK: [[@LINE]]| 1|}
76+
77+
static
78+
int test_exception_macro_nested() { // CHECK: [[@LINE]]| 1|int test_exception_macro_nested()
79+
try { // CHECK: [[@LINE]]| 1| try {
80+
TRY_AND_CATCH_ALL(do_throw(true)); // CHECK: [[@LINE]]| 1| TRY_AND_CATCH_ALL(
81+
} catch (...) { // CHECK: [[@LINE]]| 1| } catch (
82+
abort(); // CHECK: [[@LINE]]| 0| abort(
83+
} // CHECK: [[@LINE]]| 0| }
84+
printf("%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
85+
return 0; // CHECK: [[@LINE]]| 1| return
86+
} // CHECK: [[@LINE]]| 1|}
87+
88+
static
89+
int test_exception_try_crash() { // CHECK: [[@LINE]]| 1|int test_exception_try_crash()
90+
TRY_MAYBE_CRASH(do_throw(false)); // CHECK: [[@LINE]]| 1| TRY_MAYBE_CRASH(
91+
printf("%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
92+
return 0; // CHECK: [[@LINE]]| 1| return
93+
} // CHECK: [[@LINE]]| 1|}
94+
95+
static
96+
int test_exception_crash() { // CHECK: [[@LINE]]| 1|int test_exception_crash()
97+
TRY_AND_CATCH_CRASHES(do_throw(false)); // CHECK: [[@LINE]]| 1| TRY_AND_CATCH_CRASHES(
98+
printf("%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
99+
return 0; // CHECK: [[@LINE]]| 1| return
100+
} // CHECK: [[@LINE]]| 1|}
101+
102+
static
103+
int test_conditional(int i) { // CHECK: [[@LINE]]| 1|int test_conditional(int i)
104+
try { // CHECK: [[@LINE]]| 1| try {
105+
if (i % 2 == 0) { // CHECK: [[@LINE]]| 1| if (
106+
printf("%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
107+
} else { // CHECK: [[@LINE]]| 1| } else {
108+
do_throw(true); // CHECK: [[@LINE]]| 0| do_throw(
109+
} // CHECK: [[@LINE]]| 0| }
110+
} catch (...) { // CHECK: [[@LINE]]| 1| } catch (
111+
abort(); // CHECK: [[@LINE]]| 0| abort(
112+
} // CHECK: [[@LINE]]| 0| }
113+
return 0; // CHECK: [[@LINE]]| 1| return
114+
}
115+
116+
static
117+
int test_multiple_catch() { // CHECK: [[@LINE]]| 1|int test_multiple_catch()
118+
try { // CHECK: [[@LINE]]| 1| try {
119+
do_throw(true); // CHECK: [[@LINE]]| 1| do_throw(
120+
} catch (double) { // CHECK: [[@LINE]]| 1| } catch (double)
121+
abort(); // CHECK: [[@LINE]]| 0| abort(
122+
} catch (bool) { // CHECK: [[@LINE]]| 1| } catch (bool)
123+
printf("bool\n"); // CHECK: [[@LINE]]| 1| printf(
124+
} catch (float) { // CHECK: [[@LINE]]| 1| } catch (float)
125+
abort(); // CHECK: [[@LINE]]| 0| abort(
126+
} catch (...) { // CHECK: [[@LINE]]| 0| } catch (
127+
abort(); // CHECK: [[@LINE]]| 0| abort(
128+
} // CHECK: [[@LINE]]| 0| }
129+
return 0; // CHECK: [[@LINE]]| 1| return
130+
} // CHECK: [[@LINE]]| 1|}
131+
132+
int main() { // CHECK: [[@LINE]]| 1|int main()
133+
test_no_exception(); // CHECK: [[@LINE]]| 1| test_no_exception(
134+
test_no_exception_macro(); // CHECK: [[@LINE]]| 1| test_no_exception_macro(
135+
test_exception(); // CHECK: [[@LINE]]| 1| test_exception(
136+
test_exception_macro(); // CHECK: [[@LINE]]| 1| test_exception_macro(
137+
test_exception_macro_nested(); // CHECK: [[@LINE]]| 1| test_exception_macro_nested(
138+
test_exception_try_crash(); // CHECK: [[@LINE]]| 1| test_exception_try_crash(
139+
test_exception_crash(); // CHECK: [[@LINE]]| 1| test_exception_crash(
140+
test_conditional(2); // CHECK: [[@LINE]]| 1| test_conditional(
141+
test_multiple_catch(); // CHECK: [[@LINE]]| 1| test_multiple_catch(
142+
return 0; // CHECK: [[@LINE]]| 1| return
143+
} // CHECK: [[@LINE]]| 1|}
144+
// clang-format on

0 commit comments

Comments
 (0)