
We can derive and upgrade alignment for loads/stores using other well-aligned loads/stores. This optimization does a single forward pass through each basic block and uses loads/stores (the alignment and the offset) to derive the best possible alignment for a base pointer, caching the result. If it encounters another load/store based on that pointer, it tries to upgrade the alignment. The optimization must be a forward pass within a basic block because control flow and exception throwing can impact alignment guarantees. --------- Co-authored-by: Nikita Popov <github@npopov.com>
551 lines
37 KiB
C
551 lines
37 KiB
C
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 3
|
|
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -DWITH_ATTRS -Wall -fsanitize=array-bounds,object-size,local-bounds -fstrict-flex-arrays=3 -fexperimental-late-parse-attributes -emit-llvm -o - %s | FileCheck --check-prefix=SANITIZE-WITH-ATTR %s
|
|
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -DWITH_ATTRS -Wall -fstrict-flex-arrays=3 -fexperimental-late-parse-attributes -emit-llvm -o - %s | FileCheck --check-prefix=NO-SANITIZE-WITH-ATTR %s
|
|
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wall -fsanitize=array-bounds,object-size,local-bounds -fstrict-flex-arrays=3 -fexperimental-late-parse-attributes -emit-llvm -o - %s | FileCheck --check-prefix=SANITIZE-WITHOUT-ATTR %s
|
|
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wall -fstrict-flex-arrays=3 -fexperimental-late-parse-attributes -emit-llvm -o - %s | FileCheck --check-prefix=NO-SANITIZE-WITHOUT-ATTR %s
|
|
|
|
#if !__has_attribute(counted_by)
|
|
#error "has attribute broken"
|
|
#endif
|
|
|
|
#ifdef WITH_ATTRS
|
|
#define __counted_by(member) __attribute__((__counted_by__(member)))
|
|
#define __sized_by(member) __attribute__((__sized_by__(member)))
|
|
#else
|
|
#define __counted_by(member)
|
|
#define __sized_by(member)
|
|
#endif
|
|
|
|
#define __bdos(P) __builtin_dynamic_object_size(P, 0)
|
|
|
|
typedef long unsigned int size_t;
|
|
|
|
struct foo { size_t field; };
|
|
struct annotated_ptr {
|
|
unsigned long flags;
|
|
struct foo **buf __counted_by(ptr_count);
|
|
int ptr_count;
|
|
};
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test1(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2:![0-9]+]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT10:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: handler.out_of_bounds:
|
|
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR3:[0-9]+]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: cont10:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA4:![0-9]+]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP2]], i64 [[IDXPROM]]
|
|
// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA13:![0-9]+]]
|
|
// SANITIZE-WITH-ATTR-NEXT: ret void
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test1(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA2:![0-9]+]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP0]], i64 [[IDXPROM]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11:![0-9]+]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret void
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test1(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA2:![0-9]+]]
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP0]], i64 [[IDXPROM]]
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11:![0-9]+]]
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret void
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test1(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA2:![0-9]+]]
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP0]], i64 [[IDXPROM]]
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11:![0-9]+]]
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
|
|
//
|
|
void test1(struct annotated_ptr *p, int index, struct foo *value) {
|
|
p->buf[index] = value;
|
|
}
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test2(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT10:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: handler.out_of_bounds:
|
|
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR3]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: cont10:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA4]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP2]], i64 [[IDXPROM]]
|
|
// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA13]]
|
|
// SANITIZE-WITH-ATTR-NEXT: ret void
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test2(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA2]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP0]], i64 [[IDXPROM]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret void
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test2(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA2]]
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP0]], i64 [[IDXPROM]]
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11]]
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret void
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test2(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA2]]
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP0]], i64 [[IDXPROM]]
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11]]
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
|
|
//
|
|
void test2(struct annotated_ptr *p, int index, struct foo *value) {
|
|
((struct foo **)((char *)p->buf))[index] = value;
|
|
}
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test3(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTNOT:%.*]] = icmp ugt i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], label [[CONT10:%.*]], !prof [[PROF15:![0-9]+]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: handler.out_of_bounds:
|
|
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR3]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: cont10:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA4]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP1]], i64 [[IDXPROM]]
|
|
// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA13]]
|
|
// SANITIZE-WITH-ATTR-NEXT: ret void
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test3(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA2]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP0]], i64 [[IDXPROM]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret void
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test3(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA2]]
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP0]], i64 [[IDXPROM]]
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11]]
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret void
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test3(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]], ptr noundef [[VALUE:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[TBAA2]]
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[TMP0]], i64 [[IDXPROM]]
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA11]]
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
|
|
//
|
|
void test3(struct annotated_ptr *p, int index, struct foo *value) {
|
|
*&*&*&p->buf[index] = value;
|
|
}
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869184, 17179869177) i64 @test4(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = shl nsw i64 [[COUNT]], 3
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[ARRAY_SIZE]], i64 0
|
|
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869184, 17179869177) i64 @test4(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = shl nsw i64 [[COUNT]], 3
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[ARRAY_SIZE]], i64 0
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test4(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test4(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
size_t test4(struct annotated_ptr *p) {
|
|
return __bdos(p->buf);
|
|
}
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869184, 17179869177) i64 @test5(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = shl nsw i64 [[COUNT]], 3
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[ARRAY_SIZE]], i64 0
|
|
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869184, 17179869177) i64 @test5(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = shl nsw i64 [[COUNT]], 3
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[ARRAY_SIZE]], i64 0
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test5(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test5(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
size_t test5(struct annotated_ptr *p, int index) {
|
|
return __bdos((struct foo **)((char *)p->buf));
|
|
}
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 17179869177) i64 @test6(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTNOT:%.*]] = icmp ugt i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], label [[CONT8:%.*]], !prof [[PROF15]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: handler.out_of_bounds:
|
|
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR3]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: cont8:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sub nsw i64 [[COUNT]], [[IDXPROM]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.smax.i64(i64 [[TMP1]], i64 0)
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nuw nsw i64 [[TMP2]], 3
|
|
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]]
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -34359738360, 34359738361) i64 @test6(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sub nsw i64 [[COUNT]], [[IDXPROM]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = shl nsw i64 [[TMP0]], 3
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[TMP0]], -1
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[INDEX]], -1
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[RESULT]], i64 0
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]]
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test6(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test6(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
size_t test6(struct annotated_ptr *p, int index) {
|
|
return __bdos(&p->buf[index]);
|
|
}
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test7(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT10:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: handler.out_of_bounds:
|
|
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR3]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: cont10:
|
|
// SANITIZE-WITH-ATTR-NEXT: ret i64 -1
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test7(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test7(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test7(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
size_t test7(struct annotated_ptr *p, int index) {
|
|
return __bdos(((struct foo **)(char *)p->buf)[index]);
|
|
}
|
|
|
|
struct annotated_sized_ptr {
|
|
unsigned long flags;
|
|
void *buf __sized_by(ptr_count);
|
|
int ptr_count;
|
|
};
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test8(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
|
|
// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0)
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext nneg i32 [[NARROW]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]]
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test8(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0)
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext nneg i32 [[NARROW]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]]
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test8(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test8(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
size_t test8(struct annotated_sized_ptr *p, int index) {
|
|
return __bdos(p->buf);
|
|
}
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test9(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTNOT:%.*]] = icmp ugt i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], label [[CONT8:%.*]], !prof [[PROF15]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: handler.out_of_bounds:
|
|
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR3]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: cont8:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT]], [[IDXPROM]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
|
|
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -4294967295, 4294967296) i64 @test9(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT]], [[IDXPROM]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[RESULT]], -1
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[INDEX]], -1
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[RESULT]], i64 0
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]]
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test9(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test9(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
size_t test9(struct annotated_sized_ptr *p, int index) {
|
|
return __bdos(&p->buf[index]);
|
|
}
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test10(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[DOTNOT:%.*]] = icmp ugt i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], label [[CONT8:%.*]], !prof [[PROF15]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: handler.out_of_bounds:
|
|
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR3]], !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
|
|
// SANITIZE-WITH-ATTR: cont8:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[INDEX_SIZE:%.*]] = shl nuw nsw i64 [[IDXPROM]], 2
|
|
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT]], [[INDEX_SIZE]]
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
|
|
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -10737418236, 10737418240) i64 @test10(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[INDEX_SIZE:%.*]] = shl nsw i64 [[IDXPROM]], 2
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT]], [[INDEX_SIZE]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[RESULT]], -1
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[INDEX]], -1
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[RESULT]], i64 0
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]]
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test10(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test10(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
|
|
//
|
|
size_t test10(struct annotated_sized_ptr *p, int index) {
|
|
return __bdos(&((unsigned int *) p->buf)[index]);
|
|
}
|
|
|
|
struct pr151236_struct {
|
|
int *a __counted_by(a_count);
|
|
short a_count;
|
|
};
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -262144, 262137) i64 @test11(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i16, ptr [[COUNTED_BY_GEP]], align 4
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i16 [[COUNTED_BY_LOAD]], -1
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i16 [[COUNTED_BY_LOAD]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = shl nsw i64 [[COUNT]], 3
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[ARRAY_SIZE]], i64 0
|
|
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -262144, 262137) i64 @test11(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i16, ptr [[COUNTED_BY_GEP]], align 4
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i16 [[COUNTED_BY_LOAD]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = shl nsw i64 [[COUNT]], 3
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i16 [[COUNTED_BY_LOAD]], -1
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[ARRAY_SIZE]], i64 0
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local range(i64 0, -1) i64 @test11(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -2
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local range(i64 0, -1) i64 @test11(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -2
|
|
//
|
|
size_t test11(struct pr151236_struct *p) {
|
|
return __bdos(p->a) + __bdos((p->a));
|
|
}
|
|
|
|
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -262144, 262137) i64 @test12(
|
|
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i16, ptr [[COUNTED_BY_GEP]], align 4
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i16 [[COUNTED_BY_LOAD]], -1
|
|
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i16 [[COUNTED_BY_LOAD]] to i64
|
|
// SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = shl nsw i64 [[COUNT]], 3
|
|
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[ARRAY_SIZE]], i64 0
|
|
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
|
|
//
|
|
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -262144, 262137) i64 @test12(
|
|
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i16, ptr [[COUNTED_BY_GEP]], align 4
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i16 [[COUNTED_BY_LOAD]] to i64
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = shl nsw i64 [[COUNT]], 3
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i16 [[COUNTED_BY_LOAD]], -1
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[ARRAY_SIZE]], i64 0
|
|
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
|
|
//
|
|
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local range(i64 0, -1) i64 @test12(
|
|
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -2
|
|
//
|
|
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local range(i64 0, -1) i64 @test12(
|
|
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
|
|
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -2
|
|
//
|
|
size_t test12(struct pr151236_struct *p) {
|
|
return __bdos(p->a) + __bdos(((int *)p->a));
|
|
}
|