blob: 48f1b833076609452d308bc69f23fc0618a1c483 [file] [log] [blame]
// 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]] = !{}
//.