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(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 | |
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(format: "%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(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 | |
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(format: "%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(format: "%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(format: "%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(format: "%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(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 | |
116 | static |
117 | int 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 | |
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(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 | |