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
35static __attribute__((noinline)) int do_throw(bool b) {
36 if (b)
37 throw b;
38 return 1;
39}
40
41// clang-format off
42static
43int test_no_exception() { // CHECK: [[@LINE]]| 1|int test_no_exception()
44 try { // CHECK: [[@LINE]]| 1| try {
45 do_throw(b: false); // CHECK: [[@LINE]]| 1| do_throw(
46 } catch (...) { // CHECK: [[@LINE]]| 1| } catch (
47 abort(); // CHECK: [[@LINE]]| 0| abort(
48 } // CHECK: [[@LINE]]| 0| }
49 printf(format: "%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
50 return 0; // CHECK: [[@LINE]]| 1| return
51} // CHECK: [[@LINE]]| 1|}
52
53static
54int 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(format: "%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
57 return 0; // CHECK: [[@LINE]]| 1| return
58} // CHECK: [[@LINE]]| 1|}
59
60static
61int test_exception() { // CHECK: [[@LINE]]| 1|int test_exception()
62 try { // CHECK: [[@LINE]]| 1| try {
63 do_throw(b: true); // CHECK: [[@LINE]]| 1| do_throw(
64 } catch (...) { // CHECK: [[@LINE]]| 1| } catch (
65 printf(format: "%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
66 } // CHECK: [[@LINE]]| 1| }
67 return 0; // CHECK: [[@LINE]]| 1| return
68} // CHECK: [[@LINE]]| 1|}
69
70static
71int 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(format: "%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
74 return 0; // CHECK: [[@LINE]]| 1| return
75} // CHECK: [[@LINE]]| 1|}
76
77static
78int 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(format: "%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
85 return 0; // CHECK: [[@LINE]]| 1| return
86} // CHECK: [[@LINE]]| 1|}
87
88static
89int 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(format: "%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
92 return 0; // CHECK: [[@LINE]]| 1| return
93} // CHECK: [[@LINE]]| 1|}
94
95static
96int 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(format: "%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
99 return 0; // CHECK: [[@LINE]]| 1| return
100} // CHECK: [[@LINE]]| 1|}
101
102static
103int 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(format: "%s\n", __func__); // CHECK: [[@LINE]]| 1| printf(
107 } else { // CHECK: [[@LINE]]| 1| } else {
108 do_throw(b: 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
116static
117int test_multiple_catch() { // CHECK: [[@LINE]]| 1|int test_multiple_catch()
118 try { // CHECK: [[@LINE]]| 1| try {
119 do_throw(b: 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(format: "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
132int 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(i: 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
145

source code of compiler-rt/test/profile/Linux/coverage-exception.cpp