[clang] [Clang][counted_by] Support casting the array to a different type (PR #136239)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 17 19:06:20 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Bill Wendling (bwendling)
<details>
<summary>Changes</summary>
C allows the programmer to cast the base array to a different type before applying the index. We need to handle that situation.
struct annotated {
unsigned long flags;
int count;
int array[] __counted_by(count);
};
__bdos(&((unsigned short *) ((char *)p->array))[42], 1);
Use the index's type when calculating the size to remove from the flexible array member's total size.
---
Patch is 96.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136239.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+49-37)
- (modified) clang/test/CodeGen/attr-counted-by.c (+314-116)
``````````diff
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1e4e055e04afd..47aea8281287e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -910,6 +910,7 @@ class StructFieldAccess
public:
const ArraySubscriptExpr *ASE = nullptr;
+ QualType ArrayElementTy;
const Expr *VisitMemberExpr(const MemberExpr *E) {
if (AddrOfSeen && E->getType()->isArrayType())
@@ -925,6 +926,7 @@ class StructFieldAccess
AddrOfSeen = false; // '&ptr->array[idx]' is okay.
ASE = E;
+ ArrayElementTy = E->getBase()->getType();
return Visit(E->getBase());
}
const Expr *VisitCastExpr(const CastExpr *E) {
@@ -1101,23 +1103,23 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
// count = ptr->count;
//
// flexible_array_member_base_size = sizeof (*ptr->array);
- // flexible_array_member_size =
- // count * flexible_array_member_base_size;
+ // flexible_array_member_size = count * flexible_array_member_base_size;
//
// if (flexible_array_member_size < 0)
// return 0;
// return flexible_array_member_size;
//
- // 2) '&ptr->array[idx]':
+ // 2) '&((cast) ptr->array)[idx]':
//
// count = ptr->count;
// index = idx;
//
+ // casted_flexible_array_member_base_size = sizeof (*((cast) ptr->array));
+ //
// flexible_array_member_base_size = sizeof (*ptr->array);
- // flexible_array_member_size =
- // count * flexible_array_member_base_size;
+ // flexible_array_member_size = count * flexible_array_member_base_size;
//
- // index_size = index * flexible_array_member_base_size;
+ // index_size = index * casted_flexible_array_member_base_size;
//
// if (flexible_array_member_size < 0 || index < 0)
// return 0;
@@ -1129,8 +1131,7 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
// sizeof_struct = sizeof (struct s);
//
// flexible_array_member_base_size = sizeof (*ptr->array);
- // flexible_array_member_size =
- // count * flexible_array_member_base_size;
+ // flexible_array_member_size = count * flexible_array_member_base_size;
//
// field_offset = offsetof (struct s, field);
// offset_diff = sizeof_struct - field_offset;
@@ -1139,19 +1140,19 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
// return 0;
// return offset_diff + flexible_array_member_size;
//
- // 4) '&ptr->field_array[idx]':
+ // 4) '&((cast) ptr->field_array)[idx]':
//
// count = ptr->count;
// index = idx;
// sizeof_struct = sizeof (struct s);
//
// flexible_array_member_base_size = sizeof (*ptr->array);
- // flexible_array_member_size =
- // count * flexible_array_member_base_size;
+ // flexible_array_member_size = count * flexible_array_member_base_size;
+ //
+ // casted_field_base_size = sizeof (*((cast) ptr->field_array));
//
- // field_base_size = sizeof (*ptr->field_array);
// field_offset = offsetof (struct s, field)
- // field_offset += index * field_base_size;
+ // field_offset += index * casted_field_base_size;
//
// offset_diff = sizeof_struct - field_offset;
//
@@ -1162,14 +1163,11 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
QualType CountTy = CountFD->getType();
bool IsSigned = CountTy->isSignedIntegerType();
- QualType FlexibleArrayMemberTy = FlexibleArrayMemberFD->getType();
- QualType FieldTy = FD->getType();
-
// Explicit cast because otherwise the CharWidth will promote an i32's into
// u64's leading to overflows..
int64_t CharWidth = static_cast<int64_t>(CGM.getContext().getCharWidth());
- // size_t field_offset = offsetof (struct s, field);
+ // field_offset = offsetof (struct s, field);
Value *FieldOffset = nullptr;
if (FlexibleArrayMemberFD != FD) {
std::optional<int64_t> Offset = GetFieldOffset(Ctx, RD, FD);
@@ -1179,13 +1177,13 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
llvm::ConstantInt::get(ResType, *Offset / CharWidth, IsSigned);
}
- // size_t count = (size_t) ptr->count;
+ // count = ptr->count;
Value *Count = EmitLoadOfCountedByField(ME, FlexibleArrayMemberFD, CountFD);
if (!Count)
return nullptr;
Count = Builder.CreateIntCast(Count, ResType, IsSigned, "count");
- // size_t index = (size_t) ptr->index;
+ // index = ptr->index;
Value *Index = nullptr;
if (Idx) {
bool IdxSigned = Idx->getType()->isSignedIntegerType();
@@ -1193,23 +1191,35 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
Index = Builder.CreateIntCast(Index, ResType, IdxSigned, "index");
}
- // size_t flexible_array_member_base_size = sizeof (*ptr->array);
- const ArrayType *ArrayTy = Ctx.getAsArrayType(FlexibleArrayMemberTy);
- CharUnits BaseSize = Ctx.getTypeSizeInChars(ArrayTy->getElementType());
+ // flexible_array_member_base_size = sizeof (*ptr->array);
+ QualType FlexibleArrayMemberTy = FlexibleArrayMemberFD->getType();
+ const ArrayType *FAMTy = Ctx.getAsArrayType(FlexibleArrayMemberTy);
+ CharUnits BaseSize = Ctx.getTypeSizeInChars(FAMTy->getElementType());
auto *FlexibleArrayMemberBaseSize =
llvm::ConstantInt::get(ResType, BaseSize.getQuantity(), IsSigned);
- // size_t flexible_array_member_size =
- // count * flexible_array_member_base_size;
+ // flexible_array_member_size = count * flexible_array_member_base_size;
Value *FlexibleArrayMemberSize =
Builder.CreateMul(Count, FlexibleArrayMemberBaseSize,
"flexible_array_member_size", !IsSigned, IsSigned);
+ QualType CastedArrayElementTy = Visitor.ArrayElementTy;
+ llvm::ConstantInt *CastedArrayElementSize = nullptr;
+ if (!CastedArrayElementTy.isNull() && CastedArrayElementTy->isPointerType()) {
+ const PointerType *FAMTy = cast<clang::PointerType>(CastedArrayElementTy);
+ CharUnits BaseSize = Ctx.getTypeSizeInChars(FAMTy->getPointeeType());
+ CastedArrayElementSize =
+ llvm::ConstantInt::get(ResType, BaseSize.getQuantity(), IsSigned);
+ }
+
Value *Res = nullptr;
if (FlexibleArrayMemberFD == FD) {
- if (Idx) { // Option (2) '&ptr->array[idx]'
- // size_t index_size = index * flexible_array_member_base_size;
- Value *IndexSize = Builder.CreateMul(FlexibleArrayMemberBaseSize, Index,
+ if (Idx) { // Option (2) '&((cast) ptr->array)[idx]'
+ if (!CastedArrayElementSize)
+ CastedArrayElementSize = FlexibleArrayMemberBaseSize;
+
+ // index_size = index * flexible_array_member_base_size;
+ Value *IndexSize = Builder.CreateMul(CastedArrayElementSize, Index,
"index_size", !IsSigned, IsSigned);
// return flexible_array_member_size - index_size;
@@ -1220,28 +1230,30 @@ CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE,
Res = FlexibleArrayMemberSize;
}
} else {
- // size_t sizeof_struct = sizeof (struct s);
+ // sizeof_struct = sizeof (struct s);
llvm::StructType *StructTy = getTypes().getCGRecordLayout(RD).getLLVMType();
const llvm::DataLayout &Layout = CGM.getDataLayout();
TypeSize Size = Layout.getTypeSizeInBits(StructTy);
Value *SizeofStruct =
llvm::ConstantInt::get(ResType, Size.getKnownMinValue() / CharWidth);
- if (Idx) { // Option (4) '&ptr->field_array[idx]'
- // size_t field_base_size = sizeof (*ptr->field_array);
- const ArrayType *ArrayTy = Ctx.getAsArrayType(FieldTy);
- CharUnits BaseSize = Ctx.getTypeSizeInChars(ArrayTy->getElementType());
- auto *FieldBaseSize =
- llvm::ConstantInt::get(ResType, BaseSize.getQuantity(), IsSigned);
+ if (Idx) { // Option (4) '&((cast) ptr->field_array)[idx]'
+ // casted_field_base_size = sizeof (*((cast) ptr->field_array));
+ if (!CastedArrayElementSize) {
+ const ArrayType *ArrayTy = Ctx.getAsArrayType(FD->getType());
+ CharUnits BaseSize = Ctx.getTypeSizeInChars(ArrayTy->getElementType());
+ CastedArrayElementSize =
+ llvm::ConstantInt::get(ResType, BaseSize.getQuantity(), IsSigned);
+ }
- // field_offset += index * field_base_size;
- Value *Mul = Builder.CreateMul(Index, FieldBaseSize, "field_offset",
+ // field_offset += index * casted_field_base_size;
+ Value *Mul = Builder.CreateMul(Index, CastedArrayElementSize, "field_offset",
!IsSigned, IsSigned);
FieldOffset = Builder.CreateAdd(FieldOffset, Mul);
}
// Option (3) '&ptr->field', and Option (4) continuation.
- // size_t offset_diff = flexible_array_member_offset - field_offset;
+ // offset_diff = flexible_array_member_offset - field_offset;
Value *OffsetDiff = Builder.CreateSub(SizeofStruct, FieldOffset,
"offset_diff", !IsSigned, IsSigned);
diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c
index 8e062629464dd..101949af208e1 100644
--- a/clang/test/CodeGen/attr-counted-by.c
+++ b/clang/test/CodeGen/attr-counted-by.c
@@ -68,7 +68,7 @@ struct anon_struct {
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], 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 @[[GLOB1:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR12:[0-9]+]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8:[0-9]+]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
// SANITIZE-WITH-ATTR: cont3:
// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12
@@ -116,7 +116,7 @@ void test1(struct annotated *p, int index, int val) {
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[INDEX]], [[TMP0]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT6:%.*]], 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 @[[GLOB3:[0-9]+]], i64 [[INDEX]]) #[[ATTR12]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
// SANITIZE-WITH-ATTR: cont6:
// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12
@@ -159,7 +159,7 @@ void test2(struct annotated *p, size_t index) {
}
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test2_bdos(
-// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// 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 i32, ptr [[COUNTED_BY_GEP]], align 4
@@ -181,7 +181,7 @@ void test2(struct annotated *p, size_t index) {
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
//
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test2_bdos(
-// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
@@ -194,6 +194,42 @@ size_t test2_bdos(struct annotated *p) {
return __bdos(p->array);
}
+// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test2_bdos_cast(
+// 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 i32, ptr [[COUNTED_BY_GEP]], align 4
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nsw i64 [[COUNT]], 2
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], i64 0
+// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test2_bdos_cast(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] {
+// 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 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: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nsw i64 [[COUNT]], 2
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], i64 0
+// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]]
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test2_bdos_cast(
+// 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 @test2_bdos_cast(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
+//
+size_t test2_bdos_cast(struct annotated *p) {
+ return __bdos((char *)p->array);
+}
+
// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test3(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: entry:
@@ -203,7 +239,7 @@ size_t test2_bdos(struct annotated *p) {
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[INDEX]], [[TMP0]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], 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 [[INDEX]]) #[[ATTR12]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
// SANITIZE-WITH-ATTR: cont3:
// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12
@@ -242,7 +278,7 @@ void test3(struct annotated *p, size_t index) {
}
// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test3_bdos(
-// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
+// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// SANITIZE-WITH-ATTR-NEXT: entry:
// SANITIZE-WITH-ATTR-NEXT: ret i64 -1
//
@@ -252,7 +288,7 @@ void test3(struct annotated *p, size_t index) {
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1
//
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test3_bdos(
-// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
+// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
@@ -265,6 +301,30 @@ size_t test3_bdos(struct annotated *p) {
return __bdos(p);
}
+// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test3_bdos_cast(
+// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] {
+// SANITIZE-WITH-ATTR-NEXT: entry:
+// SANITIZE-WITH-ATTR-NEXT: ret i64 -1
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test3_bdos_cast(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] {
+// NO-SANITIZE-WITH-ATTR-NEXT: entry:
+// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test3_bdos_cast(
+// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] {
+// SANITIZE-WITHOUT-ATTR-NEXT: entry:
+// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test3_bdos_cast(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
+//
+size_t test3_bdos_cast(struct annotated *p) {
+ return __bdos((char *)p);
+}
+
// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test4(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: entry:
@@ -275,7 +335,7 @@ size_t test3_bdos(struct annotated *p) {
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[DOTCOUNTED_BY_LOAD]], 2
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT1:%.*]], 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 @[[GLOB5:[0-9]+]], i64 3) #[[ATTR12]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 3) #[[ATTR8]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
// SANITIZE-WITH-ATTR: cont1:
// SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl i32 [[DOTCOUNTED_BY_LOAD]], 2
@@ -283,7 +343,7 @@ size_t test3_bdos(struct annotated *p) {
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT12:%.*]], label [[HANDLER_OUT_OF_BOUNDS8:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR: handler.out_of_bounds8:
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR12]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
// SANITIZE-WITH-ATTR: cont12:
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 2
@@ -295,7 +355,7 @@ size_t test3_bdos(struct annotated *p) {
// SANITIZE-WITH-ATTR-NEXT: [[DOTNOT81:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 3
// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT81]], label [[HANDLER_OUT_OF_BOUNDS18:%.*]], label [[CONT19:%.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META2]]
// SANITIZE-WITH-ATTR: handler.out_of_bounds18:
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 4) #[[ATTR12]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/136239
More information about the cfe-commits
mailing list