145 lines · cpp
1// REQUIRES: lld-available2// XFAIL: powerpc64-target-arch3 4// RUN: %clangxx_profgen -std=c++17 -fuse-ld=lld -fcoverage-mapping -o %t %s5// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t6// RUN: llvm-profdata merge -o %t.profdata %t.profraw7// RUN: llvm-cov show %t -instr-profile=%t.profdata 2>&1 | FileCheck %s8 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 off42static43int 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| return51} // CHECK: [[@LINE]]| 1|}52 53static54int 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| return58} // CHECK: [[@LINE]]| 1|}59 60static61int 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| return68} // CHECK: [[@LINE]]| 1|}69 70static71int 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| return75} // CHECK: [[@LINE]]| 1|}76 77static78int 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| return86} // CHECK: [[@LINE]]| 1|}87 88static89int 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| return93} // CHECK: [[@LINE]]| 1|}94 95static96int 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| return100} // CHECK: [[@LINE]]| 1|}101 102static103int 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| return114}115 116static117int 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| return130} // 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(2); // CHECK: [[@LINE]]| 1| test_conditional(141 test_multiple_catch(); // CHECK: [[@LINE]]| 1| test_multiple_catch(142 return 0; // CHECK: [[@LINE]]| 1| return143} // CHECK: [[@LINE]]| 1|}144// clang-format on145