1 | // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=unreachable | FileCheck %s |
2 | |
3 | void abort() __attribute__((noreturn)); |
4 | |
5 | // CHECK-LABEL: define void @_Z14calls_noreturnv() |
6 | void calls_noreturn() { |
7 | // Check absence ([^#]*) of call site attributes (including noreturn) |
8 | // CHECK: call void @_Z5abortv(){{[^#]*}} |
9 | abort(); |
10 | |
11 | // CHECK: __ubsan_handle_builtin_unreachable |
12 | // CHECK: unreachable |
13 | } |
14 | |
15 | struct A { |
16 | // CHECK: declare void @_Z5abortv() [[EXTERN_FN_ATTR:#[0-9]+]] |
17 | |
18 | // CHECK-LABEL: define linkonce_odr void @_ZN1A5call1Ev |
19 | void call1() { |
20 | // CHECK: call void @_ZN1A16does_not_return2Ev({{.*}}){{[^#]*}} |
21 | does_not_return2(); |
22 | |
23 | // CHECK: __ubsan_handle_builtin_unreachable |
24 | // CHECK: unreachable |
25 | } |
26 | |
27 | // Test static members. Checks are below after `struct A` scope ends. |
28 | static void does_not_return1() __attribute__((noreturn)) { |
29 | abort(); |
30 | } |
31 | |
32 | // CHECK-LABEL: define linkonce_odr void @_ZN1A5call2Ev |
33 | void call2() { |
34 | // CHECK: call void @_ZN1A16does_not_return1Ev(){{[^#]*}} |
35 | does_not_return1(); |
36 | |
37 | // CHECK: __ubsan_handle_builtin_unreachable |
38 | // CHECK: unreachable |
39 | } |
40 | |
41 | // Test calls through pointers to non-static member functions. |
42 | typedef void (A::*MemFn)() __attribute__((noreturn)); |
43 | |
44 | // CHECK-LABEL: define linkonce_odr void @_ZN1A5call3Ev |
45 | void call3() { |
46 | MemFn MF = &A::does_not_return2; |
47 | // CHECK: call void %{{[0-9]+\(.*}}){{[^#]*}} |
48 | (this->*MF)(); |
49 | |
50 | // CHECK: __ubsan_handle_builtin_unreachable |
51 | // CHECK: unreachable |
52 | } |
53 | |
54 | // Test regular members. |
55 | // CHECK-LABEL: define linkonce_odr void @_ZN1A16does_not_return2Ev({{.*}}) |
56 | // CHECK-SAME: [[USER_FN_ATTR:#[0-9]+]] |
57 | void does_not_return2() __attribute__((noreturn)) { |
58 | // CHECK: call void @_Z5abortv(){{[^#]*}} |
59 | abort(); |
60 | |
61 | // CHECK: call void @__ubsan_handle_builtin_unreachable |
62 | // CHECK: unreachable |
63 | |
64 | // CHECK: call void @__ubsan_handle_builtin_unreachable |
65 | // CHECK: unreachable |
66 | } |
67 | }; |
68 | |
69 | // CHECK-LABEL: define linkonce_odr void @_ZN1A16does_not_return1Ev() |
70 | // CHECK-SAME: [[USER_FN_ATTR]] |
71 | // CHECK: call void @_Z5abortv(){{[^#]*}} |
72 | |
73 | void force_irgen() { |
74 | A a; |
75 | a.call1(); |
76 | a.call2(); |
77 | a.call3(); |
78 | } |
79 | |
80 | // `noreturn` should be removed from functions and call sites |
81 | // CHECK-LABEL: attributes |
82 | // CHECK-NOT: [[USER_FN_ATTR]] = { {{.*noreturn.*}} } |
83 | // CHECK-NOT: [[EXTERN_FN_ATTR]] = { {{.*noreturn.*}} } |
84 | |