| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5 |
| // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=integer-divide-by-zero -O3 %s -o - -fsanitize-recover=integer-divide-by-zero | FileCheck %s --check-prefixes=RECOVER |
| // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=integer-divide-by-zero -O3 %s -o - | FileCheck %s --check-prefixes=ABORT |
| |
| // RECOVER: Function Attrs: mustprogress nounwind memory(read, argmem: readwrite, inaccessiblemem: readwrite) |
| // RECOVER-LABEL: define dso_local noundef range(i32 -32768, 32768) i32 @_Z4testRiRs( |
| // RECOVER-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]], ptr noundef nonnull readonly align 2 captures(none) dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { |
| // RECOVER-NEXT: [[ENTRY:.*:]] |
| // RECOVER-NEXT: [[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa [[TBAA2:![0-9]+]] |
| // RECOVER-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[TBAA6:![0-9]+]] |
| // RECOVER-NEXT: [[DOTNOT:%.*]] = icmp eq i16 [[TMP0]], 0 |
| // RECOVER-NEXT: br i1 [[DOTNOT]], label %[[HANDLER_DIVREM_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META9:![0-9]+]] |
| // RECOVER: [[HANDLER_DIVREM_OVERFLOW]]: |
| // RECOVER-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META9]] |
| // RECOVER-NEXT: tail call void @__ubsan_handle_divrem_overflow(ptr nonnull @{{.+}}, i64 [[TMP2]], i64 0) #[[ATTR3:[0-9]+]], !nosanitize [[META9]] |
| // RECOVER-NEXT: br label %[[CONT]], !nosanitize [[META9]] |
| // RECOVER: [[CONT]]: |
| // RECOVER-NEXT: [[CONV:%.*]] = sext i16 [[TMP0]] to i32 |
| // RECOVER-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP1]], [[CONV]] |
| // RECOVER-NEXT: store i32 [[DIV]], ptr [[A]], align 4, !tbaa [[TBAA6]] |
| // RECOVER-NEXT: ret i32 [[CONV]] |
| // |
| // ABORT: Function Attrs: mustprogress nounwind |
| // ABORT-LABEL: define dso_local noundef range(i32 -32768, 32768) i32 @_Z4testRiRs( |
| // ABORT-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]], ptr noundef nonnull readonly align 2 captures(none) dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { |
| // ABORT-NEXT: [[ENTRY:.*:]] |
| // ABORT-NEXT: [[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa [[TBAA2:![0-9]+]] |
| // ABORT-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[TBAA6:![0-9]+]] |
| // ABORT-NEXT: [[DOTNOT:%.*]] = icmp eq i16 [[TMP0]], 0 |
| // ABORT-NEXT: br i1 [[DOTNOT]], label %[[HANDLER_DIVREM_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META9:![0-9]+]] |
| // ABORT: [[HANDLER_DIVREM_OVERFLOW]]: |
| // ABORT-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META9]] |
| // ABORT-NEXT: tail call void @__ubsan_handle_divrem_overflow_abort(ptr nonnull @{{.+}}, i64 [[TMP2]], i64 0) #[[ATTR3:[0-9]+]], !nosanitize [[META9]] |
| // ABORT-NEXT: unreachable, !nosanitize [[META9]] |
| // ABORT: [[CONT]]: |
| // ABORT-NEXT: [[CONV:%.*]] = sext i16 [[TMP0]] to i32 |
| // ABORT-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP1]], [[CONV]] |
| // ABORT-NEXT: store i32 [[DIV]], ptr [[A]], align 4, !tbaa [[TBAA6]] |
| // ABORT-NEXT: ret i32 [[CONV]] |
| // |
| int test(int &a, short &c) { |
| a /= c; |
| return c; |
| } |
| |
| // Make sure that we don't eliminate the call to ubsan handler. |
| // RECOVER: Function Attrs: mustprogress noreturn nounwind memory(read, argmem: none, inaccessiblemem: readwrite) |
| // RECOVER-LABEL: define dso_local noundef i32 @_Z16test_unreachablev( |
| // RECOVER-SAME: ) local_unnamed_addr #[[ATTR2:[0-9]+]] { |
| // RECOVER-NEXT: [[ENTRY:.*:]] |
| // RECOVER-NEXT: tail call void @__ubsan_handle_divrem_overflow(ptr nonnull @{{.+}}, i64 1, i64 0) #[[ATTR3]], !nosanitize [[META9]] |
| // RECOVER-NEXT: unreachable |
| // |
| // ABORT: Function Attrs: mustprogress noreturn nounwind |
| // ABORT-LABEL: define dso_local noundef i32 @_Z16test_unreachablev( |
| // ABORT-SAME: ) local_unnamed_addr #[[ATTR2:[0-9]+]] { |
| // ABORT-NEXT: [[ENTRY:.*:]] |
| // ABORT-NEXT: tail call void @__ubsan_handle_divrem_overflow_abort(ptr nonnull @{{.+}}, i64 1, i64 0) #[[ATTR3]], !nosanitize [[META9]] |
| // ABORT-NEXT: unreachable, !nosanitize [[META9]] |
| // |
| int test_unreachable() { |
| int a = 1; |
| int b = 0; |
| if (a / b) return 1; |
| return 0; |
| } |
| |
| //. |
| // RECOVER: attributes #[[ATTR0]] = { mustprogress nounwind memory(read, argmem: readwrite, inaccessiblemem: readwrite) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } |
| // RECOVER: attributes #[[ATTR1:[0-9]+]] = { memory(argmem: read, inaccessiblemem: readwrite) uwtable } |
| // RECOVER: attributes #[[ATTR2]] = { mustprogress noreturn nounwind memory(read, argmem: none, inaccessiblemem: readwrite) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } |
| // RECOVER: attributes #[[ATTR3]] = { nomerge nounwind } |
| //. |
| // ABORT: attributes #[[ATTR0]] = { mustprogress nounwind "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } |
| // ABORT: attributes #[[ATTR1:[0-9]+]] = { noreturn nounwind uwtable } |
| // ABORT: attributes #[[ATTR2]] = { mustprogress noreturn nounwind "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } |
| // ABORT: attributes #[[ATTR3]] = { nomerge noreturn nounwind } |
| //. |
| // RECOVER: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} |
| // RECOVER: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} |
| // RECOVER: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} |
| // RECOVER: [[META3]] = !{!"short", [[META4:![0-9]+]], i64 0} |
| // RECOVER: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} |
| // RECOVER: [[META5]] = !{!"Simple C++ TBAA"} |
| // RECOVER: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0} |
| // RECOVER: [[META7]] = !{!"int", [[META4]], i64 0} |
| // RECOVER: [[PROF8]] = !{!"branch_weights", i32 1, i32 1048575} |
| // RECOVER: [[META9]] = !{} |
| //. |
| // ABORT: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} |
| // ABORT: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} |
| // ABORT: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} |
| // ABORT: [[META3]] = !{!"short", [[META4:![0-9]+]], i64 0} |
| // ABORT: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} |
| // ABORT: [[META5]] = !{!"Simple C++ TBAA"} |
| // ABORT: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0} |
| // ABORT: [[META7]] = !{!"int", [[META4]], i64 0} |
| // ABORT: [[PROF8]] = !{!"branch_weights", i32 1, i32 1048575} |
| // ABORT: [[META9]] = !{} |
| //. |