[clang] [CodeGen] Fix -fsanitize=array-bounds for __sized_by / _or_null pointers (PR #213795)
Dan Liew via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 20 23:19:02 PDT 2026
https://github.com/delcypher updated https://github.com/llvm/llvm-project/pull/213795
>From 9687b66d054189222a5abe10b4db32ef7636a499 Mon Sep 17 00:00:00 2001
From: Dan Liew <dliew at apple.com>
Date: Fri, 31 Jul 2026 15:50:22 -0700
Subject: [PATCH] [CodeGen] Fix -fsanitize=array-bounds for __sized_by /
_or_null pointers
`EmitCountedByBoundsChecking()` assumed a CountAttributedType is always
a __counted_by pointer. That isn't true, there are four versions of the
attribute:
* `__counted_by`: Already handled correctly.
* `__counted_by_or_null`: Incorectly handled.
* `__sized_by`: Incorreclty handled.
* `__sized_by_or_null`: Incorreclty handled.
In particular:
* __sized_by / __sized_by_or_null: the loaded bound is a byte count, but the
element index was compared against it directly, so an access was only
flagged once the index exceeded the byte count -- missing out-of-bounds
accesses for a pointee larger than one byte. Scale the index to bytes
('index * sizeof(element)') before comparing. counted_by counts elements
and is unchanged; a void (or otherwise zero-sized) pointee uses the GNU
element size of 1, i.e. no scaling.
* __counted_by_or_null / __sized_by_or_null: a null pointer describes no
accessible memory, but the null case was ignored, so an access through a
null pointer with a non-zero count was not trapped. Treat the bound as 0
when the pointer is null.
The index scaling is threaded through EmitBoundsCheckImpl via a new
IndexScale parameter; the runtime handler is still passed the unscaled
element index. Plain __counted_by and the general array-bounds path use a
scale of 1 and are unchanged.
Assisted-by: Claude Code
rdar://184139694
---
clang/lib/CodeGen/CGExpr.cpp | 52 +-
clang/lib/CodeGen/CodeGenFunction.h | 3 +-
.../attr-counted-by-or-null-for-pointers.c | 389 +++++++++---
.../test/CodeGen/attr-sized-by-for-pointers.c | 372 +++++++++---
.../attr-sized-by-or-null-for-pointers.c | 561 ++++++++++++------
5 files changed, 1021 insertions(+), 356 deletions(-)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index eff6a7de320d7..51c34448d19ad 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1298,12 +1298,10 @@ void CodeGenFunction::EmitBoundsCheck(const Expr *ArrayExpr,
BoundsVal, getContext().getSizeType(), Accessed);
}
-void CodeGenFunction::EmitBoundsCheckImpl(const Expr *ArrayExpr,
- QualType ArrayBaseType,
- llvm::Value *IndexVal,
- QualType IndexType,
- llvm::Value *BoundsVal,
- QualType BoundsType, bool Accessed) {
+void CodeGenFunction::EmitBoundsCheckImpl(
+ const Expr *ArrayExpr, QualType ArrayBaseType, llvm::Value *IndexVal,
+ QualType IndexType, llvm::Value *BoundsVal, QualType BoundsType,
+ bool Accessed, CharUnits IndexScale) {
if (!BoundsVal)
return;
@@ -1323,14 +1321,23 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *ArrayExpr,
llvm::Value *IndexInst = Builder.CreateIntCast(IndexVal, Ty, IndexSigned);
llvm::Value *BoundsInst = Builder.CreateIntCast(BoundsVal, Ty, false);
+ // For a '__sized_by' bound the loaded value is a byte count, so compare it
+ // against the index scaled to bytes: 'index * sizeof(element)'. The
+ // element-counting ('__counted_by') and plain-array cases pass a scale of 1.
+ // The value reported to the runtime handler stays the (unscaled) index.
+ llvm::Value *CheckIndex = IndexInst;
+ if (IndexScale > CharUnits::One())
+ CheckIndex = Builder.CreateMul(
+ IndexInst, llvm::ConstantInt::get(Ty, IndexScale.getQuantity()));
+
llvm::Constant *StaticData[] = {
EmitCheckSourceLocation(ArrayExpr->getExprLoc()),
EmitCheckTypeDescriptor(ArrayBaseType),
EmitCheckTypeDescriptor(IndexType),
};
- llvm::Value *Check = Accessed ? Builder.CreateICmpULT(IndexInst, BoundsInst)
- : Builder.CreateICmpULE(IndexInst, BoundsInst);
+ llvm::Value *Check = Accessed ? Builder.CreateICmpULT(CheckIndex, BoundsInst)
+ : Builder.CreateICmpULE(CheckIndex, BoundsInst);
if (BoundsSigned) {
// Don't allow a negative bounds.
@@ -4999,9 +5006,36 @@ void CodeGenFunction::EmitCountedByBoundsChecking(
BoundsVal = Builder.CreateAlignedLoad(BoundsType, BoundsVal, getIntAlign(),
".counted_by.load");
+ const auto *CAT = FD->getType()->getAs<CountAttributedType>();
+
+ // For the '_or_null' variants a null pointer describes no accessible
+ // memory, so treat the bound as 0 when the pointer is null; any access then
+ // traps.
+ if (CAT->isOrNull()) {
+ llvm::Value *Ptr = EmitScalarExpr(ME);
+ llvm::Value *IsNull = Builder.CreateIsNull(Ptr);
+ BoundsVal = Builder.CreateSelect(
+ IsNull, llvm::ConstantInt::get(BoundsType, 0), BoundsVal);
+ }
+
+ // For '__sized_by' the bound is a byte count, so the index (in elements)
+ // must be scaled to bytes before comparing. '__counted_by' counts elements
+ // and needs no scaling. A void (or otherwise zero-/unknown-sized) pointee
+ // uses the GNU convention of element size 1, i.e. no scaling.
+ CharUnits IndexScale = CharUnits::One();
+ if (CAT->isCountInBytes()) {
+ QualType ElemTy = ArrayType->getPointeeType();
+ if (!ElemTy.isNull() && !ElemTy->isIncompleteType() &&
+ !ElemTy->isFunctionType()) {
+ CharUnits ElemSize = getContext().getTypeSizeInChars(ElemTy);
+ if (!ElemSize.isZero())
+ IndexScale = ElemSize;
+ }
+ }
+
// Now emit the bounds checking.
EmitBoundsCheckImpl(ArrayExpr, ArrayType, IndexVal, IndexType, BoundsVal,
- CountFD->getType(), Accessed);
+ CountFD->getType(), Accessed, IndexScale);
}
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 25606a51b6d71..678b5e2867232 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3405,7 +3405,8 @@ class CodeGenFunction : public CodeGenTypeCache {
void EmitBoundsCheckImpl(const Expr *ArrayExpr, QualType ArrayBaseType,
llvm::Value *IndexVal, QualType IndexType,
llvm::Value *BoundsVal, QualType BoundsType,
- bool Accessed);
+ bool Accessed,
+ CharUnits IndexScale = CharUnits::One());
/// Returns debug info, with additional annotation if
/// CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[Ordinal] is enabled for
diff --git a/clang/test/CodeGen/attr-counted-by-or-null-for-pointers.c b/clang/test/CodeGen/attr-counted-by-or-null-for-pointers.c
index fcb70bd371337..820e33be987ae 100644
--- a/clang/test/CodeGen/attr-counted-by-or-null-for-pointers.c
+++ b/clang/test/CodeGen/attr-counted-by-or-null-for-pointers.c
@@ -31,11 +31,182 @@ struct annotated_ptr {
int ptr_count;
};
-// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 17179869177) i64 @test_bdos_of_pointer(
-// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript(
+// 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: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// 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: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ult i32 [[INDEX]], [[TMP2]], !nosanitize [[META12:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT15:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13:![0-9]+]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP6]]) #[[ATTR5:[0-9]+]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT15]]:
+// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript(
+// 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 [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12:![0-9]+]]
+// SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12:![0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+void test_store_subscript(struct annotated_ptr *p, int index, struct foo *value) {
+ p->buf[index] = value;
+}
+
+// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// 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: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA6]]
+// 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: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ult i32 [[INDEX]], [[TMP2]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT15:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT15]]:
+// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14]]
+// SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// 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 [[_ZTS3FOOPTR_TBAA6]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+void test_store_subscript_through_cast(struct annotated_ptr *p, int index, struct foo *value) {
+ ((struct foo **)((char *)p->buf))[index] = value;
+}
+
+// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// 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: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA6]]
+// 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: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ule i32 [[INDEX]], [[TMP2]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT15:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT15]]:
+// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14]]
+// SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// 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 [[_ZTS3FOOPTR_TBAA6]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+void test_store_subscript_through_deref_of_addressof(struct annotated_ptr *p, int index, struct foo *value) {
+ *&*&*&p->buf[index] = value;
+}
+
+// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 17179869177) i64 @test_bdos_of_pointer(
+// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
+// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA6]]
// 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 8
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
@@ -46,10 +217,10 @@ struct annotated_ptr {
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 17179869177) i64 @test_bdos_of_pointer(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1:[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 [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA6]]
// 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 8
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
@@ -60,12 +231,12 @@ struct annotated_ptr {
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]]
//
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_pointer(
-// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[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
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_pointer(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -88,7 +259,7 @@ size_t test_bdos_of_pointer(struct annotated_ptr *p) {
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 17179869177) i64 @test_bdos_of_pointer_through_cast(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
// 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 [[_ZTS3FOOPTR_TBAA6]]
@@ -107,7 +278,7 @@ size_t test_bdos_of_pointer(struct annotated_ptr *p) {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_pointer_through_cast(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -118,31 +289,32 @@ size_t test_bdos_of_pointer_through_cast(struct annotated_ptr *p, int index) {
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 34359738361) i64 @test_bdos_of_element_address(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
+// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA6]]
// 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:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META12:![0-9]+]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13:![0-9]+]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ule i32 [[INDEX]], [[TMP2]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT13:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP3]]) #[[ATTR5:[0-9]+]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT8]]:
-// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
-// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA6]]
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
+// SANITIZE-WITH-ATTR: [[CONT13]]:
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
-// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP4]], null
-// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = shl nuw nsw i64 [[COUNT]], 3
-// SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = select i1 [[TMP5]], i64 0, i64 [[TMP6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = shl nsw i64 [[COUNT]], 3
+// SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP7]]
// SANITIZE-WITH-ATTR-NEXT: [[INDEX_SIZE:%.*]] = shl nsw i64 [[IDXPROM]], 3
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[ARRAY_SIZE]], [[INDEX_SIZE]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
-// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP7]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
+// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP8]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -34359738360, 34359738361) i64 @test_bdos_of_element_address(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
// 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 [[_ZTS3FOOPTR_TBAA6]]
@@ -167,7 +339,7 @@ size_t test_bdos_of_pointer_through_cast(struct annotated_ptr *p, int index) {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_element_address(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -178,21 +350,25 @@ size_t test_bdos_of_element_address(struct annotated_ptr *p, int index) {
// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test_bdos_of_subscript_through_cast(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
+// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA6]]
// 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:%.*]] = icmp ult i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ult i32 [[INDEX]], [[TMP2]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT15:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR: [[CONT15]]:
// SANITIZE-WITH-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test_bdos_of_subscript_through_cast(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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
//
@@ -202,7 +378,7 @@ size_t test_bdos_of_element_address(struct annotated_ptr *p, int index) {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_subscript_through_cast(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -218,7 +394,7 @@ struct pr151236_struct {
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 262137) i64 @test_bdos_of_short_count_field(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA16:![0-9]+]]
// 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 8
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i16 [[COUNTED_BY_LOAD]] to i64
@@ -230,9 +406,9 @@ struct pr151236_struct {
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[ADD]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 262137) i64 @test_bdos_of_short_count_field(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA12:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14:![0-9]+]]
// 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 8
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i16 [[COUNTED_BY_LOAD]] to i64
@@ -249,7 +425,7 @@ struct pr151236_struct {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -2
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local range(i64 0, -1) i64 @test_bdos_of_short_count_field(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -2
//
@@ -260,7 +436,7 @@ size_t test_bdos_of_short_count_field(struct pr151236_struct *p) {
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 262137) i64 @test_bdos_of_short_count_field_through_cast(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA16]]
// 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 8
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i16 [[COUNTED_BY_LOAD]] to i64
@@ -272,9 +448,9 @@ size_t test_bdos_of_short_count_field(struct pr151236_struct *p) {
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[ADD]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 262137) i64 @test_bdos_of_short_count_field_through_cast(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA12]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14]]
// 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 8
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i16 [[COUNTED_BY_LOAD]] to i64
@@ -291,7 +467,7 @@ size_t test_bdos_of_short_count_field(struct pr151236_struct *p) {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -2
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local range(i64 0, -1) i64 @test_bdos_of_short_count_field_through_cast(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -2
//
@@ -319,7 +495,7 @@ void take_ptr_with_size(void *p __attribute__((pass_dynamic_object_size(0))));
// SANITIZE-WITH-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test_bdos_of_volatile_pointer(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1
//
@@ -329,7 +505,7 @@ void take_ptr_with_size(void *p __attribute__((pass_dynamic_object_size(0))));
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test_bdos_of_volatile_pointer(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
@@ -345,7 +521,7 @@ size_t test_bdos_of_volatile_pointer(struct annotated_volatile_ptr *p) {
// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA18:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA20:![0-9]+]]
// 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 8
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
@@ -357,9 +533,9 @@ size_t test_bdos_of_volatile_pointer(struct annotated_volatile_ptr *p) {
// SANITIZE-WITH-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] {
// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA16:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA18:![0-9]+]]
// 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 8
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
@@ -367,21 +543,21 @@ size_t test_bdos_of_volatile_pointer(struct annotated_volatile_ptr *p) {
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = shl nsw i64 [[COUNT]], 2
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = tail call i64 @llvm.smax.i64(i64 [[TMP2]], i64 0)
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP3]]
-// NO-SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef [[TMP4]]) #[[ATTR6:[0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef [[TMP4]]) #[[ATTR7:[0-9]+]]
// NO-SANITIZE-WITH-ATTR-NEXT: ret void
//
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6:![0-9]+]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14:![0-9]+]]
// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef -1) #[[ATTR3:[0-9]+]]
// SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6:![0-9]+]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef -1) #[[ATTR5:[0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14:![0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef -1) #[[ATTR6:[0-9]+]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
void test_pass_dynamic_object_size_of_pointer(struct annotated_volatile_ptr *p) {
@@ -395,40 +571,43 @@ void test_pass_dynamic_object_size_of_pointer(struct annotated_volatile_ptr *p)
// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA18]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA20]]
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT9:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA20]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ule i32 [[INDEX]], [[TMP3]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP3]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT12:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[TMP4]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
-// SANITIZE-WITH-ATTR: [[CONT9]]:
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
+// SANITIZE-WITH-ATTR: [[CONT12]]:
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA18]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp eq ptr [[TMP5]], null
-// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = shl nuw nsw i64 [[COUNT]], 2
-// SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = select i1 [[TMP6]], i64 0, i64 [[TMP7]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA20]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp eq ptr [[TMP8]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = shl nsw i64 [[COUNT]], 2
+// SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = select i1 [[TMP9]], i64 0, i64 [[TMP10]]
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[ARRAY_SIZE]], [[IDXPROM]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
-// SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef [[TMP8]]) #[[ATTR6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
+// SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef [[TMP11]]) #[[ATTR6]]
// SANITIZE-WITH-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR3]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR4]] {
// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA16]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA18]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
// 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 8
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
-// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA16]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA18]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nsw i64 [[COUNT]], 2
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY_SIZE:%.*]] = select i1 [[TMP2]], i64 0, i64 [[TMP3]]
@@ -437,25 +616,25 @@ void test_pass_dynamic_object_size_of_pointer(struct annotated_volatile_ptr *p)
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[INDEX]], -1
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = select i1 [[TMP6]], i64 [[RESULT]], i64 0
-// NO-SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef [[TMP7]]) #[[ATTR6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef [[TMP7]]) #[[ATTR7]]
// NO-SANITIZE-WITH-ATTR-NEXT: ret void
//
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14]]
// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef -1) #[[ATTR3]]
// SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR3]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR4]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef -1) #[[ATTR5]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef -1) #[[ATTR6]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
void test_pass_dynamic_object_size_of_element_address(struct annotated_volatile_ptr *p, int index) {
@@ -473,12 +652,14 @@ void test_pass_dynamic_object_size_of_element_address(struct annotated_volatile_
// SANITIZE-WITH-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
// SANITIZE-WITH-ATTR: [[META12]] = !{}
// SANITIZE-WITH-ATTR: [[PROF13]] = !{!"branch_weights", i32 1048575, i32 1}
-// SANITIZE-WITH-ATTR: [[INTPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META16:![0-9]+]], i64 0}
-// SANITIZE-WITH-ATTR: [[META15]] = !{!"pr151236_struct", [[META16]], i64 0, [[META17:![0-9]+]], i64 8}
-// SANITIZE-WITH-ATTR: [[META16]] = !{!"p1 int", [[META11]], i64 0}
-// SANITIZE-WITH-ATTR: [[META17]] = !{!"short", [[META4]], i64 0}
-// SANITIZE-WITH-ATTR: [[INTPTR_TBAA18]] = !{[[META19:![0-9]+]], [[META16]], i64 0}
-// SANITIZE-WITH-ATTR: [[META19]] = !{!"annotated_volatile_ptr", [[META16]], i64 0, [[META3]], i64 8}
+// SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META15]], i64 0}
+// SANITIZE-WITH-ATTR: [[META15]] = !{!"p1 _ZTS3foo", [[META11]], i64 0}
+// SANITIZE-WITH-ATTR: [[INTPTR_TBAA16]] = !{[[META17:![0-9]+]], [[META18:![0-9]+]], i64 0}
+// SANITIZE-WITH-ATTR: [[META17]] = !{!"pr151236_struct", [[META18]], i64 0, [[META19:![0-9]+]], i64 8}
+// SANITIZE-WITH-ATTR: [[META18]] = !{!"p1 int", [[META11]], i64 0}
+// SANITIZE-WITH-ATTR: [[META19]] = !{!"short", [[META4]], i64 0}
+// SANITIZE-WITH-ATTR: [[INTPTR_TBAA20]] = !{[[META21:![0-9]+]], [[META18]], i64 0}
+// SANITIZE-WITH-ATTR: [[META21]] = !{!"annotated_volatile_ptr", [[META18]], i64 0, [[META3]], i64 8}
//.
// NO-SANITIZE-WITH-ATTR: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0}
// NO-SANITIZE-WITH-ATTR: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
@@ -489,26 +670,42 @@ void test_pass_dynamic_object_size_of_element_address(struct annotated_volatile_
// NO-SANITIZE-WITH-ATTR: [[META9]] = !{!"p2 _ZTS3foo", [[META10:![0-9]+]], i64 0}
// NO-SANITIZE-WITH-ATTR: [[META10]] = !{!"any p2 pointer", [[META11:![0-9]+]], i64 0}
// NO-SANITIZE-WITH-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[INTPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META14:![0-9]+]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[META13]] = !{!"pr151236_struct", [[META14]], i64 0, [[META15:![0-9]+]], i64 8}
-// NO-SANITIZE-WITH-ATTR: [[META14]] = !{!"p1 int", [[META11]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[META15]] = !{!"short", [[META4]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[INTPTR_TBAA16]] = !{[[META17:![0-9]+]], [[META14]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[META17]] = !{!"annotated_volatile_ptr", [[META14]], i64 0, [[META3]], i64 8}
+// NO-SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META13]] = !{!"p1 _ZTS3foo", [[META11]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[INTPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META16:![0-9]+]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META15]] = !{!"pr151236_struct", [[META16]], i64 0, [[META17:![0-9]+]], i64 8}
+// NO-SANITIZE-WITH-ATTR: [[META16]] = !{!"p1 int", [[META11]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META17]] = !{!"short", [[META4]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[INTPTR_TBAA18]] = !{[[META19:![0-9]+]], [[META16]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META19]] = !{!"annotated_volatile_ptr", [[META16]], i64 0, [[META3]], i64 8}
//.
// SANITIZE-WITHOUT-ATTR: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0}
// SANITIZE-WITHOUT-ATTR: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
// SANITIZE-WITHOUT-ATTR: [[META5]] = !{!"Simple C/C++ TBAA"}
-// SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META8:![0-9]+]], i64 0}
-// SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_volatile_ptr", [[META8]], i64 0, [[META3]], i64 8}
-// SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"p1 int", [[META9:![0-9]+]], i64 0}
-// SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"any pointer", [[META4]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META9:![0-9]+]], i64 8}
+// SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_ptr", [[META8:![0-9]+]], i64 0, [[META9]], i64 8, [[META3]], i64 16}
+// SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"long", [[META4]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"p2 _ZTS3foo", [[META10:![0-9]+]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META10]] = !{!"any p2 pointer", [[META11:![0-9]+]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META13]] = !{!"p1 _ZTS3foo", [[META11]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META16:![0-9]+]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META15]] = !{!"annotated_volatile_ptr", [[META16]], i64 0, [[META3]], i64 8}
+// SANITIZE-WITHOUT-ATTR: [[META16]] = !{!"p1 int", [[META11]], i64 0}
//.
// NO-SANITIZE-WITHOUT-ATTR: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0}
// NO-SANITIZE-WITHOUT-ATTR: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
// NO-SANITIZE-WITHOUT-ATTR: [[META5]] = !{!"Simple C/C++ TBAA"}
-// NO-SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META8:![0-9]+]], i64 0}
-// NO-SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_volatile_ptr", [[META8]], i64 0, [[META3]], i64 8}
-// NO-SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"p1 int", [[META9:![0-9]+]], i64 0}
-// NO-SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"any pointer", [[META4]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META9:![0-9]+]], i64 8}
+// NO-SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_ptr", [[META8:![0-9]+]], i64 0, [[META9]], i64 8, [[META3]], i64 16}
+// NO-SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"long", [[META4]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"p2 _ZTS3foo", [[META10:![0-9]+]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META10]] = !{!"any p2 pointer", [[META11:![0-9]+]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META13]] = !{!"p1 _ZTS3foo", [[META11]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META16:![0-9]+]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META15]] = !{!"annotated_volatile_ptr", [[META16]], i64 0, [[META3]], i64 8}
+// NO-SANITIZE-WITHOUT-ATTR: [[META16]] = !{!"p1 int", [[META11]], i64 0}
//.
diff --git a/clang/test/CodeGen/attr-sized-by-for-pointers.c b/clang/test/CodeGen/attr-sized-by-for-pointers.c
index 1fdbfd39d2628..eaa115ba4dcc3 100644
--- a/clang/test/CodeGen/attr-sized-by-for-pointers.c
+++ b/clang/test/CodeGen/attr-sized-by-for-pointers.c
@@ -19,6 +19,179 @@
typedef long unsigned int size_t;
struct foo { size_t field; };
+struct annotated_ptr {
+ unsigned long flags;
+ struct foo **buf __sized_by(ptr_count);
+ int ptr_count;
+};
+
+// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript(
+// 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: [[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:%.*]] = shl i32 [[INDEX]], 3
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP4]]) #[[ATTR5:[0-9]+]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA8:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP5]], i64 [[IDXPROM]]
+// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript(
+// 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 [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12:![0-9]+]]
+// SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12:![0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+void test_store_subscript(struct annotated_ptr *p, int index, struct foo *value) {
+ p->buf[index] = value;
+}
+
+// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// 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: [[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:%.*]] = shl i32 [[INDEX]], 3
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP4]]) #[[ATTR5]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA8]]
+// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP5]], i64 [[IDXPROM]]
+// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14]]
+// SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// 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 [[_ZTS3FOOPTR_TBAA6]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+void test_store_subscript_through_cast(struct annotated_ptr *p, int index, struct foo *value) {
+ ((struct foo **)((char *)p->buf))[index] = value;
+}
+
+// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// 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: [[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:%.*]] = shl i32 [[INDEX]], 3
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ule i32 [[TMP0]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP4]]) #[[ATTR5]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA8]]
+// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP5]], i64 [[IDXPROM]]
+// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14]]
+// SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// 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 [[_ZTS3FOOPTR_TBAA6]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+void test_store_subscript_through_deref_of_addressof(struct annotated_ptr *p, int index, struct foo *value) {
+ *&*&*&p->buf[index] = value;
+}
struct annotated_sized_ptr {
unsigned long flags;
@@ -27,7 +200,7 @@ struct annotated_sized_ptr {
};
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test_bdos_of_pointer(
-// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[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 16
// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
@@ -36,7 +209,7 @@ struct annotated_sized_ptr {
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test_bdos_of_pointer(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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
@@ -45,12 +218,12 @@ struct annotated_sized_ptr {
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]]
//
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_pointer(
-// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[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
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_pointer(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -63,13 +236,13 @@ size_t test_bdos_of_pointer(struct annotated_sized_ptr *p) {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
// 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:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP3]]) #[[ATTR5:[0-9]+]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[CONT8]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
@@ -78,7 +251,7 @@ size_t test_bdos_of_pointer(struct annotated_sized_ptr *p) {
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[RESULT]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -4294967295, 4294967296) i64 @test_bdos_of_element_address(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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
@@ -97,7 +270,7 @@ size_t test_bdos_of_pointer(struct annotated_sized_ptr *p) {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_element_address(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -110,19 +283,20 @@ size_t test_bdos_of_element_address(struct annotated_sized_ptr *p, int index) {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
// 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:%.*]] = icmp ult i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl i32 [[INDEX]], 3
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[TMP4]]) #[[ATTR5]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[CONT10]]:
// SANITIZE-WITH-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test_bdos_of_subscript_through_cast(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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
//
@@ -132,7 +306,7 @@ size_t test_bdos_of_element_address(struct annotated_sized_ptr *p, int index) {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_subscript_through_cast(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -160,7 +334,7 @@ struct annotated_sized_ptr_non_byte_sized_pointee {
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test_bdos_of_pointer_multibyte_pointee(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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 16
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
@@ -174,7 +348,7 @@ struct annotated_sized_ptr_non_byte_sized_pointee {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_pointer_multibyte_pointee(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
@@ -182,29 +356,33 @@ size_t test_bdos_of_pointer_multibyte_pointee(struct annotated_sized_ptr_non_byt
return __bdos(p->buf); // byte_count, not byte_count * sizeof(struct foo)
}
-// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 19327352832) i64 @test_bdos_of_element_address_multibyte_pointee(
+// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869175, 19327352832) i64 @test_bdos_of_element_address_multibyte_pointee(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
// 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:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl i32 [[INDEX]], 3
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ule i32 [[TMP0]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[TMP4]]) #[[ATTR5]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[CONT8]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[INDEX_SIZE:%.*]] = shl nsw i64 [[IDXPROM]], 3
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT]], [[INDEX_SIZE]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
-// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i64 [[RESULT]], -1
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[INDEX]], -1
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = and i1 [[TMP6]], [[TMP5]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = select i1 [[TMP7]], i64 [[RESULT]], i64 0
+// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP8]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -19327352824, 19327352832) i64 @test_bdos_of_element_address_multibyte_pointee(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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
@@ -224,7 +402,7 @@ size_t test_bdos_of_pointer_multibyte_pointee(struct annotated_sized_ptr_non_byt
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_element_address_multibyte_pointee(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -254,7 +432,7 @@ struct annotated_sized_ptr_incomplete {
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test_bdos_of_pointer_incomplete_pointee(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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 16
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4
@@ -268,7 +446,7 @@ struct annotated_sized_ptr_incomplete {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_pointer_incomplete_pointee(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
@@ -287,7 +465,7 @@ size_t test_bdos_of_pointer_incomplete_pointee(struct annotated_sized_ptr_incomp
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[CONT8]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
@@ -296,7 +474,7 @@ size_t test_bdos_of_pointer_incomplete_pointee(struct annotated_sized_ptr_incomp
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[RESULT]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -4294967295, 4294967296) i64 @test_bdos_of_element_address_incomplete_pointee(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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
@@ -315,7 +493,7 @@ size_t test_bdos_of_pointer_incomplete_pointee(struct annotated_sized_ptr_incomp
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_element_address_incomplete_pointee(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -343,7 +521,7 @@ void take_ptr_with_size(void *p __attribute__((pass_dynamic_object_size(0))));
// SANITIZE-WITH-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test_bdos_of_volatile_pointer(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1
//
@@ -353,7 +531,7 @@ void take_ptr_with_size(void *p __attribute__((pass_dynamic_object_size(0))));
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test_bdos_of_volatile_pointer(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
@@ -369,7 +547,7 @@ size_t test_bdos_of_volatile_pointer(struct annotated_volatile_ptr *p) {
// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA8:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA16:![0-9]+]]
// 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 8
// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0)
@@ -378,28 +556,28 @@ size_t test_bdos_of_volatile_pointer(struct annotated_volatile_ptr *p) {
// SANITIZE-WITH-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] {
// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14:![0-9]+]]
// 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 8
// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0)
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext nneg i32 [[NARROW]] to i64
-// NO-SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef [[TMP1]]) #[[ATTR6:[0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef [[TMP1]]) #[[ATTR7:[0-9]+]]
// NO-SANITIZE-WITH-ATTR-NEXT: ret void
//
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6:![0-9]+]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14:![0-9]+]]
// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef -1) #[[ATTR3:[0-9]+]]
// SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6:![0-9]+]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef -1) #[[ATTR5:[0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14:![0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef -1) #[[ATTR6:[0-9]+]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
void test_pass_dynamic_object_size_of_pointer(struct annotated_volatile_ptr *p) {
@@ -411,7 +589,7 @@ void test_pass_dynamic_object_size_of_pointer(struct annotated_volatile_ptr *p)
// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA8]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA16]]
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
@@ -420,7 +598,7 @@ void test_pass_dynamic_object_size_of_pointer(struct annotated_volatile_ptr *p)
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT6:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[TMP4]]) #[[ATTR5]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[TMP4]]) #[[ATTR5]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[CONT6]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
@@ -431,9 +609,9 @@ void test_pass_dynamic_object_size_of_pointer(struct annotated_volatile_ptr *p)
// SANITIZE-WITH-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR3]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR4]] {
// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
@@ -444,25 +622,25 @@ void test_pass_dynamic_object_size_of_pointer(struct annotated_volatile_ptr *p)
// 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: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef [[TMP4]]) #[[ATTR6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef [[TMP4]]) #[[ATTR7]]
// NO-SANITIZE-WITH-ATTR-NEXT: ret void
//
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14]]
// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef -1) #[[ATTR3]]
// SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR3]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR4]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef -1) #[[ATTR5]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef -1) #[[ATTR6]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
void test_pass_dynamic_object_size_of_element_address(struct annotated_volatile_ptr *p, int index) {
@@ -471,29 +649,33 @@ void test_pass_dynamic_object_size_of_element_address(struct annotated_volatile_
// __bdos of '&((cast) ptr->buf)[idx]': the byte count is scaled by the cast
// element size (here 4), not the void* size.
-// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 10737418240) i64 @test_bdos_of_element_address_through_widening_cast(
+// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934587, 10737418240) i64 @test_bdos_of_element_address_through_widening_cast(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
// 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:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl i32 [[INDEX]], 2
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ule i32 [[TMP0]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF7]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META6]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP4]]) #[[ATTR5]], !nosanitize [[META6]]
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META6]]
// SANITIZE-WITH-ATTR: [[CONT8]]:
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[INDEX_SIZE:%.*]] = shl nsw i64 [[IDXPROM]], 2
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT]], [[INDEX_SIZE]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
-// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i64 [[RESULT]], -1
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[INDEX]], -1
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = and i1 [[TMP6]], [[TMP5]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = select i1 [[TMP7]], i64 [[RESULT]], i64 0
+// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP8]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -10737418236, 10737418240) i64 @test_bdos_of_element_address_through_widening_cast(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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
@@ -513,7 +695,7 @@ void test_pass_dynamic_object_size_of_element_address(struct annotated_volatile_
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_element_address_through_widening_cast(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -526,32 +708,60 @@ size_t test_bdos_of_element_address_through_widening_cast(struct annotated_sized
// SANITIZE-WITH-ATTR: [[META5]] = !{!"Simple C/C++ TBAA"}
// SANITIZE-WITH-ATTR: [[META6]] = !{}
// SANITIZE-WITH-ATTR: [[PROF7]] = !{!"branch_weights", i32 1048575, i32 1}
-// SANITIZE-WITH-ATTR: [[INTPTR_TBAA8]] = !{[[META9:![0-9]+]], [[META10:![0-9]+]], i64 0}
-// SANITIZE-WITH-ATTR: [[META9]] = !{!"annotated_volatile_ptr", [[META10]], i64 0, [[META3]], i64 8}
-// SANITIZE-WITH-ATTR: [[META10]] = !{!"p1 int", [[META11:![0-9]+]], i64 0}
-// SANITIZE-WITH-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
+// SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA8]] = !{[[META9:![0-9]+]], [[META11:![0-9]+]], i64 8}
+// SANITIZE-WITH-ATTR: [[META9]] = !{!"annotated_ptr", [[META10:![0-9]+]], i64 0, [[META11]], i64 8, [[META3]], i64 16}
+// SANITIZE-WITH-ATTR: [[META10]] = !{!"long", [[META4]], i64 0}
+// SANITIZE-WITH-ATTR: [[META11]] = !{!"p2 _ZTS3foo", [[META12:![0-9]+]], i64 0}
+// SANITIZE-WITH-ATTR: [[META12]] = !{!"any p2 pointer", [[META13:![0-9]+]], i64 0}
+// SANITIZE-WITH-ATTR: [[META13]] = !{!"any pointer", [[META4]], i64 0}
+// SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META15]], i64 0}
+// SANITIZE-WITH-ATTR: [[META15]] = !{!"p1 _ZTS3foo", [[META13]], i64 0}
+// SANITIZE-WITH-ATTR: [[INTPTR_TBAA16]] = !{[[META17:![0-9]+]], [[META18:![0-9]+]], i64 0}
+// SANITIZE-WITH-ATTR: [[META17]] = !{!"annotated_volatile_ptr", [[META18]], i64 0, [[META3]], i64 8}
+// SANITIZE-WITH-ATTR: [[META18]] = !{!"p1 int", [[META13]], i64 0}
//.
// NO-SANITIZE-WITH-ATTR: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0}
// NO-SANITIZE-WITH-ATTR: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
// NO-SANITIZE-WITH-ATTR: [[META5]] = !{!"Simple C/C++ TBAA"}
-// NO-SANITIZE-WITH-ATTR: [[INTPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META8:![0-9]+]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[META7]] = !{!"annotated_volatile_ptr", [[META8]], i64 0, [[META3]], i64 8}
-// NO-SANITIZE-WITH-ATTR: [[META8]] = !{!"p1 int", [[META9:![0-9]+]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[META9]] = !{!"any pointer", [[META4]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META9:![0-9]+]], i64 8}
+// NO-SANITIZE-WITH-ATTR: [[META7]] = !{!"annotated_ptr", [[META8:![0-9]+]], i64 0, [[META9]], i64 8, [[META3]], i64 16}
+// NO-SANITIZE-WITH-ATTR: [[META8]] = !{!"long", [[META4]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META9]] = !{!"p2 _ZTS3foo", [[META10:![0-9]+]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META10]] = !{!"any p2 pointer", [[META11:![0-9]+]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META13]] = !{!"p1 _ZTS3foo", [[META11]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[INTPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META16:![0-9]+]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META15]] = !{!"annotated_volatile_ptr", [[META16]], i64 0, [[META3]], i64 8}
+// NO-SANITIZE-WITH-ATTR: [[META16]] = !{!"p1 int", [[META11]], i64 0}
//.
// SANITIZE-WITHOUT-ATTR: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0}
// SANITIZE-WITHOUT-ATTR: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
// SANITIZE-WITHOUT-ATTR: [[META5]] = !{!"Simple C/C++ TBAA"}
-// SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META8:![0-9]+]], i64 0}
-// SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_volatile_ptr", [[META8]], i64 0, [[META3]], i64 8}
-// SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"p1 int", [[META9:![0-9]+]], i64 0}
-// SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"any pointer", [[META4]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META9:![0-9]+]], i64 8}
+// SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_ptr", [[META8:![0-9]+]], i64 0, [[META9]], i64 8, [[META3]], i64 16}
+// SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"long", [[META4]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"p2 _ZTS3foo", [[META10:![0-9]+]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META10]] = !{!"any p2 pointer", [[META11:![0-9]+]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META13]] = !{!"p1 _ZTS3foo", [[META11]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META16:![0-9]+]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META15]] = !{!"annotated_volatile_ptr", [[META16]], i64 0, [[META3]], i64 8}
+// SANITIZE-WITHOUT-ATTR: [[META16]] = !{!"p1 int", [[META11]], i64 0}
//.
// NO-SANITIZE-WITHOUT-ATTR: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0}
// NO-SANITIZE-WITHOUT-ATTR: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
// NO-SANITIZE-WITHOUT-ATTR: [[META5]] = !{!"Simple C/C++ TBAA"}
-// NO-SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META8:![0-9]+]], i64 0}
-// NO-SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_volatile_ptr", [[META8]], i64 0, [[META3]], i64 8}
-// NO-SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"p1 int", [[META9:![0-9]+]], i64 0}
-// NO-SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"any pointer", [[META4]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META9:![0-9]+]], i64 8}
+// NO-SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_ptr", [[META8:![0-9]+]], i64 0, [[META9]], i64 8, [[META3]], i64 16}
+// NO-SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"long", [[META4]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"p2 _ZTS3foo", [[META10:![0-9]+]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META10]] = !{!"any p2 pointer", [[META11:![0-9]+]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META13]] = !{!"p1 _ZTS3foo", [[META11]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META16:![0-9]+]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META15]] = !{!"annotated_volatile_ptr", [[META16]], i64 0, [[META3]], i64 8}
+// NO-SANITIZE-WITHOUT-ATTR: [[META16]] = !{!"p1 int", [[META11]], i64 0}
//.
diff --git a/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c b/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c
index 5f673e44a8ec3..03f5198c7ee44 100644
--- a/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c
+++ b/clang/test/CodeGen/attr-sized-by-or-null-for-pointers.c
@@ -25,6 +25,185 @@
typedef long unsigned int size_t;
struct foo { size_t field; };
+struct annotated_ptr {
+ unsigned long flags;
+ struct foo **buf __sized_by_or_null(ptr_count);
+ int ptr_count;
+};
+
+// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript(
+// 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: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// 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: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl i32 [[INDEX]], 3
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i32 [[TMP3]], [[TMP2]], !nosanitize [[META12:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT15:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13:![0-9]+]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP7]]) #[[ATTR5:[0-9]+]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT15]]:
+// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript(
+// 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 [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12:![0-9]+]]
+// SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6:![0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12:![0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+void test_store_subscript(struct annotated_ptr *p, int index, struct foo *value) {
+ p->buf[index] = value;
+}
+
+// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// 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: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA6]]
+// 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: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl i32 [[INDEX]], 3
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i32 [[TMP3]], [[TMP2]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT15:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT15]]:
+// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14]]
+// SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// 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 [[_ZTS3FOOPTR_TBAA6]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_cast(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+void test_store_subscript_through_cast(struct annotated_ptr *p, int index, struct foo *value) {
+ ((struct foo **)((char *)p->buf))[index] = value;
+}
+
+// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// 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: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA6]]
+// 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: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl i32 [[INDEX]], 3
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ule i32 [[TMP3]], [[TMP2]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT15:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT15]]:
+// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA14]]
+// SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITH-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// 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 [[_ZTS3FOOPTR_TBAA6]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_store_subscript_through_deref_of_addressof(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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 [[_ZTS3FOOPTR_TBAA6]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP0]], i64 [[IDXPROM]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: store ptr [[VALUE]], ptr [[ARRAYIDX]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+void test_store_subscript_through_deref_of_addressof(struct annotated_ptr *p, int index, struct foo *value) {
+ *&*&*&p->buf[index] = value;
+}
struct annotated_sized_ptr {
unsigned long flags;
@@ -33,10 +212,10 @@ struct annotated_sized_ptr {
};
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test_bdos_of_pointer(
-// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
-// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[ANYPTR_TBAA6:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[ANYPTR_TBAA16:![0-9]+]]
// 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 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
@@ -46,10 +225,10 @@ struct annotated_sized_ptr {
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test_bdos_of_pointer(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1:[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 [[ANYPTR_TBAA6:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[ANYPTR_TBAA14:![0-9]+]]
// 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 8
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
@@ -59,12 +238,12 @@ struct annotated_sized_ptr {
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]]
//
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_pointer(
-// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[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
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_pointer(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -75,32 +254,33 @@ size_t test_bdos_of_pointer(struct annotated_sized_ptr *p) {
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 4294967296) i64 @test_bdos_of_element_address(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
+// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[ANYPTR_TBAA16]]
// 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:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META10:![0-9]+]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF11:![0-9]+]], !nosanitize [[META10]]
+// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ule i32 [[INDEX]], [[TMP2]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT13:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP3]]) #[[ATTR5:[0-9]+]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR: [[CONT8]]:
-// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
-// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[ANYPTR_TBAA6]]
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT13]]:
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
-// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP4]], null
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP5]], i64 0, i64 [[COUNT]]
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP1]], i64 0, i64 [[COUNT]]
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT_OR_NULL]], [[IDXPROM]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
-// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
+// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP7]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -4294967295, 4294967296) i64 @test_bdos_of_element_address(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
// 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 [[ANYPTR_TBAA6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[ANYPTR_TBAA14]]
// 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 8
@@ -120,7 +300,7 @@ size_t test_bdos_of_pointer(struct annotated_sized_ptr *p) {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_element_address(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -131,21 +311,26 @@ size_t test_bdos_of_element_address(struct annotated_sized_ptr *p, int index) {
// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test_bdos_of_subscript_through_cast(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
+// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[ANYPTR_TBAA16]]
// 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:%.*]] = icmp ult i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT10:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF11]], !nosanitize [[META10]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl i32 [[INDEX]], 3
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i32 [[TMP3]], [[TMP2]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT15:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR: [[CONT10]]:
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT15]]:
// SANITIZE-WITH-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test_bdos_of_subscript_through_cast(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree 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
//
@@ -155,7 +340,7 @@ size_t test_bdos_of_element_address(struct annotated_sized_ptr *p, int index) {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_subscript_through_cast(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -178,7 +363,7 @@ struct annotated_sized_ptr_non_byte_sized_pointee {
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
-// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA18:![0-9]+]]
// 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 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
@@ -188,10 +373,10 @@ struct annotated_sized_ptr_non_byte_sized_pointee {
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test_bdos_of_pointer_multibyte_pointee(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
// 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 [[_ZTS3FOOPTR_TBAA10:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA16:![0-9]+]]
// 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 8
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
@@ -206,7 +391,7 @@ struct annotated_sized_ptr_non_byte_sized_pointee {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_pointer_multibyte_pointee(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
@@ -214,36 +399,41 @@ size_t test_bdos_of_pointer_multibyte_pointee(struct annotated_sized_ptr_non_byt
return __bdos(p->buf); // p->buf ? byte_count : 0
}
-// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 19327352832) i64 @test_bdos_of_element_address_multibyte_pointee(
+// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -19327352824, 19327352832) i64 @test_bdos_of_element_address_multibyte_pointee(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
+// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA18]]
// 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:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF11]], !nosanitize [[META10]]
+// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl i32 [[INDEX]], 3
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ule i32 [[TMP3]], [[TMP2]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT13:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR: [[CONT8]]:
-// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
-// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA12]]
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT13]]:
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
-// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP4]], null
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP5]], i64 0, i64 [[COUNT]]
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP1]], i64 0, i64 [[COUNT]]
// SANITIZE-WITH-ATTR-NEXT: [[INDEX_SIZE:%.*]] = shl nsw i64 [[IDXPROM]], 3
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT_OR_NULL]], [[INDEX_SIZE]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
-// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp sgt i64 [[RESULT]], -1
+// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp sgt i32 [[INDEX]], -1
+// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = select i1 [[TMP10]], i64 [[RESULT]], i64 0
+// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP11]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -19327352824, 19327352832) i64 @test_bdos_of_element_address_multibyte_pointee(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
// 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 [[_ZTS3FOOPTR_TBAA10]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS3FOOPTR_TBAA16]]
// 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 8
@@ -264,7 +454,7 @@ size_t test_bdos_of_pointer_multibyte_pointee(struct annotated_sized_ptr_non_byt
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_element_address_multibyte_pointee(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -288,7 +478,7 @@ struct annotated_sized_ptr_incomplete {
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
-// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS13INCOMPLETE_TYPTR_TBAA15:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS13INCOMPLETE_TYPTR_TBAA20:![0-9]+]]
// 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 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
@@ -298,10 +488,10 @@ struct annotated_sized_ptr_incomplete {
// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test_bdos_of_pointer_incomplete_pointee(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
// 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 [[_ZTS13INCOMPLETE_TYPTR_TBAA13:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS13INCOMPLETE_TYPTR_TBAA18:![0-9]+]]
// 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 8
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
@@ -316,7 +506,7 @@ struct annotated_sized_ptr_incomplete {
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_pointer_incomplete_pointee(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
@@ -327,32 +517,33 @@ size_t test_bdos_of_pointer_incomplete_pointee(struct annotated_sized_ptr_incomp
// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 4294967296) i64 @test_bdos_of_element_address_incomplete_pointee(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
+// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS13INCOMPLETE_TYPTR_TBAA20]]
// 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:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF11]], !nosanitize [[META10]]
+// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ule i32 [[INDEX]], [[TMP2]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label %[[CONT13:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR: [[CONT8]]:
-// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
-// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS13INCOMPLETE_TYPTR_TBAA15]]
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[TMP6]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT13]]:
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
-// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP4]], null
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP5]], i64 0, i64 [[COUNT]]
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP1]], i64 0, i64 [[COUNT]]
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT_OR_NULL]], [[IDXPROM]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
-// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
+// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP7]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -4294967295, 4294967296) i64 @test_bdos_of_element_address_incomplete_pointee(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
// 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 [[_ZTS13INCOMPLETE_TYPTR_TBAA13]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[_ZTS13INCOMPLETE_TYPTR_TBAA18]]
// 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 8
@@ -372,7 +563,7 @@ size_t test_bdos_of_pointer_incomplete_pointee(struct annotated_sized_ptr_incomp
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_element_address_incomplete_pointee(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -400,7 +591,7 @@ void take_ptr_with_size(void *p __attribute__((pass_dynamic_object_size(0))));
// SANITIZE-WITH-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test_bdos_of_volatile_pointer(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1
//
@@ -410,7 +601,7 @@ void take_ptr_with_size(void *p __attribute__((pass_dynamic_object_size(0))));
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test_bdos_of_volatile_pointer(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
@@ -426,7 +617,7 @@ size_t test_bdos_of_volatile_pointer(struct annotated_volatile_ptr *p) {
// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA18:![0-9]+]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA23:![0-9]+]]
// 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 8
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
@@ -437,30 +628,30 @@ size_t test_bdos_of_volatile_pointer(struct annotated_volatile_ptr *p) {
// SANITIZE-WITH-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] {
// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA16:![0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA21:![0-9]+]]
// 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 8
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0)
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext nneg i32 [[TMP2]] to i64
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP3]]
-// NO-SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef [[TMP4]]) #[[ATTR6:[0-9]+]]
+// NO-SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef [[TMP4]]) #[[ATTR7:[0-9]+]]
// NO-SANITIZE-WITH-ATTR-NEXT: ret void
//
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6:![0-9]+]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14:![0-9]+]]
// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef -1) #[[ATTR3:[0-9]+]]
// SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_pointer(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6:![0-9]+]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef -1) #[[ATTR5:[0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14:![0-9]+]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[TMP0]], i64 noundef -1) #[[ATTR6:[0-9]+]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
void test_pass_dynamic_object_size_of_pointer(struct annotated_volatile_ptr *p) {
@@ -476,39 +667,42 @@ void test_pass_dynamic_object_size_of_pointer(struct annotated_volatile_ptr *p)
// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA18]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA23]]
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label %[[CONT9:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF11]], !nosanitize [[META10]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA23]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ule i32 [[INDEX]], [[TMP3]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP3]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT12:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[TMP4]]) #[[ATTR5]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR: [[CONT9]]:
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT12]]:
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA18]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp eq ptr [[TMP5]], null
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP6]], i64 0, i64 [[COUNT]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA23]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp eq ptr [[TMP8]], null
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP9]], i64 0, i64 [[COUNT]]
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT_OR_NULL]], [[IDXPROM]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
-// SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef [[TMP7]]) #[[ATTR6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
+// SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef [[TMP10]]) #[[ATTR6]]
// SANITIZE-WITH-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR3]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR4]] {
// NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA16]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA21]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
// 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 8
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64
-// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA16]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA21]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null
// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP2]], i64 0, i64 [[COUNT]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT_OR_NULL]], [[IDXPROM]]
@@ -516,25 +710,25 @@ void test_pass_dynamic_object_size_of_pointer(struct annotated_volatile_ptr *p)
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[INDEX]], -1
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = select i1 [[TMP5]], i64 [[RESULT]], i64 0
-// NO-SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef [[TMP6]]) #[[ATTR6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef [[TMP6]]) #[[ATTR7]]
// NO-SANITIZE-WITH-ATTR-NEXT: ret void
//
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6]]
+// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14]]
// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef -1) #[[ATTR3]]
// SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test_pass_dynamic_object_size_of_element_address(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR3]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef captures(address) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR4]] {
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRY:.*:]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA6]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load volatile ptr, ptr [[P]], align 8, !tbaa [[INTPTR_TBAA14]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[IDXPROM]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef -1) #[[ATTR5]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: tail call void @take_ptr_with_size(ptr noundef [[ARRAYIDX]], i64 noundef -1) #[[ATTR6]]
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
//
void test_pass_dynamic_object_size_of_element_address(struct annotated_volatile_ptr *p, int index) {
@@ -543,36 +737,41 @@ void test_pass_dynamic_object_size_of_element_address(struct annotated_volatile_
// __bdos of '&((cast) ptr->buf)[idx]': the byte count is scaled by the cast
// element size (here 4), not the void* size.
-// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 10737418240) i64 @test_bdos_of_element_address_through_widening_cast(
+// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -10737418236, 10737418240) i64 @test_bdos_of_element_address_through_widening_cast(
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
// SANITIZE-WITH-ATTR-NEXT: [[ENTRY:.*:]]
+// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[ANYPTR_TBAA16]]
// 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:%.*]] = icmp ule i32 [[INDEX]], [[DOTCOUNTED_BY_LOAD]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 0, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label %[[CONT8:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF11]], !nosanitize [[META10]]
+// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 8
+// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp eq ptr [[TMP0]], null
+// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 0, i32 [[DOTCOUNTED_BY_LOAD]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl i32 [[INDEX]], 2
+// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ule i32 [[TMP3]], [[TMP2]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP2]], 0, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label %[[CONT13:.*]], label %[[HANDLER_OUT_OF_BOUNDS:.*]], !prof [[PROF13]], !nosanitize [[META12]]
// SANITIZE-WITH-ATTR: [[HANDLER_OUT_OF_BOUNDS]]:
-// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[TMP3]]) #[[ATTR5]], !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META10]]
-// SANITIZE-WITH-ATTR: [[CONT8]]:
-// SANITIZE-WITH-ATTR-NEXT: [[BUF:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
-// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[ANYPTR_TBAA6]]
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext nneg i32 [[DOTCOUNTED_BY_LOAD]] to i64
+// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP7]]) #[[ATTR5]], !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META12]]
+// SANITIZE-WITH-ATTR: [[CONT13]]:
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
-// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP4]], null
-// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP5]], i64 0, i64 [[COUNT]]
+// SANITIZE-WITH-ATTR-NEXT: [[COUNT_OR_NULL:%.*]] = select i1 [[TMP1]], i64 0, i64 [[COUNT]]
// SANITIZE-WITH-ATTR-NEXT: [[INDEX_SIZE:%.*]] = shl nsw i64 [[IDXPROM]], 2
// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = sub nsw i64 [[COUNT_OR_NULL]], [[INDEX_SIZE]]
-// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = tail call i64 @llvm.smax.i64(i64 [[RESULT]], i64 0)
-// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP6]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp sgt i64 [[RESULT]], -1
+// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp sgt i32 [[INDEX]], -1
+// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]
+// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = select i1 [[TMP10]], i64 [[RESULT]], i64 0
+// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP11]]
//
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -10737418236, 10737418240) i64 @test_bdos_of_element_address_through_widening_cast(
-// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] {
// 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 [[ANYPTR_TBAA6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BUF]], align 8, !tbaa [[ANYPTR_TBAA14]]
// 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 8
@@ -593,7 +792,7 @@ void test_pass_dynamic_object_size_of_element_address(struct annotated_volatile_
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
//
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test_bdos_of_element_address_through_widening_cast(
-// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nofree 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
//
@@ -604,52 +803,76 @@ size_t test_bdos_of_element_address_through_widening_cast(struct annotated_sized
// SANITIZE-WITH-ATTR: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0}
// SANITIZE-WITH-ATTR: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
// SANITIZE-WITH-ATTR: [[META5]] = !{!"Simple C/C++ TBAA"}
-// SANITIZE-WITH-ATTR: [[ANYPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META9:![0-9]+]], i64 8}
-// SANITIZE-WITH-ATTR: [[META7]] = !{!"annotated_sized_ptr", [[META8:![0-9]+]], i64 0, [[META9]], i64 8, [[META3]], i64 16}
+// SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META9:![0-9]+]], i64 8}
+// SANITIZE-WITH-ATTR: [[META7]] = !{!"annotated_ptr", [[META8:![0-9]+]], i64 0, [[META9]], i64 8, [[META3]], i64 16}
// SANITIZE-WITH-ATTR: [[META8]] = !{!"long", [[META4]], i64 0}
-// SANITIZE-WITH-ATTR: [[META9]] = !{!"any pointer", [[META4]], i64 0}
-// SANITIZE-WITH-ATTR: [[META10]] = !{}
-// SANITIZE-WITH-ATTR: [[PROF11]] = !{!"branch_weights", i32 1048575, i32 1}
-// SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META14:![0-9]+]], i64 8}
-// SANITIZE-WITH-ATTR: [[META13]] = !{!"annotated_sized_ptr_non_byte_sized_pointee", [[META8]], i64 0, [[META14]], i64 8, [[META3]], i64 16}
-// SANITIZE-WITH-ATTR: [[META14]] = !{!"p1 _ZTS3foo", [[META9]], i64 0}
-// SANITIZE-WITH-ATTR: [[_ZTS13INCOMPLETE_TYPTR_TBAA15]] = !{[[META16:![0-9]+]], [[META17:![0-9]+]], i64 8}
-// SANITIZE-WITH-ATTR: [[META16]] = !{!"annotated_sized_ptr_incomplete", [[META8]], i64 0, [[META17]], i64 8, [[META3]], i64 16}
-// SANITIZE-WITH-ATTR: [[META17]] = !{!"p1 _ZTS13incomplete_ty", [[META9]], i64 0}
-// SANITIZE-WITH-ATTR: [[INTPTR_TBAA18]] = !{[[META19:![0-9]+]], [[META20:![0-9]+]], i64 0}
-// SANITIZE-WITH-ATTR: [[META19]] = !{!"annotated_volatile_ptr", [[META20]], i64 0, [[META3]], i64 8}
-// SANITIZE-WITH-ATTR: [[META20]] = !{!"p1 int", [[META9]], i64 0}
+// SANITIZE-WITH-ATTR: [[META9]] = !{!"p2 _ZTS3foo", [[META10:![0-9]+]], i64 0}
+// SANITIZE-WITH-ATTR: [[META10]] = !{!"any p2 pointer", [[META11:![0-9]+]], i64 0}
+// SANITIZE-WITH-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
+// SANITIZE-WITH-ATTR: [[META12]] = !{}
+// SANITIZE-WITH-ATTR: [[PROF13]] = !{!"branch_weights", i32 1048575, i32 1}
+// SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META15]], i64 0}
+// SANITIZE-WITH-ATTR: [[META15]] = !{!"p1 _ZTS3foo", [[META11]], i64 0}
+// SANITIZE-WITH-ATTR: [[ANYPTR_TBAA16]] = !{[[META17:![0-9]+]], [[META11]], i64 8}
+// SANITIZE-WITH-ATTR: [[META17]] = !{!"annotated_sized_ptr", [[META8]], i64 0, [[META11]], i64 8, [[META3]], i64 16}
+// SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA18]] = !{[[META19:![0-9]+]], [[META15]], i64 8}
+// SANITIZE-WITH-ATTR: [[META19]] = !{!"annotated_sized_ptr_non_byte_sized_pointee", [[META8]], i64 0, [[META15]], i64 8, [[META3]], i64 16}
+// SANITIZE-WITH-ATTR: [[_ZTS13INCOMPLETE_TYPTR_TBAA20]] = !{[[META21:![0-9]+]], [[META22:![0-9]+]], i64 8}
+// SANITIZE-WITH-ATTR: [[META21]] = !{!"annotated_sized_ptr_incomplete", [[META8]], i64 0, [[META22]], i64 8, [[META3]], i64 16}
+// SANITIZE-WITH-ATTR: [[META22]] = !{!"p1 _ZTS13incomplete_ty", [[META11]], i64 0}
+// SANITIZE-WITH-ATTR: [[INTPTR_TBAA23]] = !{[[META24:![0-9]+]], [[META25:![0-9]+]], i64 0}
+// SANITIZE-WITH-ATTR: [[META24]] = !{!"annotated_volatile_ptr", [[META25]], i64 0, [[META3]], i64 8}
+// SANITIZE-WITH-ATTR: [[META25]] = !{!"p1 int", [[META11]], i64 0}
//.
// NO-SANITIZE-WITH-ATTR: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0}
// NO-SANITIZE-WITH-ATTR: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
// NO-SANITIZE-WITH-ATTR: [[META5]] = !{!"Simple C/C++ TBAA"}
-// NO-SANITIZE-WITH-ATTR: [[ANYPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META9:![0-9]+]], i64 8}
-// NO-SANITIZE-WITH-ATTR: [[META7]] = !{!"annotated_sized_ptr", [[META8:![0-9]+]], i64 0, [[META9]], i64 8, [[META3]], i64 16}
+// NO-SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META9:![0-9]+]], i64 8}
+// NO-SANITIZE-WITH-ATTR: [[META7]] = !{!"annotated_ptr", [[META8:![0-9]+]], i64 0, [[META9]], i64 8, [[META3]], i64 16}
// NO-SANITIZE-WITH-ATTR: [[META8]] = !{!"long", [[META4]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[META9]] = !{!"any pointer", [[META4]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA10]] = !{[[META11:![0-9]+]], [[META12:![0-9]+]], i64 8}
-// NO-SANITIZE-WITH-ATTR: [[META11]] = !{!"annotated_sized_ptr_non_byte_sized_pointee", [[META8]], i64 0, [[META12]], i64 8, [[META3]], i64 16}
-// NO-SANITIZE-WITH-ATTR: [[META12]] = !{!"p1 _ZTS3foo", [[META9]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[_ZTS13INCOMPLETE_TYPTR_TBAA13]] = !{[[META14:![0-9]+]], [[META15:![0-9]+]], i64 8}
-// NO-SANITIZE-WITH-ATTR: [[META14]] = !{!"annotated_sized_ptr_incomplete", [[META8]], i64 0, [[META15]], i64 8, [[META3]], i64 16}
-// NO-SANITIZE-WITH-ATTR: [[META15]] = !{!"p1 _ZTS13incomplete_ty", [[META9]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[INTPTR_TBAA16]] = !{[[META17:![0-9]+]], [[META18:![0-9]+]], i64 0}
-// NO-SANITIZE-WITH-ATTR: [[META17]] = !{!"annotated_volatile_ptr", [[META18]], i64 0, [[META3]], i64 8}
-// NO-SANITIZE-WITH-ATTR: [[META18]] = !{!"p1 int", [[META9]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META9]] = !{!"p2 _ZTS3foo", [[META10:![0-9]+]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META10]] = !{!"any p2 pointer", [[META11:![0-9]+]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META13]] = !{!"p1 _ZTS3foo", [[META11]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[ANYPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META11]], i64 8}
+// NO-SANITIZE-WITH-ATTR: [[META15]] = !{!"annotated_sized_ptr", [[META8]], i64 0, [[META11]], i64 8, [[META3]], i64 16}
+// NO-SANITIZE-WITH-ATTR: [[_ZTS3FOOPTR_TBAA16]] = !{[[META17:![0-9]+]], [[META13]], i64 8}
+// NO-SANITIZE-WITH-ATTR: [[META17]] = !{!"annotated_sized_ptr_non_byte_sized_pointee", [[META8]], i64 0, [[META13]], i64 8, [[META3]], i64 16}
+// NO-SANITIZE-WITH-ATTR: [[_ZTS13INCOMPLETE_TYPTR_TBAA18]] = !{[[META19:![0-9]+]], [[META20:![0-9]+]], i64 8}
+// NO-SANITIZE-WITH-ATTR: [[META19]] = !{!"annotated_sized_ptr_incomplete", [[META8]], i64 0, [[META20]], i64 8, [[META3]], i64 16}
+// NO-SANITIZE-WITH-ATTR: [[META20]] = !{!"p1 _ZTS13incomplete_ty", [[META11]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[INTPTR_TBAA21]] = !{[[META22:![0-9]+]], [[META23:![0-9]+]], i64 0}
+// NO-SANITIZE-WITH-ATTR: [[META22]] = !{!"annotated_volatile_ptr", [[META23]], i64 0, [[META3]], i64 8}
+// NO-SANITIZE-WITH-ATTR: [[META23]] = !{!"p1 int", [[META11]], i64 0}
//.
// SANITIZE-WITHOUT-ATTR: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0}
// SANITIZE-WITHOUT-ATTR: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
// SANITIZE-WITHOUT-ATTR: [[META5]] = !{!"Simple C/C++ TBAA"}
-// SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META8:![0-9]+]], i64 0}
-// SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_volatile_ptr", [[META8]], i64 0, [[META3]], i64 8}
-// SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"p1 int", [[META9:![0-9]+]], i64 0}
-// SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"any pointer", [[META4]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META9:![0-9]+]], i64 8}
+// SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_ptr", [[META8:![0-9]+]], i64 0, [[META9]], i64 8, [[META3]], i64 16}
+// SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"long", [[META4]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"p2 _ZTS3foo", [[META10:![0-9]+]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META10]] = !{!"any p2 pointer", [[META11:![0-9]+]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META13]] = !{!"p1 _ZTS3foo", [[META11]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META16:![0-9]+]], i64 0}
+// SANITIZE-WITHOUT-ATTR: [[META15]] = !{!"annotated_volatile_ptr", [[META16]], i64 0, [[META3]], i64 8}
+// SANITIZE-WITHOUT-ATTR: [[META16]] = !{!"p1 int", [[META11]], i64 0}
//.
// NO-SANITIZE-WITHOUT-ATTR: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0}
// NO-SANITIZE-WITHOUT-ATTR: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
// NO-SANITIZE-WITHOUT-ATTR: [[META5]] = !{!"Simple C/C++ TBAA"}
-// NO-SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META8:![0-9]+]], i64 0}
-// NO-SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_volatile_ptr", [[META8]], i64 0, [[META3]], i64 8}
-// NO-SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"p1 int", [[META9:![0-9]+]], i64 0}
-// NO-SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"any pointer", [[META4]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA6]] = !{[[META7:![0-9]+]], [[META9:![0-9]+]], i64 8}
+// NO-SANITIZE-WITHOUT-ATTR: [[META7]] = !{!"annotated_ptr", [[META8:![0-9]+]], i64 0, [[META9]], i64 8, [[META3]], i64 16}
+// NO-SANITIZE-WITHOUT-ATTR: [[META8]] = !{!"long", [[META4]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META9]] = !{!"p2 _ZTS3foo", [[META10:![0-9]+]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META10]] = !{!"any p2 pointer", [[META11:![0-9]+]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META11]] = !{!"any pointer", [[META4]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[_ZTS3FOOPTR_TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META13]] = !{!"p1 _ZTS3foo", [[META11]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[INTPTR_TBAA14]] = !{[[META15:![0-9]+]], [[META16:![0-9]+]], i64 0}
+// NO-SANITIZE-WITHOUT-ATTR: [[META15]] = !{!"annotated_volatile_ptr", [[META16]], i64 0, [[META3]], i64 8}
+// NO-SANITIZE-WITHOUT-ATTR: [[META16]] = !{!"p1 int", [[META11]], i64 0}
//.
More information about the cfe-commits
mailing list