Skip to content

Commit 1b3a647

Browse files
committed
[NFC][clang] Add ubsan-handler-merge.c test to show absence of nomerge
This shows that ubsan handlers do not have nomerge attributes, even if -ubsan-unique-trap is enabled. 0d15d46 attaches nomerge but only for trap mode. ubsan-handler-merge.c is equivalent to ubsan-trap-merge.c (1b68b33) but without using trap mode.
1 parent 7d89ebf commit 1b3a647

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// NOTE: Assertions have mostly been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2+
// The most important assertion is the attributes at the end of the file, which
3+
// shows that -ubsan-unique-traps does not attach 'nomerge' to each ubsan handler.
4+
//
5+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 -mllvm -ubsan-unique-traps %s -o - \
6+
// RUN: | FileCheck %s
7+
//
8+
// REQUIRES: x86-registered-target
9+
10+
// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
11+
// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
12+
// CHECK-NEXT: [[ENTRY:.*:]]
13+
// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]]
14+
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
15+
// CHECK-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]]
16+
// CHECK: [[HANDLER_ADD_OVERFLOW]]:
17+
// CHECK-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]]
18+
// CHECK-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP2]], i64 125) #[[ATTR4:[0-9]+]], !nosanitize [[META2]]
19+
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
20+
// CHECK: [[CONT]]:
21+
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
22+
// CHECK-NEXT: ret i32 [[TMP3]]
23+
//
24+
int f(int x) {
25+
return x + 125;
26+
}
27+
28+
// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
29+
// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
30+
// CHECK-NEXT: [[ENTRY:.*:]]
31+
// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]]
32+
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
33+
// CHECK-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
34+
// CHECK: [[HANDLER_ADD_OVERFLOW]]:
35+
// CHECK-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]]
36+
// CHECK-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META2]]
37+
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
38+
// CHECK: [[CONT]]:
39+
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
40+
// CHECK-NEXT: ret i32 [[TMP3]]
41+
//
42+
int g(int x) {
43+
return x + 127;
44+
}
45+
46+
// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h(
47+
// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
48+
// CHECK-NEXT: [[ENTRY:.*:]]
49+
// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]]
50+
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
51+
// CHECK-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
52+
// CHECK: [[HANDLER_ADD_OVERFLOW]]:
53+
// CHECK-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]]
54+
// CHECK-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META2]]
55+
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
56+
// CHECK: [[CONT]]:
57+
// CHECK-NEXT: [[TMP3:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]]
58+
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1, !nosanitize [[META2]]
59+
// CHECK-NEXT: br i1 [[TMP4]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF3]], !nosanitize [[META2]]
60+
// CHECK: [[HANDLER_ADD_OVERFLOW1]]:
61+
// CHECK-NEXT: [[TMP5:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META2]]
62+
// CHECK-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP5]], i64 129) #[[ATTR4]], !nosanitize [[META2]]
63+
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
64+
// CHECK: [[CONT2]]:
65+
// CHECK-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP3]], 0, !nosanitize [[META2]]
66+
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
67+
// CHECK-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP7]], i32 [[TMP6]])
68+
// CHECK-NEXT: ret i32 [[COND]]
69+
//
70+
int h(int x, int y) {
71+
x += 127;
72+
y += 129;
73+
return x < y ? x : y;
74+
}
75+
76+
// CHECK-LABEL: define dso_local noundef i32 @m(
77+
// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
78+
// CHECK-NEXT: [[ENTRY:.*:]]
79+
// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]]
80+
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
81+
// CHECK-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
82+
// CHECK: [[HANDLER_ADD_OVERFLOW_I]]:
83+
// CHECK-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]]
84+
// CHECK-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1]], i64 [[TMP2]], i64 125) #[[ATTR4]], !nosanitize [[META2]]
85+
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
86+
// CHECK: [[F_EXIT]]:
87+
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
88+
// CHECK-NEXT: [[TMP4:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]]
89+
// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1, !nosanitize [[META2]]
90+
// CHECK-NEXT: br i1 [[TMP5]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
91+
// CHECK: [[HANDLER_ADD_OVERFLOW_I2]]:
92+
// CHECK-NEXT: [[TMP6:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META2]]
93+
// CHECK-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2]], i64 [[TMP6]], i64 127) #[[ATTR4]], !nosanitize [[META2]]
94+
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
95+
// CHECK: [[G_EXIT]]:
96+
// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0, !nosanitize [[META2]]
97+
// CHECK-NEXT: [[TMP8:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP3]], i32 [[TMP7]]), !nosanitize [[META2]]
98+
// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1, !nosanitize [[META2]]
99+
// CHECK-NEXT: br i1 [[TMP9]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]]
100+
// CHECK: [[HANDLER_ADD_OVERFLOW]]:
101+
// CHECK-NEXT: [[TMP10:%.*]] = zext i32 [[TMP3]] to i64, !nosanitize [[META2]]
102+
// CHECK-NEXT: [[TMP11:%.*]] = zext i32 [[TMP7]] to i64, !nosanitize [[META2]]
103+
// CHECK-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR4]], !nosanitize [[META2]]
104+
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
105+
// CHECK: [[CONT]]:
106+
// CHECK-NEXT: [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0, !nosanitize [[META2]]
107+
// CHECK-NEXT: ret i32 [[TMP12]]
108+
//
109+
int m(int x, int y) {
110+
return f(x) + g(y);
111+
}
112+
//.
113+
// CHECK: attributes #[[ATTR4]] = { noreturn nounwind }

0 commit comments

Comments
 (0)