[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGen / catch-implicit-signed-integer-truncation-or-sign-change.c
blob758fc85f894f086c96b9cc95129353827ca62329
1 // RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
2 // RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE
3 // RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
4 // RUN: %clang_cc1 -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-trap=implicit-signed-integer-truncation,implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE
6 // CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_INT:.*]] = {{.*}} c"'unsigned int'\00" }
7 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[SIGNED_CHAR:.*]] = {{.*}} c"'signed char'\00" }
8 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_100_SIGNED_TRUNCATION_OR_SIGN_CHANGE:.*]] = {{.*}}, i32 100, i32 10 }, ptr @[[UNSIGNED_INT]], ptr @[[SIGNED_CHAR]], i8 4, i32 0 }
9 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_200_SIGN_CHANGE:.*]] = {{.*}}, i32 200, i32 10 }, ptr @[[UNSIGNED_INT]], ptr @[[SIGNED_CHAR]], i8 3, i32 0 }
10 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_300_SIGN_CHANGE:.*]] = {{.*}}, i32 300, i32 10 }, ptr @[[UNSIGNED_INT]], ptr @[[SIGNED_CHAR]], i8 3, i32 0 }
11 // CHECK-SANITIZE-ANYRECOVER-NEXT: @[[LINE_400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 400, i32 10 }, ptr @[[UNSIGNED_INT]], ptr @[[SIGNED_CHAR]], i8 2, i32 0 }
13 //============================================================================//
14 // Both sanitizers are enabled, and not disabled per-function.
15 //============================================================================//
17 // CHECK-LABEL: @unsigned_int_to_signed_char
18 // CHECK-SAME: i32 noundef %[[SRC:.*]])
19 signed char unsigned_int_to_signed_char(unsigned int src) {
20 // CHECK-NEXT: [[ENTRY:.*]]:
21 // CHECK-NEXT: %[[SRC_ADDR:.*]] = alloca i32
22 // CHECK-NEXT: store i32 %[[SRC]], ptr %[[SRC_ADDR]]
23 // CHECK-NEXT: %[[DST:.*]] = load i32, ptr %[[SRC_ADDR]]
24 // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
25 // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[CONV]], 0, !nosanitize
26 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
27 // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[CONV]] to i32, !nosanitize
28 // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[DST]], !nosanitize
29 // CHECK-SANITIZE-NEXT: %[[BOTHCHECKS:.*]] = and i1 %[[SIGNCHANGECHECK]], %[[TRUNCHECK]], !nosanitize
30 // CHECK-SANITIZE-NEXT: br i1 %[[BOTHCHECKS]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
31 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
32 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
33 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize
34 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(ptr @[[LINE_100_SIGNED_TRUNCATION_OR_SIGN_CHANGE]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
35 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_100_SIGNED_TRUNCATION_OR_SIGN_CHANGE]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
36 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize
37 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
38 // CHECK-SANITIZE: [[CONT]]:
39 // CHECK-NEXT: ret i8 %[[CONV]]
40 // CHECK-NEXT: }
41 #line 100
42 return src;
45 //============================================================================//
46 // Truncation sanitizer is disabled per-function.
47 //============================================================================//
49 // CHECK-LABEL: @unsigned_int_to_signed_char__no_truncation_sanitizer
50 // CHECK-SAME: i32 noundef %[[SRC:.*]])
51 __attribute__((no_sanitize("implicit-integer-truncation"))) signed char
52 unsigned_int_to_signed_char__no_truncation_sanitizer(unsigned int src) {
53 // CHECK-NEXT: [[ENTRY:.*]]:
54 // CHECK-NEXT: %[[SRC_ADDR:.*]] = alloca i32
55 // CHECK-NEXT: store i32 %[[SRC]], ptr %[[SRC_ADDR]]
56 // CHECK-NEXT: %[[DST:.*]] = load i32, ptr %[[SRC_ADDR]]
57 // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
58 // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[CONV]], 0, !nosanitize
59 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
60 // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
61 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
62 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
63 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize
64 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(ptr @[[LINE_200_SIGN_CHANGE]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
65 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_200_SIGN_CHANGE]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
66 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize
67 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
68 // CHECK-SANITIZE: [[CONT]]:
69 // CHECK-NEXT: ret i8 %[[CONV]]
70 // CHECK-NEXT: }
71 #line 200
72 return src;
75 //============================================================================//
76 // Signed truncation sanitizer is disabled per-function.
77 //============================================================================//
79 // CHECK-LABEL: @unsigned_int_to_signed_char__no_signed_truncation_sanitizer
80 // CHECK-SAME: i32 noundef %[[SRC:.*]])
81 __attribute__((no_sanitize("implicit-signed-integer-truncation"))) signed char
82 unsigned_int_to_signed_char__no_signed_truncation_sanitizer(unsigned int src) {
83 // CHECK-NEXT: [[ENTRY:.*]]:
84 // CHECK-NEXT: %[[SRC_ADDR:.*]] = alloca i32
85 // CHECK-NEXT: store i32 %[[SRC]], ptr %[[SRC_ADDR]]
86 // CHECK-NEXT: %[[DST:.*]] = load i32, ptr %[[SRC_ADDR]]
87 // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
88 // CHECK-SANITIZE-NEXT: %[[DST_NEGATIVITYCHECK:.*]] = icmp slt i8 %[[CONV]], 0, !nosanitize
89 // CHECK-SANITIZE-NEXT: %[[SIGNCHANGECHECK:.*]] = icmp eq i1 false, %[[DST_NEGATIVITYCHECK]], !nosanitize
90 // CHECK-SANITIZE-NEXT: br i1 %[[SIGNCHANGECHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
91 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
92 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
93 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize
94 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(ptr @[[LINE_300_SIGN_CHANGE]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
95 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_300_SIGN_CHANGE]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
96 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize
97 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
98 // CHECK-SANITIZE: [[CONT]]:
99 // CHECK-NEXT: ret i8 %[[CONV]]
100 // CHECK-NEXT: }
101 #line 300
102 return src;
105 //============================================================================//
106 // Sign change sanitizer is disabled per-function
107 //============================================================================//
109 // CHECK-LABEL: @unsigned_int_to_signed_char__no_sign_change_sanitizer
110 // CHECK-SAME: i32 noundef %[[SRC:.*]])
111 __attribute__((no_sanitize("implicit-integer-sign-change"))) signed char
112 unsigned_int_to_signed_char__no_sign_change_sanitizer(unsigned int src) {
113 // CHECK-NEXT: [[ENTRY:.*]]:
114 // CHECK-NEXT: %[[SRC_ADDR:.*]] = alloca i32
115 // CHECK-NEXT: store i32 %[[SRC]], ptr %[[SRC_ADDR]]
116 // CHECK-NEXT: %[[DST:.*]] = load i32, ptr %[[SRC_ADDR]]
117 // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
118 // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[CONV]] to i32, !nosanitize
119 // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[DST]], !nosanitize
120 // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
121 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
122 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[DST]] to i64, !nosanitize
123 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTCONV:.*]] = zext i8 %[[CONV]] to i64, !nosanitize
124 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(ptr @[[LINE_400_SIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
125 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_400_SIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTCONV]]){{.*}}, !nosanitize
126 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize
127 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
128 // CHECK-SANITIZE: [[CONT]]:
129 // CHECK-NEXT: ret i8 %[[CONV]]
130 // CHECK-NEXT: }
131 #line 400
132 return src;
135 //============================================================================//
136 // Both sanitizers are disabled per-function.
137 //============================================================================//
139 // CHECK-LABEL: @unsigned_int_to_signed_char__no_sanitizers
140 // CHECK-SAME: i32 noundef %[[SRC:.*]])
141 __attribute__((no_sanitize("implicit-integer-truncation"),
142 no_sanitize("implicit-integer-sign-change"))) signed char
143 unsigned_int_to_signed_char__no_sanitizers(unsigned int src) {
144 // CHECK-NEXT: [[ENTRY:.*]]:
145 // CHECK-NEXT: %[[SRC_ADDR:.*]] = alloca i32
146 // CHECK-NEXT: store i32 %[[SRC]], ptr %[[SRC_ADDR]]
147 // CHECK-NEXT: %[[DST:.*]] = load i32, ptr %[[SRC_ADDR]]
148 // CHECK-NEXT: %[[CONV:.*]] = trunc i32 %[[DST]] to i8
149 // CHECK-NEXT: ret i8 %[[CONV]]
150 // CHECK-NEXT: }
151 return src;