[clang] [ubsan] Add more -fsanitize-annotate-debug-info checks (PR #141997)

Thurston Dang via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 5 09:57:03 PDT 2025


https://github.com/thurstond updated https://github.com/llvm/llvm-project/pull/141997

>From 6bc5c7c752786530ae202ee2bb5a71b0900e67e4 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Wed, 28 May 2025 17:14:39 +0000
Subject: [PATCH 01/26] [ubsan] Add more -fsanitize-annotate-debug-info checks

This extends https://github.com/llvm/llvm-project/pull/138577 to more
UBSan checks.

Note that the annotations are less detailed: they will always be
__ubsan_check_singularity, rather than using the SanitizerKind (previous
behavior, which is not always possible for all UBSan checks) or SanitizerHandler.
This is a (minor) regression compared to
https://github.com/llvm/llvm-project/pull/128977 and
https://github.com/llvm/llvm-project/pull/139809.

Updates the tests from https://github.com/llvm/llvm-project/pull/128976,
https://github.com/llvm/llvm-project/pull/139149 and https://github.com/llvm/llvm-project/pull/141814.
---
 clang/lib/CodeGen/CGBuiltin.cpp               |   9 +-
 clang/lib/CodeGen/CGCall.cpp                  |   6 +-
 clang/lib/CodeGen/CGClass.cpp                 |   8 +-
 clang/lib/CodeGen/CGDecl.cpp                  |   4 +-
 clang/lib/CodeGen/CGExpr.cpp                  |  71 +++++----
 clang/lib/CodeGen/CGExprScalar.cpp            |  60 ++++++--
 clang/lib/CodeGen/CGObjC.cpp                  |   2 +-
 clang/lib/CodeGen/CodeGenFunction.cpp         |  16 ++-
 clang/lib/CodeGen/CodeGenFunction.h           |  13 +-
 clang/lib/CodeGen/ItaniumCXXABI.cpp           |  10 +-
 .../test/CodeGen/bounds-checking-debuginfo.c  |  12 +-
 clang/test/CodeGen/cfi-check-fail-debuginfo.c |  25 ++--
 .../CodeGen/cfi-icall-generalize-debuginfo.c  |  50 +++----
 .../CodeGen/cfi-icall-normalize2-debuginfo.c  | 135 +++++++++---------
 clang/test/CodeGen/ubsan-function-debuginfo.c |  35 ++---
 .../CodeGen/unsigned-promotion-debuginfo.c    |  33 +++--
 16 files changed, 269 insertions(+), 220 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 89b321090f2d8..94cb399ab23d4 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2006,7 +2006,7 @@ Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
   if (!SanOpts.has(SanitizerKind::Builtin))
     return ArgValue;
 
-  SanitizerScope SanScope(this);
+  SanitizerScope SanScope(this, {SanitizerKind::SO_Builtin});
   Value *Cond = Builder.CreateICmpNE(
       ArgValue, llvm::Constant::getNullValue(ArgValue->getType()));
   EmitCheck(std::make_pair(Cond, SanitizerKind::SO_Builtin),
@@ -2022,7 +2022,7 @@ Value *CodeGenFunction::EmitCheckedArgForAssume(const Expr *E) {
   if (!SanOpts.has(SanitizerKind::Builtin))
     return ArgValue;
 
-  SanitizerScope SanScope(this);
+  SanitizerScope SanScope(this, {SanitizerKind::SO_Builtin});
   EmitCheck(
       std::make_pair(ArgValue, SanitizerKind::SO_Builtin),
       SanitizerHandler::InvalidBuiltin,
@@ -2048,7 +2048,10 @@ static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E,
       return EmitAbs(CGF, ArgValue, true);
   }
 
-  CodeGenFunction::SanitizerScope SanScope(&CGF);
+  SmallVector<SanitizerKind::SanitizerOrdinal, 3> Kinds;
+  if (SanitizeOverflow)
+    Kinds.push_back(SanitizerKind::SO_SignedIntegerOverflow);
+  CodeGenFunction::SanitizerScope SanScope(&CGF, Kinds);
 
   Constant *Zero = Constant::getNullValue(ArgValue->getType());
   Value *ResultAndOverflow = CGF.Builder.CreateBinaryIntrinsic(
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index bd920a2e3f2dd..fedabea72d600 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4156,7 +4156,7 @@ void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV) {
     Handler = SanitizerHandler::NullabilityReturn;
   }
 
-  SanitizerScope SanScope(this);
+  SanitizerScope SanScope(this, {CheckKind});
 
   // Make sure the "return" source location is valid. If we're checking a
   // nullability annotation, make sure the preconditions for the check are met.
@@ -4541,7 +4541,7 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
     Handler = SanitizerHandler::NullabilityArg;
   }
 
-  SanitizerScope SanScope(this);
+  SanitizerScope SanScope(this, {CheckKind});
   llvm::Value *Cond = EmitNonNullRValueCheck(RV, ArgType);
   llvm::Constant *StaticData[] = {
       EmitCheckSourceLocation(ArgLoc),
@@ -5976,7 +5976,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
       // attribute to insert handler calls.
       if (SanOpts.hasOneOf(SanitizerKind::Address |
                            SanitizerKind::KernelAddress)) {
-        SanitizerScope SanScope(this);
+        SanitizerScope SanScope(this, {});
         llvm::IRBuilder<>::InsertPointGuard IPGuard(Builder);
         Builder.SetInsertPoint(CI);
         auto *FnType = llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 251b059c256f6..5b3d105d3444e 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1678,7 +1678,7 @@ namespace {
   static void EmitSanitizerDtorCallback(
       CodeGenFunction &CGF, StringRef Name, llvm::Value *Ptr,
       std::optional<CharUnits::QuantityType> PoisonSize = {}) {
-    CodeGenFunction::SanitizerScope SanScope(&CGF);
+    CodeGenFunction::SanitizerScope SanScope(&CGF, {});
     // Pass in void pointer and size of region as arguments to runtime
     // function
     SmallVector<llvm::Value *, 2> Args = {Ptr};
@@ -2885,7 +2885,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
           SanitizerMask::bitPosToMask(M), TypeName))
     return;
 
-  SanitizerScope SanScope(this);
+  SanitizerScope SanScope(this, {M});
   EmitSanitizerStatReport(SSK);
 
   llvm::Metadata *MD =
@@ -2942,11 +2942,9 @@ bool CodeGenFunction::ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD) {
 llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
     const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy,
     uint64_t VTableByteOffset) {
-  SanitizerScope SanScope(this);
+  SanitizerScope SanScope(this, {SanitizerKind::SO_CFIVCall});
 
   EmitSanitizerStatReport(llvm::SanStat_CFI_VCall);
-  ApplyDebugLocation ApplyTrapDI(
-      *this, SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIVCall));
 
   llvm::Metadata *MD =
       CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index f4549ab3033b2..52f7919f529f3 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -765,7 +765,7 @@ void CodeGenFunction::EmitNullabilityCheck(LValue LHS, llvm::Value *RHS,
 
   // Check if the right hand side of the assignment is nonnull, if the left
   // hand side must be nonnull.
-  SanitizerScope SanScope(this);
+  SanitizerScope SanScope(this, {SanitizerKind::SO_NullabilityAssign});
   llvm::Value *IsNotNull = Builder.CreateIsNotNull(RHS);
   llvm::Constant *StaticData[] = {
       EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(LHS.getType()),
@@ -2852,7 +2852,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
   if (requiresReturnValueNullabilityCheck()) {
     auto Nullability = Ty->getNullability();
     if (Nullability && *Nullability == NullabilityKind::NonNull) {
-      SanitizerScope SanScope(this);
+      SanitizerScope SanScope(this, {});
       RetValNullabilityPrecondition =
           Builder.CreateAnd(RetValNullabilityPrecondition,
                             Builder.CreateIsNotNull(Arg.getAnyValue()));
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index bae28b45afaa3..69e1e2060a61f 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -748,7 +748,9 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
   if (Ty.isVolatileQualified())
     return;
 
-  SanitizerScope SanScope(this);
+  SanitizerScope SanScope(
+      this, {SanitizerKind::SO_Null, SanitizerKind::SO_ObjectSize,
+             SanitizerKind::SO_Alignment, SanitizerKind::SO_Vptr});
 
   SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 3>
       Checks;
@@ -989,7 +991,7 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
     if (CE->getCastKind() == CK_ArrayToPointerDecay &&
         !CE->getSubExpr()->isFlexibleArrayMemberLike(CGF.getContext(),
                                                      StrictFlexArraysLevel)) {
-      CodeGenFunction::SanitizerScope SanScope(&CGF);
+      CodeGenFunction::SanitizerScope SanScope(&CGF, {});
 
       IndexedType = CE->getSubExpr()->getType();
       const ArrayType *AT = IndexedType->castAsArrayTypeUnsafe();
@@ -1002,7 +1004,7 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
     }
   }
 
-  CodeGenFunction::SanitizerScope SanScope(&CGF);
+  CodeGenFunction::SanitizerScope SanScope(&CGF, {});
 
   QualType EltTy{Base->getType()->getPointeeOrArrayElementType(), 0};
   if (llvm::Value *POS = CGF.LoadPassedObjectSize(Base, EltTy)) {
@@ -1224,10 +1226,8 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
   if (!Bound)
     return;
 
-  SanitizerScope SanScope(this);
-
   auto CheckKind = SanitizerKind::SO_ArrayBounds;
-  ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(CheckKind));
+  SanitizerScope SanScope(this, {CheckKind});
 
   bool IndexSigned = IndexType->isSignedIntegerOrEnumerationType();
   llvm::Value *IndexVal = Builder.CreateIntCast(Index, SizeTy, IndexSigned);
@@ -1245,30 +1245,21 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
 }
 
 llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
-    SanitizerKind::SanitizerOrdinal CheckKindOrdinal) {
-  std::string Label;
-  switch (CheckKindOrdinal) {
-#define SANITIZER(NAME, ID)                                                    \
-  case SanitizerKind::SO_##ID:                                                 \
-    Label = "__ubsan_check_" NAME;                                             \
-    break;
-#include "clang/Basic/Sanitizers.def"
-  default:
-    llvm_unreachable("unexpected sanitizer kind");
-  }
-
-  // Sanitize label
-  for (unsigned int i = 0; i < Label.length(); i++)
-    if (!std::isalpha(Label[i]))
-      Label[i] = '_';
-
+    ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals) {
   llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
-  // TODO: deprecate ClArrayBoundsPseudoFn
-  if (((ClArrayBoundsPseudoFn &&
-        CheckKindOrdinal == SanitizerKind::SO_ArrayBounds) ||
-       CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo.has(CheckKindOrdinal)) &&
-      CheckDI)
-    CheckDI = getDebugInfo()->CreateSyntheticInlineAt(CheckDI, Label);
+
+  // TODO: the annotation could be more precise:
+  // 1) use the ordinal name if there is only one ordinal
+  // 2) use the overarching SanitizerHandler if there are multiple ordinals
+  for (auto Ord : Ordinals) {
+    if (((ClArrayBoundsPseudoFn && Ord == SanitizerKind::SO_ArrayBounds) ||
+         CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo.has(Ord)) &&
+        CheckDI) {
+      CheckDI = getDebugInfo()->CreateSyntheticInlineAt(
+          CheckDI, "__ubsan_check_singularity");
+      break;
+    }
+  }
 
   return CheckDI;
 }
@@ -1994,8 +1985,11 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
   if (!getRangeForType(*this, Ty, Min, End, /*StrictEnums=*/true, IsBool))
     return true;
 
+  SanitizerKind::SanitizerOrdinal Kind =
+      NeedsEnumCheck ? SanitizerKind::SO_Enum : SanitizerKind::SO_Bool;
+
   auto &Ctx = getLLVMContext();
-  SanitizerScope SanScope(this);
+  SanitizerScope SanScope(this, {Kind});
   llvm::Value *Check;
   --End;
   if (!Min) {
@@ -2009,8 +2003,6 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
   }
   llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc),
                                   EmitCheckTypeDescriptor(Ty)};
-  SanitizerKind::SanitizerOrdinal Kind =
-      NeedsEnumCheck ? SanitizerKind::SO_Enum : SanitizerKind::SO_Bool;
   EmitCheck(std::make_pair(Check, Kind), SanitizerHandler::LoadInvalidValue,
             StaticArgs, Value);
   return true;
@@ -3931,7 +3923,14 @@ void CodeGenFunction::EmitCfiCheckStub() {
 // can be nullptr if the calling module has -fsanitize-trap behavior for this
 // check kind; in this case __cfi_check_fail traps as well.
 void CodeGenFunction::EmitCfiCheckFail() {
-  SanitizerScope SanScope(this);
+  // TODO: the SanitizerKind is not yet determined for this check (and might
+  // not even be available, if Data == nullptr). However, we still want to
+  // annotate the instrumentation. We approximate this by using all the CFI
+  // kinds.
+  SanitizerScope SanScope(
+      this, {SanitizerKind::SO_CFIVCall, SanitizerKind::SO_CFINVCall,
+             SanitizerKind::SO_CFIDerivedCast,
+             SanitizerKind::SO_CFIUnrelatedCast, SanitizerKind::SO_CFIICall});
   FunctionArgList Args;
   ImplicitParamDecl ArgData(getContext(), getContext().VoidPtrTy,
                             ImplicitParamKind::Other);
@@ -4030,7 +4029,7 @@ void CodeGenFunction::EmitCfiCheckFail() {
 
 void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
   if (SanOpts.has(SanitizerKind::Unreachable)) {
-    SanitizerScope SanScope(this);
+    SanitizerScope SanScope(this, {SanitizerKind::SO_Unreachable});
     EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
                              SanitizerKind::SO_Unreachable),
               SanitizerHandler::BuiltinUnreachable,
@@ -6271,7 +6270,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
       !isa<FunctionNoProtoType>(PointeeType)) {
     if (llvm::Constant *PrefixSig =
             CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
-      SanitizerScope SanScope(this);
+      SanitizerScope SanScope(this, {SanitizerKind::SO_Function});
       auto *TypeHash = getUBSanFunctionTypeHash(PointeeType);
 
       llvm::Type *PrefixSigType = PrefixSig->getType();
@@ -6350,7 +6349,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
   // function pointer is a member of the bit set for the function type.
   if (SanOpts.has(SanitizerKind::CFIICall) &&
       (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
-    SanitizerScope SanScope(this);
+    SanitizerScope SanScope(this, {SanitizerKind::SO_CFIICall});
     EmitSanitizerStatReport(llvm::SanStat_CFI_ICall);
     ApplyDebugLocation ApplyTrapDI(
         *this, SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIICall));
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 111b5805c6a94..d449a2b30eef5 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -999,7 +999,8 @@ void ScalarExprEmitter::EmitFloatConversionCheck(
   if (!isa<llvm::IntegerType>(DstTy))
     return;
 
-  CodeGenFunction::SanitizerScope SanScope(&CGF);
+  CodeGenFunction::SanitizerScope SanScope(
+      &CGF, {SanitizerKind::SO_FloatCastOverflow});
   using llvm::APFloat;
   using llvm::APSInt;
 
@@ -1134,18 +1135,26 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
       (!SrcSigned && DstSigned))
     return;
 
-  CodeGenFunction::SanitizerScope SanScope(&CGF);
-
   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
             std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
-      Check =
-          EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
-  // If the comparison result is 'i1 false', then the truncation was lossy.
+      Check;
+
+  {
+    // We don't know the check kind yet
+    CodeGenFunction::SanitizerScope SanScope(
+        &CGF, {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
+               SanitizerKind::SO_ImplicitSignedIntegerTruncation});
+    Check =
+        EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
+    // If the comparison result is 'i1 false', then the truncation was lossy.
+  }
 
   // Do we care about this type of truncation?
   if (!CGF.SanOpts.has(Check.second.second))
     return;
 
+  CodeGenFunction::SanitizerScope SanScope(&CGF, {Check.second.second});
+
   // Does some SSCL ignore this type?
   if (CGF.getContext().isTypeIgnoredBySanitizer(
           SanitizerMask::bitPosToMask(Check.second.second), DstType))
@@ -1272,7 +1281,9 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
     return;
   // That's it. We can't rule out any more cases with the data we have.
 
-  CodeGenFunction::SanitizerScope SanScope(&CGF);
+  CodeGenFunction::SanitizerScope SanScope(
+      &CGF, {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
+             SanitizerKind::SO_ImplicitSignedIntegerTruncation});
 
   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
             std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
@@ -1393,7 +1404,8 @@ void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType,
   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
 
-  CodeGenFunction::SanitizerScope SanScope(this);
+  CodeGenFunction::SanitizerScope SanScope(
+      this, {SanitizerKind::SO_ImplicitBitfieldConversion});
 
   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
             std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
@@ -3975,7 +3987,10 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
 
 Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
   {
-    CodeGenFunction::SanitizerScope SanScope(&CGF);
+    CodeGenFunction::SanitizerScope SanScope(
+        &CGF, {SanitizerKind::SO_IntegerDivideByZero,
+               SanitizerKind::SO_SignedIntegerOverflow,
+               SanitizerKind::SO_FloatDivideByZero});
     if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
          CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
         Ops.Ty->isIntegerType() &&
@@ -4029,7 +4044,9 @@ Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
        CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
       Ops.Ty->isIntegerType() &&
       (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
-    CodeGenFunction::SanitizerScope SanScope(&CGF);
+    CodeGenFunction::SanitizerScope SanScope(
+        &CGF, {SanitizerKind::SO_IntegerDivideByZero,
+               SanitizerKind::SO_SignedIntegerOverflow});
     llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
     EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
   }
@@ -4078,7 +4095,9 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
   if (isSigned)
     OpID |= 1;
 
-  CodeGenFunction::SanitizerScope SanScope(&CGF);
+  CodeGenFunction::SanitizerScope SanScope(
+      &CGF, {SanitizerKind::SO_SignedIntegerOverflow,
+             SanitizerKind::SO_UnsignedIntegerOverflow});
   llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
 
   llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
@@ -4204,7 +4223,8 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
                              PtrTy->getPointerAddressSpace()))
       return Ptr;
     // The inbounds GEP of null is valid iff the index is zero.
-    CodeGenFunction::SanitizerScope SanScope(&CGF);
+    CodeGenFunction::SanitizerScope SanScope(
+        &CGF, {SanitizerKind::SO_PointerOverflow});
     Value *IsZeroIndex = CGF.Builder.CreateIsNull(index);
     llvm::Constant *StaticArgs[] = {
         CGF.EmitCheckSourceLocation(op.E->getExprLoc())};
@@ -4734,7 +4754,16 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
     RHS = ConstrainShiftValue(Ops.LHS, RHS, "shl.mask");
   else if ((SanitizeBase || SanitizeExponent) &&
            isa<llvm::IntegerType>(Ops.LHS->getType())) {
-    CodeGenFunction::SanitizerScope SanScope(&CGF);
+    SmallVector<SanitizerKind::SanitizerOrdinal, 3> Kinds;
+    if (SanitizeSignedBase)
+      Kinds.push_back(SanitizerKind::SO_ShiftBase);
+    if (SanitizeUnsignedBase)
+      Kinds.push_back(SanitizerKind::SO_UnsignedShiftBase);
+    if (SanitizeExponent) {
+      Kinds.push_back(SanitizerKind::SO_ShiftExponent);
+    }
+
+    CodeGenFunction::SanitizerScope SanScope(&CGF, Kinds);
     SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
     bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
     llvm::Value *WidthMinusOne =
@@ -4805,7 +4834,8 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
     RHS = ConstrainShiftValue(Ops.LHS, RHS, "shr.mask");
   else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) &&
            isa<llvm::IntegerType>(Ops.LHS->getType())) {
-    CodeGenFunction::SanitizerScope SanScope(&CGF);
+    CodeGenFunction::SanitizerScope SanScope(&CGF,
+                                             {SanitizerKind::SO_ShiftExponent});
     bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
     llvm::Value *Valid = Builder.CreateICmpULE(
         Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
@@ -6037,7 +6067,7 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
 
   const auto &DL = CGM.getDataLayout();
 
-  SanitizerScope SanScope(this);
+  SanitizerScope SanScope(this, {SanitizerKind::SO_PointerOverflow});
   llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
 
   GEPOffsetAndOverflow EvaluatedGEP =
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 73071bc60901b..950313539fa96 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1967,7 +1967,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
     const ObjCInterfaceType *InterfaceTy =
         ObjPtrTy ? ObjPtrTy->getInterfaceType() : nullptr;
     if (InterfaceTy) {
-      SanitizerScope SanScope(this);
+      SanitizerScope SanScope(this, {SanitizerKind::SO_ObjCCast});
       auto &C = CGM.getContext();
       assert(InterfaceTy->getDecl() && "No decl for ObjC interface type");
       Selector IsKindOfClassSel = GetUnarySelector("isKindOfClass", C);
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 4193f0a1b278f..0fe1a8fc76ef6 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1632,7 +1632,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
         CGM.getCodeGenOpts().StrictReturn ||
         !CGM.MayDropFunctionReturn(FD->getASTContext(), FD->getReturnType());
     if (SanOpts.has(SanitizerKind::Return)) {
-      SanitizerScope SanScope(this);
+      SanitizerScope SanScope(this, {SanitizerKind::SO_Return});
       llvm::Value *IsFalse = Builder.getFalse();
       EmitCheck(std::make_pair(IsFalse, SanitizerKind::SO_Return),
                 SanitizerHandler::MissingReturn,
@@ -2537,7 +2537,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
           //   expression [...] each time it is evaluated it shall have a value
           //   greater than zero.
           if (SanOpts.has(SanitizerKind::VLABound)) {
-            SanitizerScope SanScope(this);
+            SanitizerScope SanScope(this, {SanitizerKind::SO_VLABound});
             llvm::Value *Zero = llvm::Constant::getNullValue(size->getType());
             clang::QualType SEType = sizeExpr->getType();
             llvm::Value *CheckCondition =
@@ -2752,14 +2752,20 @@ Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
 
 CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { }
 
-CodeGenFunction::SanitizerScope::SanitizerScope(CodeGenFunction *CGF)
+CodeGenFunction::SanitizerScope::SanitizerScope(
+    CodeGenFunction *CGF, ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals)
     : CGF(CGF) {
   assert(!CGF->IsSanitizerScope);
   CGF->IsSanitizerScope = true;
+
+  this->ApplyTrapDI =
+      new ApplyDebugLocation(*CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals));
 }
 
 CodeGenFunction::SanitizerScope::~SanitizerScope() {
   CGF->IsSanitizerScope = false;
+
+  delete ((ApplyDebugLocation *)this->ApplyTrapDI);
 }
 
 void CodeGenFunction::InsertHelper(llvm::Instruction *I,
@@ -3192,7 +3198,7 @@ void CodeGenFunction::emitAlignmentAssumptionCheck(
   Assumption->removeFromParent();
 
   {
-    SanitizerScope SanScope(this);
+    SanitizerScope SanScope(this, {SanitizerKind::SO_Alignment});
 
     if (!OffsetValue)
       OffsetValue = Builder.getInt1(false); // no offset.
@@ -3355,4 +3361,4 @@ void CodeGenFunction::addInstToNewSourceAtom(llvm::Instruction *KeyInstruction,
     ApplyAtomGroup Grp(getDebugInfo());
     DI->addInstToCurrentSourceAtom(KeyInstruction, Backup);
   }
-}
\ No newline at end of file
+}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 92e9ab8156ad2..dbfebdfbb8df1 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -596,9 +596,11 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// RAII object to set/unset CodeGenFunction::IsSanitizerScope.
   class SanitizerScope {
     CodeGenFunction *CGF;
+    void *ApplyTrapDI;
 
   public:
-    SanitizerScope(CodeGenFunction *CGF);
+    SanitizerScope(CodeGenFunction *CGF,
+                   ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals);
     ~SanitizerScope();
   };
 
@@ -3390,10 +3392,11 @@ class CodeGenFunction : public CodeGenTypeCache {
                            llvm::Value *Index, QualType IndexType,
                            QualType IndexedType, bool Accessed);
 
-  /// Returns debug info, with additional annotation if enabled by
-  /// CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[CheckKindOrdinal].
-  llvm::DILocation *
-  SanitizerAnnotateDebugInfo(SanitizerKind::SanitizerOrdinal CheckKindOrdinal);
+  /// Returns debug info, with additional annotation if
+  /// CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[Ordinal] is enabled for
+  /// any of the ordinals.
+  llvm::DILocation *SanitizerAnnotateDebugInfo(
+      ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals);
 
   llvm::Value *GetCountedByFieldExprGEP(const Expr *Base, const FieldDecl *FD,
                                         const FieldDecl *CountDecl);
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index a2984941947c7..e68e8acc60190 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -702,9 +702,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
   llvm::Value *VirtualFn = nullptr;
 
   {
-    CodeGenFunction::SanitizerScope SanScope(&CGF);
-    ApplyDebugLocation ApplyTrapDI(
-        CGF, CGF.SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIMFCall));
+    CodeGenFunction::SanitizerScope SanScope(&CGF,
+                                             {SanitizerKind::SO_CFIMFCall});
 
     llvm::Value *TypeId = nullptr;
     llvm::Value *CheckResult = nullptr;
@@ -802,9 +801,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
   if (ShouldEmitCFICheck) {
     CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
     if (RD->hasDefinition()) {
-      CodeGenFunction::SanitizerScope SanScope(&CGF);
-      ApplyDebugLocation ApplyTrapDI(
-          CGF, CGF.SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIMFCall));
+      CodeGenFunction::SanitizerScope SanScope(&CGF,
+                                               {SanitizerKind::SO_CFIMFCall});
 
       llvm::Constant *StaticData[] = {
           llvm::ConstantInt::get(CGF.Int8Ty, CodeGenFunction::CFITCK_NVMFCall),
diff --git a/clang/test/CodeGen/bounds-checking-debuginfo.c b/clang/test/CodeGen/bounds-checking-debuginfo.c
index 74c06665dfe02..a6a1b16acb8e7 100644
--- a/clang/test/CodeGen/bounds-checking-debuginfo.c
+++ b/clang/test/CodeGen/bounds-checking-debuginfo.c
@@ -68,9 +68,9 @@ double f1(int b, int i) {
 
 //.
 // CHECK-TRAP: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK-TRAP: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// CHECK-TRAP: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // CHECK-TRAP: [[DBG4]] = distinct !DISubprogram(name: "f1", scope: [[META5:![0-9]+]], file: [[META5]], line: 63, type: [[META6:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]], retainedNodes: [[META10]])
-// CHECK-TRAP: [[META5]] = !DIFile(filename: "bounds-checking-debuginfo.c", directory: {{.*}})
+// CHECK-TRAP: [[META5]] = !DIFile(filename: "{{.*}}bounds-checking-debuginfo.c", directory: {{.*}})
 // CHECK-TRAP: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
 // CHECK-TRAP: [[META7]] = !{[[META8:![0-9]+]], [[META9:![0-9]+]], [[META9]]}
 // CHECK-TRAP: [[META8]] = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)
@@ -89,16 +89,16 @@ double f1(int b, int i) {
 // CHECK-TRAP: [[DBG21]] = !DILocation(line: 65, column: 3, scope: [[DBG4]])
 // CHECK-TRAP: [[DBG22]] = !DILocation(line: 66, column: 12, scope: [[DBG4]])
 // CHECK-TRAP: [[DBG23]] = !DILocation(line: 0, scope: [[META24:![0-9]+]], inlinedAt: [[DBG26]])
-// CHECK-TRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_array_bounds", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK-TRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK-TRAP: [[META25]] = !DISubroutineType(types: null)
 // CHECK-TRAP: [[DBG26]] = !DILocation(line: 66, column: 10, scope: [[DBG4]])
 // CHECK-TRAP: [[PROF27]] = !{!"branch_weights", i32 1048575, i32 1}
 // CHECK-TRAP: [[DBG28]] = !DILocation(line: 66, column: 3, scope: [[DBG4]])
 //.
 // CHECK-NOTRAP: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // CHECK-NOTRAP: [[DBG4]] = distinct !DISubprogram(name: "f1", scope: [[META5:![0-9]+]], file: [[META5]], line: 63, type: [[META6:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]], retainedNodes: [[META10]])
-// CHECK-NOTRAP: [[META5]] = !DIFile(filename: "bounds-checking-debuginfo.c", directory: {{.*}})
+// CHECK-NOTRAP: [[META5]] = !DIFile(filename: "{{.*}}bounds-checking-debuginfo.c", directory: {{.*}})
 // CHECK-NOTRAP: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
 // CHECK-NOTRAP: [[META7]] = !{[[META8:![0-9]+]], [[META9:![0-9]+]], [[META9]]}
 // CHECK-NOTRAP: [[META8]] = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)
@@ -117,7 +117,7 @@ double f1(int b, int i) {
 // CHECK-NOTRAP: [[DBG21]] = !DILocation(line: 65, column: 3, scope: [[DBG4]])
 // CHECK-NOTRAP: [[DBG22]] = !DILocation(line: 66, column: 12, scope: [[DBG4]])
 // CHECK-NOTRAP: [[DBG23]] = !DILocation(line: 0, scope: [[META24:![0-9]+]], inlinedAt: [[DBG26]])
-// CHECK-NOTRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_array_bounds", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK-NOTRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK-NOTRAP: [[META25]] = !DISubroutineType(types: null)
 // CHECK-NOTRAP: [[DBG26]] = !DILocation(line: 66, column: 10, scope: [[DBG4]])
 // CHECK-NOTRAP: [[PROF27]] = !{!"branch_weights", i32 1048575, i32 1}
diff --git a/clang/test/CodeGen/cfi-check-fail-debuginfo.c b/clang/test/CodeGen/cfi-check-fail-debuginfo.c
index 74ed5564ec704..39e5a014249f7 100644
--- a/clang/test/CodeGen/cfi-check-fail-debuginfo.c
+++ b/clang/test/CodeGen/cfi-check-fail-debuginfo.c
@@ -10,14 +10,14 @@
 // CHECK-SAME: ptr noundef [[F:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !dbg [[DBG7:![0-9]+]] !type [[META16:![0-9]+]] !type [[META17:![0-9]+]] !type [[META18:![0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:      #dbg_value(ptr [[F]], [[META15:![0-9]+]], !DIExpression(), [[META19:![0-9]+]])
-// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[F]], metadata !"_ZTSFvvE"), !dbg [[DBG20:![0-9]+]], !nosanitize [[META24:![0-9]+]]
-// CHECK-NEXT:    br i1 [[TMP0]], label %[[CFI_CONT:.*]], label %[[CFI_SLOWPATH:.*]], !dbg [[DBG20]], !prof [[PROF25:![0-9]+]], !nosanitize [[META24]]
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[F]], metadata !"_ZTSFvvE"), !dbg [[DBG20:![0-9]+]], !nosanitize [[META25:![0-9]+]]
+// CHECK-NEXT:    br i1 [[TMP0]], label %[[CFI_CONT:.*]], label %[[CFI_SLOWPATH:.*]], !dbg [[DBG20]], !prof [[PROF26:![0-9]+]], !nosanitize [[META25]]
 // CHECK:       [[CFI_SLOWPATH]]:
-// CHECK-NEXT:    tail call void @__cfi_slowpath(i64 9080559750644022485, ptr [[F]]) #[[ATTR6:[0-9]+]], !dbg [[DBG20]], !nosanitize [[META24]]
-// CHECK-NEXT:    br label %[[CFI_CONT]], !dbg [[DBG20]], !nosanitize [[META24]]
+// CHECK-NEXT:    tail call void @__cfi_slowpath(i64 9080559750644022485, ptr [[F]]) #[[ATTR6:[0-9]+]], !dbg [[DBG20]], !nosanitize [[META25]]
+// CHECK-NEXT:    br label %[[CFI_CONT]], !dbg [[DBG20]], !nosanitize [[META25]]
 // CHECK:       [[CFI_CONT]]:
-// CHECK-NEXT:    tail call void [[F]]() #[[ATTR6]], !dbg [[DBG23:![0-9]+]]
-// CHECK-NEXT:    ret void, !dbg [[DBG26:![0-9]+]]
+// CHECK-NEXT:    tail call void [[F]]() #[[ATTR6]], !dbg [[DBG24:![0-9]+]]
+// CHECK-NEXT:    ret void, !dbg [[DBG27:![0-9]+]]
 //
 void caller(void (*f)(void)) {
   f();
@@ -38,11 +38,12 @@ void caller(void (*f)(void)) {
 // CHECK: [[META17]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // CHECK: [[META18]] = !{i64 0, i64 2451761621477796417}
 // CHECK: [[META19]] = !DILocation(line: 0, scope: [[DBG7]])
-// CHECK: [[DBG20]] = !DILocation(line: 0, scope: [[META21:![0-9]+]], inlinedAt: [[DBG23]])
-// CHECK: [[META21]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall", scope: [[META8]], file: [[META8]], type: [[META22:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[DBG20]] = !DILocation(line: 0, scope: [[META21:![0-9]+]], inlinedAt: [[META23:![0-9]+]])
+// CHECK: [[META21]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META8]], file: [[META8]], type: [[META22:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META22]] = !DISubroutineType(types: null)
-// CHECK: [[DBG23]] = !DILocation(line: 23, column: 3, scope: [[DBG7]])
-// CHECK: [[META24]] = !{}
-// CHECK: [[PROF25]] = !{!"branch_weights", i32 1048575, i32 1}
-// CHECK: [[DBG26]] = !DILocation(line: 24, column: 1, scope: [[DBG7]])
+// CHECK: [[META23]] = !DILocation(line: 0, scope: [[META21]], inlinedAt: [[DBG24]])
+// CHECK: [[DBG24]] = !DILocation(line: 23, column: 3, scope: [[DBG7]])
+// CHECK: [[META25]] = !{}
+// CHECK: [[PROF26]] = !{!"branch_weights", i32 1048575, i32 1}
+// CHECK: [[DBG27]] = !DILocation(line: 24, column: 1, scope: [[DBG7]])
 //.
diff --git a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
index 304b60539c3d1..6f06fe7d89750 100644
--- a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
+++ b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
@@ -27,27 +27,27 @@ int** f(const char *a, const char **b) {
 // UNGENERALIZED-SAME: ptr noundef [[FP:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !dbg [[DBG25:![0-9]+]] !type [[META31:![0-9]+]] !type [[META32:![0-9]+]] {
 // UNGENERALIZED-NEXT:  [[ENTRY:.*:]]
 // UNGENERALIZED-NEXT:      #dbg_value(ptr [[FP]], [[META30:![0-9]+]], !DIExpression(), [[META33:![0-9]+]])
-// UNGENERALIZED-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FP]], metadata !"_ZTSFPPiPKcPS2_E"), !dbg [[DBG34:![0-9]+]], !nosanitize [[META38:![0-9]+]]
-// UNGENERALIZED-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF39:![0-9]+]], !nosanitize [[META38]]
+// UNGENERALIZED-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FP]], metadata !"_ZTSFPPiPKcPS2_E"), !dbg [[DBG34:![0-9]+]], !nosanitize [[META39:![0-9]+]]
+// UNGENERALIZED-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF40:![0-9]+]], !nosanitize [[META39]]
 // UNGENERALIZED:       [[TRAP]]:
-// UNGENERALIZED-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], !dbg [[DBG34]], !nosanitize [[META38]]
-// UNGENERALIZED-NEXT:    unreachable, !dbg [[DBG34]], !nosanitize [[META38]]
+// UNGENERALIZED-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], !dbg [[DBG34]], !nosanitize [[META39]]
+// UNGENERALIZED-NEXT:    unreachable, !dbg [[DBG34]], !nosanitize [[META39]]
 // UNGENERALIZED:       [[CONT]]:
-// UNGENERALIZED-NEXT:    [[CALL:%.*]] = tail call ptr [[FP]](ptr noundef null, ptr noundef null) #[[ATTR5:[0-9]+]], !dbg [[DBG37:![0-9]+]]
-// UNGENERALIZED-NEXT:    ret void, !dbg [[DBG40:![0-9]+]]
+// UNGENERALIZED-NEXT:    [[CALL:%.*]] = tail call ptr [[FP]](ptr noundef null, ptr noundef null) #[[ATTR5:[0-9]+]], !dbg [[DBG38:![0-9]+]]
+// UNGENERALIZED-NEXT:    ret void, !dbg [[DBG41:![0-9]+]]
 //
 // GENERALIZED-LABEL: define dso_local void @g(
 // GENERALIZED-SAME: ptr noundef [[FP:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !dbg [[DBG25:![0-9]+]] !type [[META31:![0-9]+]] !type [[META32:![0-9]+]] {
 // GENERALIZED-NEXT:  [[ENTRY:.*:]]
 // GENERALIZED-NEXT:      #dbg_value(ptr [[FP]], [[META30:![0-9]+]], !DIExpression(), [[META33:![0-9]+]])
-// GENERALIZED-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FP]], metadata !"_ZTSFPvPKvS_E.generalized"), !dbg [[DBG34:![0-9]+]], !nosanitize [[META38:![0-9]+]]
-// GENERALIZED-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF39:![0-9]+]], !nosanitize [[META38]]
+// GENERALIZED-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FP]], metadata !"_ZTSFPvPKvS_E.generalized"), !dbg [[DBG34:![0-9]+]], !nosanitize [[META39:![0-9]+]]
+// GENERALIZED-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF40:![0-9]+]], !nosanitize [[META39]]
 // GENERALIZED:       [[TRAP]]:
-// GENERALIZED-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], !dbg [[DBG34]], !nosanitize [[META38]]
-// GENERALIZED-NEXT:    unreachable, !dbg [[DBG34]], !nosanitize [[META38]]
+// GENERALIZED-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], !dbg [[DBG34]], !nosanitize [[META39]]
+// GENERALIZED-NEXT:    unreachable, !dbg [[DBG34]], !nosanitize [[META39]]
 // GENERALIZED:       [[CONT]]:
-// GENERALIZED-NEXT:    [[CALL:%.*]] = tail call ptr [[FP]](ptr noundef null, ptr noundef null) #[[ATTR5:[0-9]+]], !dbg [[DBG37:![0-9]+]]
-// GENERALIZED-NEXT:    ret void, !dbg [[DBG40:![0-9]+]]
+// GENERALIZED-NEXT:    [[CALL:%.*]] = tail call ptr [[FP]](ptr noundef null, ptr noundef null) #[[ATTR5:[0-9]+]], !dbg [[DBG38:![0-9]+]]
+// GENERALIZED-NEXT:    ret void, !dbg [[DBG41:![0-9]+]]
 //
 void g(int** (*fp)(const char *, const char **)) {
   fp(0, 0);
@@ -84,13 +84,14 @@ void g(int** (*fp)(const char *, const char **)) {
 // UNGENERALIZED: [[META31]] = !{i64 0, !"_ZTSFvPFPPiPKcPS2_EE"}
 // UNGENERALIZED: [[META32]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // UNGENERALIZED: [[META33]] = !DILocation(line: 0, scope: [[DBG25]])
-// UNGENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[DBG37]])
-// UNGENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// UNGENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[META37:![0-9]+]])
+// UNGENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // UNGENERALIZED: [[META36]] = !DISubroutineType(types: null)
-// UNGENERALIZED: [[DBG37]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
-// UNGENERALIZED: [[META38]] = !{}
-// UNGENERALIZED: [[PROF39]] = !{!"branch_weights", i32 1048575, i32 1}
-// UNGENERALIZED: [[DBG40]] = !DILocation(line: 54, column: 1, scope: [[DBG25]])
+// UNGENERALIZED: [[META37]] = !DILocation(line: 0, scope: [[META35]], inlinedAt: [[DBG38]])
+// UNGENERALIZED: [[DBG38]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
+// UNGENERALIZED: [[META39]] = !{}
+// UNGENERALIZED: [[PROF40]] = !{!"branch_weights", i32 1048575, i32 1}
+// UNGENERALIZED: [[DBG41]] = !DILocation(line: 54, column: 1, scope: [[DBG25]])
 //.
 // GENERALIZED: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: [[META2:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
 // GENERALIZED: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
@@ -122,11 +123,12 @@ void g(int** (*fp)(const char *, const char **)) {
 // GENERALIZED: [[META31]] = !{i64 0, !"_ZTSFvPFPPiPKcPS2_EE"}
 // GENERALIZED: [[META32]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // GENERALIZED: [[META33]] = !DILocation(line: 0, scope: [[DBG25]])
-// GENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[DBG37]])
-// GENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// GENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[META37:![0-9]+]])
+// GENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // GENERALIZED: [[META36]] = !DISubroutineType(types: null)
-// GENERALIZED: [[DBG37]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
-// GENERALIZED: [[META38]] = !{}
-// GENERALIZED: [[PROF39]] = !{!"branch_weights", i32 1048575, i32 1}
-// GENERALIZED: [[DBG40]] = !DILocation(line: 54, column: 1, scope: [[DBG25]])
+// GENERALIZED: [[META37]] = !DILocation(line: 0, scope: [[META35]], inlinedAt: [[DBG38]])
+// GENERALIZED: [[DBG38]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
+// GENERALIZED: [[META39]] = !{}
+// GENERALIZED: [[PROF40]] = !{!"branch_weights", i32 1048575, i32 1}
+// GENERALIZED: [[DBG41]] = !DILocation(line: 54, column: 1, scope: [[DBG25]])
 //.
diff --git a/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c b/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
index a2f6ee0c6805c..a5336b47398fa 100644
--- a/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
+++ b/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
@@ -12,53 +12,53 @@
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:      #dbg_value(ptr [[FN]], [[META16:![0-9]+]], !DIExpression(), [[META20:![0-9]+]])
 // CHECK-NEXT:      #dbg_value(i32 [[ARG]], [[META17:![0-9]+]], !DIExpression(), [[META20]])
-// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32E.normalized"), !dbg [[DBG21:![0-9]+]], !nosanitize [[META25:![0-9]+]]
-// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG21]], !prof [[PROF26:![0-9]+]], !nosanitize [[META25]]
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32E.normalized"), !dbg [[DBG21:![0-9]+]], !nosanitize [[META26:![0-9]+]]
+// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG21]], !prof [[PROF27:![0-9]+]], !nosanitize [[META26]]
 // CHECK:       [[TRAP]]:
-// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3:[0-9]+]], !dbg [[DBG21]], !nosanitize [[META25]]
-// CHECK-NEXT:    unreachable, !dbg [[DBG21]], !nosanitize [[META25]]
+// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3:[0-9]+]], !dbg [[DBG21]], !nosanitize [[META26]]
+// CHECK-NEXT:    unreachable, !dbg [[DBG21]], !nosanitize [[META26]]
 // CHECK:       [[CONT]]:
-// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG]]) #[[ATTR4:[0-9]+]], !dbg [[DBG24:![0-9]+]]
-// CHECK-NEXT:    ret void, !dbg [[DBG27:![0-9]+]]
+// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG]]) #[[ATTR4:[0-9]+]], !dbg [[DBG25:![0-9]+]]
+// CHECK-NEXT:    ret void, !dbg [[DBG28:![0-9]+]]
 //
 void foo(void (*fn)(int), int arg) {
     fn(arg);
 }
 
 // CHECK-LABEL: define dso_local void @bar(
-// CHECK-SAME: ptr noundef [[FN:%.*]], i32 noundef [[ARG1:%.*]], i32 noundef [[ARG2:%.*]]) local_unnamed_addr #[[ATTR0]] !dbg [[DBG28:![0-9]+]] !type [[META38:![0-9]+]] !type [[META39:![0-9]+]] {
+// CHECK-SAME: ptr noundef [[FN:%.*]], i32 noundef [[ARG1:%.*]], i32 noundef [[ARG2:%.*]]) local_unnamed_addr #[[ATTR0]] !dbg [[DBG29:![0-9]+]] !type [[META39:![0-9]+]] !type [[META40:![0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:      #dbg_value(ptr [[FN]], [[META35:![0-9]+]], !DIExpression(), [[META40:![0-9]+]])
-// CHECK-NEXT:      #dbg_value(i32 [[ARG1]], [[META36:![0-9]+]], !DIExpression(), [[META40]])
-// CHECK-NEXT:      #dbg_value(i32 [[ARG2]], [[META37:![0-9]+]], !DIExpression(), [[META40]])
-// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32S_E.normalized"), !dbg [[DBG41:![0-9]+]], !nosanitize [[META25]]
-// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG41]], !prof [[PROF26]], !nosanitize [[META25]]
+// CHECK-NEXT:      #dbg_value(ptr [[FN]], [[META36:![0-9]+]], !DIExpression(), [[META41:![0-9]+]])
+// CHECK-NEXT:      #dbg_value(i32 [[ARG1]], [[META37:![0-9]+]], !DIExpression(), [[META41]])
+// CHECK-NEXT:      #dbg_value(i32 [[ARG2]], [[META38:![0-9]+]], !DIExpression(), [[META41]])
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32S_E.normalized"), !dbg [[DBG42:![0-9]+]], !nosanitize [[META26]]
+// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG42]], !prof [[PROF27]], !nosanitize [[META26]]
 // CHECK:       [[TRAP]]:
-// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3]], !dbg [[DBG41]], !nosanitize [[META25]]
-// CHECK-NEXT:    unreachable, !dbg [[DBG41]], !nosanitize [[META25]]
+// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3]], !dbg [[DBG42]], !nosanitize [[META26]]
+// CHECK-NEXT:    unreachable, !dbg [[DBG42]], !nosanitize [[META26]]
 // CHECK:       [[CONT]]:
-// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG1]], i32 noundef [[ARG2]]) #[[ATTR4]], !dbg [[DBG42:![0-9]+]]
-// CHECK-NEXT:    ret void, !dbg [[DBG43:![0-9]+]]
+// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG1]], i32 noundef [[ARG2]]) #[[ATTR4]], !dbg [[DBG44:![0-9]+]]
+// CHECK-NEXT:    ret void, !dbg [[DBG45:![0-9]+]]
 //
 void bar(void (*fn)(int, int), int arg1, int arg2) {
     fn(arg1, arg2);
 }
 
 // CHECK-LABEL: define dso_local void @baz(
-// CHECK-SAME: ptr noundef [[FN:%.*]], i32 noundef [[ARG1:%.*]], i32 noundef [[ARG2:%.*]], i32 noundef [[ARG3:%.*]]) local_unnamed_addr #[[ATTR0]] !dbg [[DBG44:![0-9]+]] !type [[META55:![0-9]+]] !type [[META56:![0-9]+]] {
+// CHECK-SAME: ptr noundef [[FN:%.*]], i32 noundef [[ARG1:%.*]], i32 noundef [[ARG2:%.*]], i32 noundef [[ARG3:%.*]]) local_unnamed_addr #[[ATTR0]] !dbg [[DBG46:![0-9]+]] !type [[META57:![0-9]+]] !type [[META58:![0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:      #dbg_value(ptr [[FN]], [[META51:![0-9]+]], !DIExpression(), [[META57:![0-9]+]])
-// CHECK-NEXT:      #dbg_value(i32 [[ARG1]], [[META52:![0-9]+]], !DIExpression(), [[META57]])
-// CHECK-NEXT:      #dbg_value(i32 [[ARG2]], [[META53:![0-9]+]], !DIExpression(), [[META57]])
-// CHECK-NEXT:      #dbg_value(i32 [[ARG3]], [[META54:![0-9]+]], !DIExpression(), [[META57]])
-// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32S_S_E.normalized"), !dbg [[DBG58:![0-9]+]], !nosanitize [[META25]]
-// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG58]], !prof [[PROF26]], !nosanitize [[META25]]
+// CHECK-NEXT:      #dbg_value(ptr [[FN]], [[META53:![0-9]+]], !DIExpression(), [[META59:![0-9]+]])
+// CHECK-NEXT:      #dbg_value(i32 [[ARG1]], [[META54:![0-9]+]], !DIExpression(), [[META59]])
+// CHECK-NEXT:      #dbg_value(i32 [[ARG2]], [[META55:![0-9]+]], !DIExpression(), [[META59]])
+// CHECK-NEXT:      #dbg_value(i32 [[ARG3]], [[META56:![0-9]+]], !DIExpression(), [[META59]])
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32S_S_E.normalized"), !dbg [[DBG60:![0-9]+]], !nosanitize [[META26]]
+// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG60]], !prof [[PROF27]], !nosanitize [[META26]]
 // CHECK:       [[TRAP]]:
-// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3]], !dbg [[DBG58]], !nosanitize [[META25]]
-// CHECK-NEXT:    unreachable, !dbg [[DBG58]], !nosanitize [[META25]]
+// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3]], !dbg [[DBG60]], !nosanitize [[META26]]
+// CHECK-NEXT:    unreachable, !dbg [[DBG60]], !nosanitize [[META26]]
 // CHECK:       [[CONT]]:
-// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG1]], i32 noundef [[ARG2]], i32 noundef [[ARG3]]) #[[ATTR4]], !dbg [[DBG59:![0-9]+]]
-// CHECK-NEXT:    ret void, !dbg [[DBG60:![0-9]+]]
+// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG1]], i32 noundef [[ARG2]], i32 noundef [[ARG3]]) #[[ATTR4]], !dbg [[DBG62:![0-9]+]]
+// CHECK-NEXT:    ret void, !dbg [[DBG63:![0-9]+]]
 //
 void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) {
     fn(arg1, arg2, arg3);
@@ -81,44 +81,47 @@ void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) {
 // CHECK: [[META18]] = !{i64 0, !"_ZTSFvPFvu3i32ES_E.normalized"}
 // CHECK: [[META19]] = !{i64 0, !"_ZTSFvPvu3i32E.normalized.generalized"}
 // CHECK: [[META20]] = !DILocation(line: 0, scope: [[DBG7]])
-// CHECK: [[DBG21]] = !DILocation(line: 0, scope: [[META22:![0-9]+]], inlinedAt: [[DBG24]])
-// CHECK: [[META22]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall", scope: [[META8]], file: [[META8]], type: [[META23:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[DBG21]] = !DILocation(line: 0, scope: [[META22:![0-9]+]], inlinedAt: [[META24:![0-9]+]])
+// CHECK: [[META22]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META8]], file: [[META8]], type: [[META23:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META23]] = !DISubroutineType(types: null)
-// CHECK: [[DBG24]] = !DILocation(line: 25, column: 5, scope: [[DBG7]])
-// CHECK: [[META25]] = !{}
-// CHECK: [[PROF26]] = !{!"branch_weights", i32 1048575, i32 1}
-// CHECK: [[DBG27]] = !DILocation(line: 26, column: 1, scope: [[DBG7]])
-// CHECK: [[DBG28]] = distinct !DISubprogram(name: "bar", scope: [[META8]], file: [[META8]], line: 43, type: [[META29:![0-9]+]], scopeLine: 43, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META34:![0-9]+]])
-// CHECK: [[META29]] = !DISubroutineType(types: [[META30:![0-9]+]])
-// CHECK: [[META30]] = !{null, [[META31:![0-9]+]], [[META14]], [[META14]]}
-// CHECK: [[META31]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META32:![0-9]+]], size: 64)
-// CHECK: [[META32]] = !DISubroutineType(types: [[META33:![0-9]+]])
-// CHECK: [[META33]] = !{null, [[META14]], [[META14]]}
-// CHECK: [[META34]] = !{[[META35]], [[META36]], [[META37]]}
-// CHECK: [[META35]] = !DILocalVariable(name: "fn", arg: 1, scope: [[DBG28]], file: [[META8]], line: 43, type: [[META31]])
-// CHECK: [[META36]] = !DILocalVariable(name: "arg1", arg: 2, scope: [[DBG28]], file: [[META8]], line: 43, type: [[META14]])
-// CHECK: [[META37]] = !DILocalVariable(name: "arg2", arg: 3, scope: [[DBG28]], file: [[META8]], line: 43, type: [[META14]])
-// CHECK: [[META38]] = !{i64 0, !"_ZTSFvPFvu3i32S_ES_S_E.normalized"}
-// CHECK: [[META39]] = !{i64 0, !"_ZTSFvPvu3i32S0_E.normalized.generalized"}
-// CHECK: [[META40]] = !DILocation(line: 0, scope: [[DBG28]])
-// CHECK: [[DBG41]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[DBG42]])
-// CHECK: [[DBG42]] = !DILocation(line: 44, column: 5, scope: [[DBG28]])
-// CHECK: [[DBG43]] = !DILocation(line: 45, column: 1, scope: [[DBG28]])
-// CHECK: [[DBG44]] = distinct !DISubprogram(name: "baz", scope: [[META8]], file: [[META8]], line: 63, type: [[META45:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META50:![0-9]+]])
-// CHECK: [[META45]] = !DISubroutineType(types: [[META46:![0-9]+]])
-// CHECK: [[META46]] = !{null, [[META47:![0-9]+]], [[META14]], [[META14]], [[META14]]}
-// CHECK: [[META47]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META48:![0-9]+]], size: 64)
-// CHECK: [[META48]] = !DISubroutineType(types: [[META49:![0-9]+]])
-// CHECK: [[META49]] = !{null, [[META14]], [[META14]], [[META14]]}
-// CHECK: [[META50]] = !{[[META51]], [[META52]], [[META53]], [[META54]]}
-// CHECK: [[META51]] = !DILocalVariable(name: "fn", arg: 1, scope: [[DBG44]], file: [[META8]], line: 63, type: [[META47]])
-// CHECK: [[META52]] = !DILocalVariable(name: "arg1", arg: 2, scope: [[DBG44]], file: [[META8]], line: 63, type: [[META14]])
-// CHECK: [[META53]] = !DILocalVariable(name: "arg2", arg: 3, scope: [[DBG44]], file: [[META8]], line: 63, type: [[META14]])
-// CHECK: [[META54]] = !DILocalVariable(name: "arg3", arg: 4, scope: [[DBG44]], file: [[META8]], line: 63, type: [[META14]])
-// CHECK: [[META55]] = !{i64 0, !"_ZTSFvPFvu3i32S_S_ES_S_S_E.normalized"}
-// CHECK: [[META56]] = !{i64 0, !"_ZTSFvPvu3i32S0_S0_E.normalized.generalized"}
-// CHECK: [[META57]] = !DILocation(line: 0, scope: [[DBG44]])
-// CHECK: [[DBG58]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[DBG59]])
-// CHECK: [[DBG59]] = !DILocation(line: 64, column: 5, scope: [[DBG44]])
-// CHECK: [[DBG60]] = !DILocation(line: 65, column: 1, scope: [[DBG44]])
+// CHECK: [[META24]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[DBG25]])
+// CHECK: [[DBG25]] = !DILocation(line: 25, column: 5, scope: [[DBG7]])
+// CHECK: [[META26]] = !{}
+// CHECK: [[PROF27]] = !{!"branch_weights", i32 1048575, i32 1}
+// CHECK: [[DBG28]] = !DILocation(line: 26, column: 1, scope: [[DBG7]])
+// CHECK: [[DBG29]] = distinct !DISubprogram(name: "bar", scope: [[META8]], file: [[META8]], line: 43, type: [[META30:![0-9]+]], scopeLine: 43, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META35:![0-9]+]])
+// CHECK: [[META30]] = !DISubroutineType(types: [[META31:![0-9]+]])
+// CHECK: [[META31]] = !{null, [[META32:![0-9]+]], [[META14]], [[META14]]}
+// CHECK: [[META32]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META33:![0-9]+]], size: 64)
+// CHECK: [[META33]] = !DISubroutineType(types: [[META34:![0-9]+]])
+// CHECK: [[META34]] = !{null, [[META14]], [[META14]]}
+// CHECK: [[META35]] = !{[[META36]], [[META37]], [[META38]]}
+// CHECK: [[META36]] = !DILocalVariable(name: "fn", arg: 1, scope: [[DBG29]], file: [[META8]], line: 43, type: [[META32]])
+// CHECK: [[META37]] = !DILocalVariable(name: "arg1", arg: 2, scope: [[DBG29]], file: [[META8]], line: 43, type: [[META14]])
+// CHECK: [[META38]] = !DILocalVariable(name: "arg2", arg: 3, scope: [[DBG29]], file: [[META8]], line: 43, type: [[META14]])
+// CHECK: [[META39]] = !{i64 0, !"_ZTSFvPFvu3i32S_ES_S_E.normalized"}
+// CHECK: [[META40]] = !{i64 0, !"_ZTSFvPvu3i32S0_E.normalized.generalized"}
+// CHECK: [[META41]] = !DILocation(line: 0, scope: [[DBG29]])
+// CHECK: [[DBG42]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[META43:![0-9]+]])
+// CHECK: [[META43]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[DBG44]])
+// CHECK: [[DBG44]] = !DILocation(line: 44, column: 5, scope: [[DBG29]])
+// CHECK: [[DBG45]] = !DILocation(line: 45, column: 1, scope: [[DBG29]])
+// CHECK: [[DBG46]] = distinct !DISubprogram(name: "baz", scope: [[META8]], file: [[META8]], line: 63, type: [[META47:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META52:![0-9]+]])
+// CHECK: [[META47]] = !DISubroutineType(types: [[META48:![0-9]+]])
+// CHECK: [[META48]] = !{null, [[META49:![0-9]+]], [[META14]], [[META14]], [[META14]]}
+// CHECK: [[META49]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META50:![0-9]+]], size: 64)
+// CHECK: [[META50]] = !DISubroutineType(types: [[META51:![0-9]+]])
+// CHECK: [[META51]] = !{null, [[META14]], [[META14]], [[META14]]}
+// CHECK: [[META52]] = !{[[META53]], [[META54]], [[META55]], [[META56]]}
+// CHECK: [[META53]] = !DILocalVariable(name: "fn", arg: 1, scope: [[DBG46]], file: [[META8]], line: 63, type: [[META49]])
+// CHECK: [[META54]] = !DILocalVariable(name: "arg1", arg: 2, scope: [[DBG46]], file: [[META8]], line: 63, type: [[META14]])
+// CHECK: [[META55]] = !DILocalVariable(name: "arg2", arg: 3, scope: [[DBG46]], file: [[META8]], line: 63, type: [[META14]])
+// CHECK: [[META56]] = !DILocalVariable(name: "arg3", arg: 4, scope: [[DBG46]], file: [[META8]], line: 63, type: [[META14]])
+// CHECK: [[META57]] = !{i64 0, !"_ZTSFvPFvu3i32S_S_ES_S_S_E.normalized"}
+// CHECK: [[META58]] = !{i64 0, !"_ZTSFvPvu3i32S0_S0_E.normalized.generalized"}
+// CHECK: [[META59]] = !DILocation(line: 0, scope: [[DBG46]])
+// CHECK: [[DBG60]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[META61:![0-9]+]])
+// CHECK: [[META61]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[DBG62]])
+// CHECK: [[DBG62]] = !DILocation(line: 64, column: 5, scope: [[DBG46]])
+// CHECK: [[DBG63]] = !DILocation(line: 65, column: 1, scope: [[DBG46]])
 //.
diff --git a/clang/test/CodeGen/ubsan-function-debuginfo.c b/clang/test/CodeGen/ubsan-function-debuginfo.c
index 21cc7e41e1a37..5bf490d498bb3 100644
--- a/clang/test/CodeGen/ubsan-function-debuginfo.c
+++ b/clang/test/CodeGen/ubsan-function-debuginfo.c
@@ -18,26 +18,26 @@ void call_no_prototype(void (*f)()) { f(); }
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:      #dbg_value(ptr [[F]], [[META25:![0-9]+]], !DIExpression(), [[META27:![0-9]+]])
 // CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i8, ptr [[F]], i64 -8, !dbg [[DBG28:![0-9]+]]
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4, !dbg [[DBG28]], !nosanitize [[META29:![0-9]+]]
-// CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -1056584962, !dbg [[DBG28]], !nosanitize [[META29]]
-// CHECK-NEXT:    br i1 [[TMP2]], label %[[TYPECHECK:.*]], label %[[CONT1:.*]], !dbg [[DBG28]], !nosanitize [[META29]]
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4, !dbg [[DBG28]], !nosanitize [[META32:![0-9]+]]
+// CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -1056584962, !dbg [[DBG28]], !nosanitize [[META32]]
+// CHECK-NEXT:    br i1 [[TMP2]], label %[[TYPECHECK:.*]], label %[[CONT1:.*]], !dbg [[DBG28]], !nosanitize [[META32]]
 // CHECK:       [[TYPECHECK]]:
 // CHECK-NEXT:    [[TMP3:%.*]] = getelementptr i8, ptr [[F]], i64 -4, !dbg [[DBG28]]
-// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 8, !dbg [[DBG28]], !nosanitize [[META29]]
-// CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 905068220, !dbg [[DBG28]], !nosanitize [[META29]]
-// CHECK-NEXT:    br i1 [[TMP5]], label %[[CONT1]], label %[[HANDLER_FUNCTION_TYPE_MISMATCH:.*]], !dbg [[DBG28]], !prof [[PROF30:![0-9]+]], !nosanitize [[META29]]
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 8, !dbg [[DBG28]], !nosanitize [[META32]]
+// CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 905068220, !dbg [[DBG28]], !nosanitize [[META32]]
+// CHECK-NEXT:    br i1 [[TMP5]], label %[[CONT1]], label %[[HANDLER_FUNCTION_TYPE_MISMATCH:.*]], !dbg [[DBG28]], !prof [[PROF33:![0-9]+]], !nosanitize [[META32]]
 // CHECK:       [[HANDLER_FUNCTION_TYPE_MISMATCH]]:
-// CHECK-NEXT:    [[TMP6:%.*]] = ptrtoint ptr [[F]] to i64, !dbg [[DBG28]], !nosanitize [[META29]]
-// CHECK-NEXT:    tail call void @__ubsan_handle_function_type_mismatch_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP6]]) #[[ATTR3:[0-9]+]], !dbg [[DBG28]], !nosanitize [[META29]]
-// CHECK-NEXT:    unreachable, !dbg [[DBG28]], !nosanitize [[META29]]
+// CHECK-NEXT:    [[TMP6:%.*]] = ptrtoint ptr [[F]] to i64, !dbg [[DBG28]], !nosanitize [[META32]]
+// CHECK-NEXT:    tail call void @__ubsan_handle_function_type_mismatch_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP6]]) #[[ATTR3:[0-9]+]], !dbg [[DBG28]], !nosanitize [[META32]]
+// CHECK-NEXT:    unreachable, !dbg [[DBG28]], !nosanitize [[META32]]
 // CHECK:       [[CONT1]]:
-// CHECK-NEXT:    tail call void [[F]]() #[[ATTR2]], !dbg [[DBG28]]
-// CHECK-NEXT:    ret void, !dbg [[DBG31:![0-9]+]]
+// CHECK-NEXT:    tail call void [[F]]() #[[ATTR2]], !dbg [[DBG31:![0-9]+]]
+// CHECK-NEXT:    ret void, !dbg [[DBG34:![0-9]+]]
 //
 void call_prototype(void (*f)(void)) { f(); }
 //.
 // CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// CHECK: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // CHECK: [[DBG5]] = distinct !DISubprogram(name: "call_no_prototype", scope: [[META6:![0-9]+]], file: [[META6]], line: 14, type: [[META7:![0-9]+]], scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META12:![0-9]+]])
 // CHECK: [[META6]] = !DIFile(filename: "{{.*}}ubsan-function-debuginfo.c", directory: {{.*}})
 // CHECK: [[META7]] = !DISubroutineType(types: [[META8:![0-9]+]])
@@ -61,8 +61,11 @@ void call_prototype(void (*f)(void)) { f(); }
 // CHECK: [[META25]] = !DILocalVariable(name: "f", arg: 1, scope: [[DBG18]], file: [[META6]], line: 37, type: [[META21]])
 // CHECK: [[META26]] = !{i32 -1056584962, i32 -747727454}
 // CHECK: [[META27]] = !DILocation(line: 0, scope: [[DBG18]])
-// CHECK: [[DBG28]] = !DILocation(line: 37, column: 40, scope: [[DBG18]])
-// CHECK: [[META29]] = !{}
-// CHECK: [[PROF30]] = !{!"branch_weights", i32 1048575, i32 1}
-// CHECK: [[DBG31]] = !DILocation(line: 37, column: 45, scope: [[DBG18]])
+// CHECK: [[DBG28]] = !DILocation(line: 0, scope: [[META29:![0-9]+]], inlinedAt: [[DBG31]])
+// CHECK: [[META29]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META6]], file: [[META6]], type: [[META30:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[META30]] = !DISubroutineType(types: null)
+// CHECK: [[DBG31]] = !DILocation(line: 37, column: 40, scope: [[DBG18]])
+// CHECK: [[META32]] = !{}
+// CHECK: [[PROF33]] = !{!"branch_weights", i32 1048575, i32 1}
+// CHECK: [[DBG34]] = !DILocation(line: 37, column: 45, scope: [[DBG18]])
 //.
diff --git a/clang/test/CodeGen/unsigned-promotion-debuginfo.c b/clang/test/CodeGen/unsigned-promotion-debuginfo.c
index 163f306f60a1f..6b758096aee77 100644
--- a/clang/test/CodeGen/unsigned-promotion-debuginfo.c
+++ b/clang/test/CodeGen/unsigned-promotion-debuginfo.c
@@ -18,19 +18,19 @@ unsigned short si, sj, sk;
 // CHECKS-NEXT:    [[CONV:%.*]] = zext i16 [[TMP0]] to i32, !dbg [[DBG16]]
 // CHECKS-NEXT:    [[TMP1:%.*]] = load i16, ptr @sk, align 2, !dbg [[DBG21:![0-9]+]], !tbaa [[TBAA17]]
 // CHECKS-NEXT:    [[CONV1:%.*]] = zext i16 [[TMP1]] to i32, !dbg [[DBG21]]
-// CHECKS-NEXT:    [[TMP2:%.*]] = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[CONV]], i32 [[CONV1]]), !dbg [[DBG22:![0-9]+]], !nosanitize [[META23:![0-9]+]]
-// CHECKS-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !dbg [[DBG22]], !nosanitize [[META23]]
-// CHECKS-NEXT:    br i1 [[TMP3]], label %[[HANDLER_MUL_OVERFLOW:.*]], label %[[CONT:.*]], !dbg [[DBG22]], !prof [[PROF24:![0-9]+]], !nosanitize [[META23]]
+// CHECKS-NEXT:    [[TMP2:%.*]] = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[CONV]], i32 [[CONV1]]), !dbg [[DBG22:![0-9]+]], !nosanitize [[META26:![0-9]+]]
+// CHECKS-NEXT:    [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !dbg [[DBG22]], !nosanitize [[META26]]
+// CHECKS-NEXT:    br i1 [[TMP3]], label %[[HANDLER_MUL_OVERFLOW:.*]], label %[[CONT:.*]], !dbg [[DBG22]], !prof [[PROF27:![0-9]+]], !nosanitize [[META26]]
 // CHECKS:       [[HANDLER_MUL_OVERFLOW]]:
 // CHECKS-NEXT:    [[TMP4:%.*]] = zext i16 [[TMP0]] to i64, !dbg [[DBG22]]
 // CHECKS-NEXT:    [[TMP5:%.*]] = zext i16 [[TMP1]] to i64, !dbg [[DBG22]]
-// CHECKS-NEXT:    tail call void @__ubsan_handle_mul_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !dbg [[DBG22]], !nosanitize [[META23]]
-// CHECKS-NEXT:    unreachable, !dbg [[DBG22]], !nosanitize [[META23]]
+// CHECKS-NEXT:    tail call void @__ubsan_handle_mul_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !dbg [[DBG22]], !nosanitize [[META26]]
+// CHECKS-NEXT:    unreachable, !dbg [[DBG22]], !nosanitize [[META26]]
 // CHECKS:       [[CONT]]:
-// CHECKS-NEXT:    [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !dbg [[DBG22]], !nosanitize [[META23]]
+// CHECKS-NEXT:    [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !dbg [[DBG22]], !nosanitize [[META26]]
 // CHECKS-NEXT:    [[CONV2:%.*]] = trunc i32 [[TMP6]] to i16, !dbg [[DBG16]]
-// CHECKS-NEXT:    store i16 [[CONV2]], ptr @si, align 2, !dbg [[DBG25:![0-9]+]], !tbaa [[TBAA17]]
-// CHECKS-NEXT:    ret void, !dbg [[DBG26:![0-9]+]]
+// CHECKS-NEXT:    store i16 [[CONV2]], ptr @si, align 2, !dbg [[DBG28:![0-9]+]], !tbaa [[TBAA17]]
+// CHECKS-NEXT:    ret void, !dbg [[DBG29:![0-9]+]]
 //
 // CHECKU-LABEL: define dso_local void @testshortmul(
 // CHECKU-SAME: ) local_unnamed_addr #[[ATTR0:[0-9]+]] !dbg [[DBG13:![0-9]+]] {
@@ -50,7 +50,7 @@ void testshortmul(void) {
 // CHECKS: [[META0:![0-9]+]] = !DIGlobalVariableExpression(var: [[META1:![0-9]+]], expr: !DIExpression())
 // CHECKS: [[META1]] = distinct !DIGlobalVariable(name: "sj", scope: [[META2:![0-9]+]], file: [[META7:![0-9]+]], line: 12, type: [[META8:![0-9]+]], isLocal: false, isDefinition: true)
 // CHECKS: [[META2]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META3:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: [[META4:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
-// CHECKS: [[META3]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// CHECKS: [[META3]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // CHECKS: [[META4]] = !{[[META5:![0-9]+]], [[META0]], [[META9:![0-9]+]]}
 // CHECKS: [[META5]] = !DIGlobalVariableExpression(var: [[META6:![0-9]+]], expr: !DIExpression())
 // CHECKS: [[META6]] = distinct !DIGlobalVariable(name: "si", scope: [[META2]], file: [[META7]], line: 12, type: [[META8]], isLocal: false, isDefinition: true)
@@ -67,16 +67,19 @@ void testshortmul(void) {
 // CHECKS: [[META19]] = !{!"omnipotent char", [[META20:![0-9]+]], i64 0}
 // CHECKS: [[META20]] = !{!"Simple C/C++ TBAA"}
 // CHECKS: [[DBG21]] = !DILocation(line: 47, column: 13, scope: [[DBG13]])
-// CHECKS: [[DBG22]] = !DILocation(line: 47, column: 11, scope: [[DBG13]])
-// CHECKS: [[META23]] = !{}
-// CHECKS: [[PROF24]] = !{!"branch_weights", i32 1, i32 1048575}
-// CHECKS: [[DBG25]] = !DILocation(line: 47, column: 6, scope: [[DBG13]])
-// CHECKS: [[DBG26]] = !DILocation(line: 48, column: 1, scope: [[DBG13]])
+// CHECKS: [[DBG22]] = !DILocation(line: 0, scope: [[META23:![0-9]+]], inlinedAt: [[META25:![0-9]+]])
+// CHECKS: [[META23]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META7]], file: [[META7]], type: [[META24:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META2]])
+// CHECKS: [[META24]] = !DISubroutineType(types: null)
+// CHECKS: [[META25]] = !DILocation(line: 47, column: 11, scope: [[DBG13]])
+// CHECKS: [[META26]] = !{}
+// CHECKS: [[PROF27]] = !{!"branch_weights", i32 1, i32 1048575}
+// CHECKS: [[DBG28]] = !DILocation(line: 47, column: 6, scope: [[DBG13]])
+// CHECKS: [[DBG29]] = !DILocation(line: 48, column: 1, scope: [[DBG13]])
 //.
 // CHECKU: [[META0:![0-9]+]] = !DIGlobalVariableExpression(var: [[META1:![0-9]+]], expr: !DIExpression())
 // CHECKU: [[META1]] = distinct !DIGlobalVariable(name: "sj", scope: [[META2:![0-9]+]], file: [[META7:![0-9]+]], line: 12, type: [[META8:![0-9]+]], isLocal: false, isDefinition: true)
 // CHECKU: [[META2]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META3:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: [[META4:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
-// CHECKU: [[META3]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// CHECKU: [[META3]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // CHECKU: [[META4]] = !{[[META5:![0-9]+]], [[META0]], [[META9:![0-9]+]]}
 // CHECKU: [[META5]] = !DIGlobalVariableExpression(var: [[META6:![0-9]+]], expr: !DIExpression())
 // CHECKU: [[META6]] = distinct !DIGlobalVariable(name: "si", scope: [[META2]], file: [[META7]], line: 12, type: [[META8]], isLocal: false, isDefinition: true)

>From 41735cb9e35427b185be06239d07812d980692b4 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Thu, 29 May 2025 16:30:39 +0000
Subject: [PATCH 02/26] Refactor to use explicit CheckOrdinal variable

---
 clang/lib/CodeGen/CGBuiltin.cpp       | 17 +++++++++--------
 clang/lib/CodeGen/CGClass.cpp         |  5 +++--
 clang/lib/CodeGen/CGDecl.cpp          |  7 ++++---
 clang/lib/CodeGen/CGExprScalar.cpp    | 10 ++++++----
 clang/lib/CodeGen/CGObjC.cpp          |  6 +++---
 clang/lib/CodeGen/CodeGenFunction.cpp | 18 ++++++++++--------
 clang/lib/CodeGen/ItaniumCXXABI.cpp   | 12 ++++++------
 7 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 94cb399ab23d4..893ea8d0ff318 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2006,10 +2006,11 @@ Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
   if (!SanOpts.has(SanitizerKind::Builtin))
     return ArgValue;
 
-  SanitizerScope SanScope(this, {SanitizerKind::SO_Builtin});
+  auto CheckOrdinal = SanitizerKind::SO_Builtin;
+  SanitizerScope SanScope(this, {CheckOrdinal});
   Value *Cond = Builder.CreateICmpNE(
       ArgValue, llvm::Constant::getNullValue(ArgValue->getType()));
-  EmitCheck(std::make_pair(Cond, SanitizerKind::SO_Builtin),
+  EmitCheck(std::make_pair(Cond, CheckOrdinal),
             SanitizerHandler::InvalidBuiltin,
             {EmitCheckSourceLocation(E->getExprLoc()),
              llvm::ConstantInt::get(Builder.getInt8Ty(), Kind)},
@@ -2022,10 +2023,10 @@ Value *CodeGenFunction::EmitCheckedArgForAssume(const Expr *E) {
   if (!SanOpts.has(SanitizerKind::Builtin))
     return ArgValue;
 
-  SanitizerScope SanScope(this, {SanitizerKind::SO_Builtin});
+  auto CheckOrdinal = SanitizerKind::SO_Builtin;
+  SanitizerScope SanScope(this, {CheckOrdinal});
   EmitCheck(
-      std::make_pair(ArgValue, SanitizerKind::SO_Builtin),
-      SanitizerHandler::InvalidBuiltin,
+      std::make_pair(ArgValue, CheckOrdinal), SanitizerHandler::InvalidBuiltin,
       {EmitCheckSourceLocation(E->getExprLoc()),
        llvm::ConstantInt::get(Builder.getInt8Ty(), BCK_AssumePassedFalse)},
       std::nullopt);
@@ -2048,10 +2049,10 @@ static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E,
       return EmitAbs(CGF, ArgValue, true);
   }
 
-  SmallVector<SanitizerKind::SanitizerOrdinal, 3> Kinds;
+  SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
   if (SanitizeOverflow)
-    Kinds.push_back(SanitizerKind::SO_SignedIntegerOverflow);
-  CodeGenFunction::SanitizerScope SanScope(&CGF, Kinds);
+    Ordinals.push_back(SanitizerKind::SO_SignedIntegerOverflow);
+  CodeGenFunction::SanitizerScope SanScope(&CGF, Ordinals);
 
   Constant *Zero = Constant::getNullValue(ArgValue->getType());
   Value *ResultAndOverflow = CGF.Builder.CreateBinaryIntrinsic(
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 5b3d105d3444e..70f885de05cf9 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2942,7 +2942,8 @@ bool CodeGenFunction::ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD) {
 llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
     const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy,
     uint64_t VTableByteOffset) {
-  SanitizerScope SanScope(this, {SanitizerKind::SO_CFIVCall});
+  auto CheckOrdinal = SanitizerKind::SO_CFIVCall;
+  SanitizerScope SanScope(this, {CheckOrdinal});
 
   EmitSanitizerStatReport(llvm::SanStat_CFI_VCall);
 
@@ -2963,7 +2964,7 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
   if (SanOpts.has(SanitizerKind::CFIVCall) &&
       !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
                                                      TypeName)) {
-    EmitCheck(std::make_pair(CheckResult, SanitizerKind::SO_CFIVCall),
+    EmitCheck(std::make_pair(CheckResult, CheckOrdinal),
               SanitizerHandler::CFICheckFail, {}, {});
   }
 
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 52f7919f529f3..139cc567f101b 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -765,14 +765,15 @@ void CodeGenFunction::EmitNullabilityCheck(LValue LHS, llvm::Value *RHS,
 
   // Check if the right hand side of the assignment is nonnull, if the left
   // hand side must be nonnull.
-  SanitizerScope SanScope(this, {SanitizerKind::SO_NullabilityAssign});
+  auto CheckOrdinal = SanitizerKind::SO_NullabilityAssign;
+  SanitizerScope SanScope(this, {CheckOrdinal});
   llvm::Value *IsNotNull = Builder.CreateIsNotNull(RHS);
   llvm::Constant *StaticData[] = {
       EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(LHS.getType()),
       llvm::ConstantInt::get(Int8Ty, 0), // The LogAlignment info is unused.
       llvm::ConstantInt::get(Int8Ty, TCK_NonnullAssign)};
-  EmitCheck({{IsNotNull, SanitizerKind::SO_NullabilityAssign}},
-            SanitizerHandler::TypeMismatch, StaticData, RHS);
+  EmitCheck({{IsNotNull, CheckOrdinal}}, SanitizerHandler::TypeMismatch,
+            StaticData, RHS);
 }
 
 void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index d449a2b30eef5..43ac70bd81b7c 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -999,8 +999,8 @@ void ScalarExprEmitter::EmitFloatConversionCheck(
   if (!isa<llvm::IntegerType>(DstTy))
     return;
 
-  CodeGenFunction::SanitizerScope SanScope(
-      &CGF, {SanitizerKind::SO_FloatCastOverflow});
+  auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
+  CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal});
   using llvm::APFloat;
   using llvm::APSInt;
 
@@ -1057,7 +1057,7 @@ void ScalarExprEmitter::EmitFloatConversionCheck(
   llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc),
                                   CGF.EmitCheckTypeDescriptor(OrigSrcType),
                                   CGF.EmitCheckTypeDescriptor(DstType)};
-  CGF.EmitCheck(std::make_pair(Check, SanitizerKind::SO_FloatCastOverflow),
+  CGF.EmitCheck(std::make_pair(Check, CheckOrdinal),
                 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
 }
 
@@ -1140,7 +1140,9 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
       Check;
 
   {
-    // We don't know the check kind yet
+    // We don't know the check kind until we call
+    // EmitIntegerTruncationCheckHelper, but we want to annotate
+    // EmitIntegerTruncationCheckHelper's instructions too.
     CodeGenFunction::SanitizerScope SanScope(
         &CGF, {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
                SanitizerKind::SO_ImplicitSignedIntegerTruncation});
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 950313539fa96..1c85d02479fe0 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1967,7 +1967,8 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
     const ObjCInterfaceType *InterfaceTy =
         ObjPtrTy ? ObjPtrTy->getInterfaceType() : nullptr;
     if (InterfaceTy) {
-      SanitizerScope SanScope(this, {SanitizerKind::SO_ObjCCast});
+      auto CheckOrdinal = SanitizerKind::SO_ObjCCast;
+      SanitizerScope SanScope(this, {CheckOrdinal});
       auto &C = CGM.getContext();
       assert(InterfaceTy->getDecl() && "No decl for ObjC interface type");
       Selector IsKindOfClassSel = GetUnarySelector("isKindOfClass", C);
@@ -1984,8 +1985,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
       llvm::Constant *StaticData[] = {
           EmitCheckSourceLocation(S.getBeginLoc()),
           EmitCheckTypeDescriptor(QualType(InterfaceTy, 0))};
-      EmitCheck({{IsClass, SanitizerKind::SO_ObjCCast}},
-                SanitizerHandler::InvalidObjCCast,
+      EmitCheck({{IsClass, CheckOrdinal}}, SanitizerHandler::InvalidObjCCast,
                 ArrayRef<llvm::Constant *>(StaticData), CurrentItem);
     }
   }
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 0fe1a8fc76ef6..acb9d345a80db 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1632,9 +1632,10 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
         CGM.getCodeGenOpts().StrictReturn ||
         !CGM.MayDropFunctionReturn(FD->getASTContext(), FD->getReturnType());
     if (SanOpts.has(SanitizerKind::Return)) {
-      SanitizerScope SanScope(this, {SanitizerKind::SO_Return});
+      auto CheckOrdinal = SanitizerKind::SO_Return;
+      SanitizerScope SanScope(this, {CheckOrdinal});
       llvm::Value *IsFalse = Builder.getFalse();
-      EmitCheck(std::make_pair(IsFalse, SanitizerKind::SO_Return),
+      EmitCheck(std::make_pair(IsFalse, CheckOrdinal),
                 SanitizerHandler::MissingReturn,
                 EmitCheckSourceLocation(FD->getLocation()), {});
     } else if (ShouldEmitUnreachable) {
@@ -2537,7 +2538,8 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
           //   expression [...] each time it is evaluated it shall have a value
           //   greater than zero.
           if (SanOpts.has(SanitizerKind::VLABound)) {
-            SanitizerScope SanScope(this, {SanitizerKind::SO_VLABound});
+            auto CheckOrdinal = SanitizerKind::SO_VLABound;
+            SanitizerScope SanScope(this, {CheckOrdinal});
             llvm::Value *Zero = llvm::Constant::getNullValue(size->getType());
             clang::QualType SEType = sizeExpr->getType();
             llvm::Value *CheckCondition =
@@ -2547,9 +2549,8 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
             llvm::Constant *StaticArgs[] = {
                 EmitCheckSourceLocation(sizeExpr->getBeginLoc()),
                 EmitCheckTypeDescriptor(SEType)};
-            EmitCheck(
-                std::make_pair(CheckCondition, SanitizerKind::SO_VLABound),
-                SanitizerHandler::VLABoundNotPositive, StaticArgs, size);
+            EmitCheck(std::make_pair(CheckCondition, CheckOrdinal),
+                      SanitizerHandler::VLABoundNotPositive, StaticArgs, size);
           }
 
           // Always zexting here would be wrong if it weren't
@@ -3198,7 +3199,8 @@ void CodeGenFunction::emitAlignmentAssumptionCheck(
   Assumption->removeFromParent();
 
   {
-    SanitizerScope SanScope(this, {SanitizerKind::SO_Alignment});
+    auto CheckOrdinal = SanitizerKind::SO_Alignment;
+    SanitizerScope SanScope(this, {CheckOrdinal});
 
     if (!OffsetValue)
       OffsetValue = Builder.getInt1(false); // no offset.
@@ -3207,7 +3209,7 @@ void CodeGenFunction::emitAlignmentAssumptionCheck(
                                     EmitCheckSourceLocation(SecondaryLoc),
                                     EmitCheckTypeDescriptor(Ty)};
     llvm::Value *DynamicData[] = {Ptr, Alignment, OffsetValue};
-    EmitCheck({std::make_pair(TheCheck, SanitizerKind::SO_Alignment)},
+    EmitCheck({std::make_pair(TheCheck, CheckOrdinal)},
               SanitizerHandler::AlignmentAssumption, StaticData, DynamicData);
   }
 
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index e68e8acc60190..32e2b0ae0b723 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -702,8 +702,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
   llvm::Value *VirtualFn = nullptr;
 
   {
-    CodeGenFunction::SanitizerScope SanScope(&CGF,
-                                             {SanitizerKind::SO_CFIMFCall});
+    auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
+    CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal});
 
     llvm::Value *TypeId = nullptr;
     llvm::Value *CheckResult = nullptr;
@@ -780,7 +780,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
             llvm::MDString::get(CGM.getLLVMContext(), "all-vtables"));
         llvm::Value *ValidVtable = Builder.CreateCall(
             CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
-        CGF.EmitCheck(std::make_pair(CheckResult, SanitizerKind::SO_CFIMFCall),
+        CGF.EmitCheck(std::make_pair(CheckResult, CheckOrdinal),
                       SanitizerHandler::CFICheckFail, StaticData,
                       {VTable, ValidVtable});
       }
@@ -801,8 +801,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
   if (ShouldEmitCFICheck) {
     CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
     if (RD->hasDefinition()) {
-      CodeGenFunction::SanitizerScope SanScope(&CGF,
-                                               {SanitizerKind::SO_CFIMFCall});
+      auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
+      CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal});
 
       llvm::Constant *StaticData[] = {
           llvm::ConstantInt::get(CGF.Int8Ty, CodeGenFunction::CFITCK_NVMFCall),
@@ -825,7 +825,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
         Bit = Builder.CreateOr(Bit, TypeTest);
       }
 
-      CGF.EmitCheck(std::make_pair(Bit, SanitizerKind::SO_CFIMFCall),
+      CGF.EmitCheck(std::make_pair(Bit, CheckOrdinal),
                     SanitizerHandler::CFICheckFail, StaticData,
                     {NonVirtualFn, llvm::UndefValue::get(CGF.IntPtrTy)});
 

>From 3e534622f01def6aecb43c5d525dd2a040718c4f Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Thu, 29 May 2025 16:49:16 +0000
Subject: [PATCH 03/26] Mention why void* is used instead of
 ApplyDebugLocation*

---
 clang/lib/CodeGen/CodeGenFunction.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index dbfebdfbb8df1..cb730167d8f56 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -596,6 +596,9 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// RAII object to set/unset CodeGenFunction::IsSanitizerScope.
   class SanitizerScope {
     CodeGenFunction *CGF;
+
+    // ApplyDebugLocation is undeclared: CGDebugInfo.h is not #included in this
+    // header due to overhead (b384d6d6ccc8f4452cd7086061c657ce76b41224)
     void *ApplyTrapDI;
 
   public:

>From fbadcee10bf56cfda1aaada55f31132a68c899e4 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Thu, 29 May 2025 16:56:19 +0000
Subject: [PATCH 04/26] !ApplyTrapDI assertion

---
 clang/lib/CodeGen/CodeGenFunction.cpp | 2 ++
 clang/lib/CodeGen/CodeGenFunction.h   | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index acb9d345a80db..a661bd51cab08 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2759,6 +2759,7 @@ CodeGenFunction::SanitizerScope::SanitizerScope(
   assert(!CGF->IsSanitizerScope);
   CGF->IsSanitizerScope = true;
 
+  assert(!this->ApplyTrapDI);
   this->ApplyTrapDI =
       new ApplyDebugLocation(*CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals));
 }
@@ -2767,6 +2768,7 @@ CodeGenFunction::SanitizerScope::~SanitizerScope() {
   CGF->IsSanitizerScope = false;
 
   delete ((ApplyDebugLocation *)this->ApplyTrapDI);
+  this->ApplyTrapDI = nullptr;
 }
 
 void CodeGenFunction::InsertHelper(llvm::Instruction *I,
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index cb730167d8f56..c6c9bce596e17 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -599,7 +599,7 @@ class CodeGenFunction : public CodeGenTypeCache {
 
     // ApplyDebugLocation is undeclared: CGDebugInfo.h is not #included in this
     // header due to overhead (b384d6d6ccc8f4452cd7086061c657ce76b41224)
-    void *ApplyTrapDI;
+    void *ApplyTrapDI = nullptr;
 
   public:
     SanitizerScope(CodeGenFunction *CGF,

>From 6f82a484bf63518a2fd4d81d5ef9c7aa85c42666 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Thu, 29 May 2025 17:18:26 +0000
Subject: [PATCH 05/26] Cleanup

---
 clang/lib/CodeGen/CGBuiltin.cpp |  2 +-
 clang/lib/CodeGen/CGExpr.cpp    | 25 ++++++++++++++-----------
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 893ea8d0ff318..b858770155472 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2049,7 +2049,7 @@ static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E,
       return EmitAbs(CGF, ArgValue, true);
   }
 
-  SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
+  SmallVector<SanitizerKind::SanitizerOrdinal, 1> Ordinals;
   if (SanitizeOverflow)
     Ordinals.push_back(SanitizerKind::SO_SignedIntegerOverflow);
   CodeGenFunction::SanitizerScope SanScope(&CGF, Ordinals);
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 69e1e2060a61f..514989404ed11 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1249,9 +1249,11 @@ llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
   llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
 
   // TODO: the annotation could be more precise:
-  // 1) use the ordinal name if there is only one ordinal
+  // 1) use the ordinal name if there is only one ordinal; and/or,
   // 2) use the overarching SanitizerHandler if there are multiple ordinals
+  //    (this may be confusing to users)
   for (auto Ord : Ordinals) {
+    // TODO: deprecate ClArrayBoundsPseudoFn
     if (((ClArrayBoundsPseudoFn && Ord == SanitizerKind::SO_ArrayBounds) ||
          CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo.has(Ord)) &&
         CheckDI) {
@@ -4029,9 +4031,10 @@ void CodeGenFunction::EmitCfiCheckFail() {
 
 void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
   if (SanOpts.has(SanitizerKind::Unreachable)) {
-    SanitizerScope SanScope(this, {SanitizerKind::SO_Unreachable});
+    auto CheckOrdinal = SanitizerKind::SO_Unreachable;
+    SanitizerScope SanScope(this, {CheckOrdinal});
     EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
-                             SanitizerKind::SO_Unreachable),
+                             CheckOrdinal),
               SanitizerHandler::BuiltinUnreachable,
               EmitCheckSourceLocation(Loc), {});
   }
@@ -6270,7 +6273,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
       !isa<FunctionNoProtoType>(PointeeType)) {
     if (llvm::Constant *PrefixSig =
             CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
-      SanitizerScope SanScope(this, {SanitizerKind::SO_Function});
+      auto CheckOrdinal = SanitizerKind::SO_Function;
+      SanitizerScope SanScope(this, {CheckOrdinal});
       auto *TypeHash = getUBSanFunctionTypeHash(PointeeType);
 
       llvm::Type *PrefixSigType = PrefixSig->getType();
@@ -6330,7 +6334,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
           Builder.CreateICmpEQ(CalleeTypeHash, TypeHash);
       llvm::Constant *StaticData[] = {EmitCheckSourceLocation(E->getBeginLoc()),
                                       EmitCheckTypeDescriptor(CalleeType)};
-      EmitCheck(std::make_pair(CalleeTypeHashMatch, SanitizerKind::SO_Function),
+      EmitCheck(std::make_pair(CalleeTypeHashMatch, CheckOrdinal),
                 SanitizerHandler::FunctionTypeMismatch, StaticData,
                 {CalleePtr});
 
@@ -6349,10 +6353,9 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
   // function pointer is a member of the bit set for the function type.
   if (SanOpts.has(SanitizerKind::CFIICall) &&
       (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
-    SanitizerScope SanScope(this, {SanitizerKind::SO_CFIICall});
+    auto CheckOrdinal = SanitizerKind::SO_CFIICall;
+    SanitizerScope SanScope(this, {CheckOrdinal});
     EmitSanitizerStatReport(llvm::SanStat_CFI_ICall);
-    ApplyDebugLocation ApplyTrapDI(
-        *this, SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIICall));
 
     llvm::Metadata *MD;
     if (CGM.getCodeGenOpts().SanitizeCfiICallGeneralizePointers)
@@ -6373,10 +6376,10 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
         EmitCheckTypeDescriptor(QualType(FnType, 0)),
     };
     if (CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
-      EmitCfiSlowPathCheck(SanitizerKind::SO_CFIICall, TypeTest, CrossDsoTypeId,
-                           CalleePtr, StaticData);
+      EmitCfiSlowPathCheck(CheckOrdinal, TypeTest, CrossDsoTypeId, CalleePtr,
+                           StaticData);
     } else {
-      EmitCheck(std::make_pair(TypeTest, SanitizerKind::SO_CFIICall),
+      EmitCheck(std::make_pair(TypeTest, CheckOrdinal),
                 SanitizerHandler::CFICheckFail, StaticData,
                 {CalleePtr, llvm::UndefValue::get(IntPtrTy)});
     }

>From 58d76a62dcefc27d67c7020b895520082d77a4b6 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Thu, 29 May 2025 17:28:15 +0000
Subject: [PATCH 06/26] ApplyTrapDI and stdin cleanup

---
 clang/lib/CodeGen/CGExpr.cpp                  |   5 +-
 .../test/CodeGen/bounds-checking-debuginfo.c  |   4 +-
 clang/test/CodeGen/cfi-check-fail-debuginfo.c |  25 ++--
 .../CodeGen/cfi-icall-generalize-debuginfo.c  |  50 ++++---
 .../CodeGen/cfi-icall-normalize2-debuginfo.c  | 135 +++++++++---------
 clang/test/CodeGen/ubsan-function-debuginfo.c |   2 +-
 .../CodeGen/unsigned-promotion-debuginfo.c    |   4 +-
 7 files changed, 109 insertions(+), 116 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 514989404ed11..5bd782215b1b4 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3995,8 +3995,6 @@ void CodeGenFunction::EmitCfiCheckFail() {
                          {Addr, AllVtables}),
       IntPtrTy);
 
-  // TODO: the instructions above are not annotated with debug info. It is
-  // inconvenient to do so because we have not determined SanitizerKind yet.
   const std::pair<int, SanitizerKind::SanitizerOrdinal> CheckKinds[] = {
       {CFITCK_VCall, SanitizerKind::SO_CFIVCall},
       {CFITCK_NVCall, SanitizerKind::SO_CFINVCall},
@@ -4008,7 +4006,8 @@ void CodeGenFunction::EmitCfiCheckFail() {
     int Kind = CheckKindOrdinalPair.first;
     SanitizerKind::SanitizerOrdinal Ordinal = CheckKindOrdinalPair.second;
 
-    ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(Ordinal));
+    // TODO: we could apply SanitizerAnnotateDebugInfo(Ordinal) instead of
+    //       relying on the SanitizerScope with all CFI ordinals
 
     llvm::Value *Cond =
         Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(Int8Ty, Kind));
diff --git a/clang/test/CodeGen/bounds-checking-debuginfo.c b/clang/test/CodeGen/bounds-checking-debuginfo.c
index a6a1b16acb8e7..4c0eb5a8559c4 100644
--- a/clang/test/CodeGen/bounds-checking-debuginfo.c
+++ b/clang/test/CodeGen/bounds-checking-debuginfo.c
@@ -68,7 +68,7 @@ double f1(int b, int i) {
 
 //.
 // CHECK-TRAP: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK-TRAP: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
+// CHECK-TRAP: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
 // CHECK-TRAP: [[DBG4]] = distinct !DISubprogram(name: "f1", scope: [[META5:![0-9]+]], file: [[META5]], line: 63, type: [[META6:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]], retainedNodes: [[META10]])
 // CHECK-TRAP: [[META5]] = !DIFile(filename: "{{.*}}bounds-checking-debuginfo.c", directory: {{.*}})
 // CHECK-TRAP: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
@@ -96,7 +96,7 @@ double f1(int b, int i) {
 // CHECK-TRAP: [[DBG28]] = !DILocation(line: 66, column: 3, scope: [[DBG4]])
 //.
 // CHECK-NOTRAP: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
+// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
 // CHECK-NOTRAP: [[DBG4]] = distinct !DISubprogram(name: "f1", scope: [[META5:![0-9]+]], file: [[META5]], line: 63, type: [[META6:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]], retainedNodes: [[META10]])
 // CHECK-NOTRAP: [[META5]] = !DIFile(filename: "{{.*}}bounds-checking-debuginfo.c", directory: {{.*}})
 // CHECK-NOTRAP: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
diff --git a/clang/test/CodeGen/cfi-check-fail-debuginfo.c b/clang/test/CodeGen/cfi-check-fail-debuginfo.c
index 39e5a014249f7..b5b06977f7b77 100644
--- a/clang/test/CodeGen/cfi-check-fail-debuginfo.c
+++ b/clang/test/CodeGen/cfi-check-fail-debuginfo.c
@@ -10,21 +10,21 @@
 // CHECK-SAME: ptr noundef [[F:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !dbg [[DBG7:![0-9]+]] !type [[META16:![0-9]+]] !type [[META17:![0-9]+]] !type [[META18:![0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:      #dbg_value(ptr [[F]], [[META15:![0-9]+]], !DIExpression(), [[META19:![0-9]+]])
-// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[F]], metadata !"_ZTSFvvE"), !dbg [[DBG20:![0-9]+]], !nosanitize [[META25:![0-9]+]]
-// CHECK-NEXT:    br i1 [[TMP0]], label %[[CFI_CONT:.*]], label %[[CFI_SLOWPATH:.*]], !dbg [[DBG20]], !prof [[PROF26:![0-9]+]], !nosanitize [[META25]]
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[F]], metadata !"_ZTSFvvE"), !dbg [[DBG20:![0-9]+]], !nosanitize [[META24:![0-9]+]]
+// CHECK-NEXT:    br i1 [[TMP0]], label %[[CFI_CONT:.*]], label %[[CFI_SLOWPATH:.*]], !dbg [[DBG20]], !prof [[PROF25:![0-9]+]], !nosanitize [[META24]]
 // CHECK:       [[CFI_SLOWPATH]]:
-// CHECK-NEXT:    tail call void @__cfi_slowpath(i64 9080559750644022485, ptr [[F]]) #[[ATTR6:[0-9]+]], !dbg [[DBG20]], !nosanitize [[META25]]
-// CHECK-NEXT:    br label %[[CFI_CONT]], !dbg [[DBG20]], !nosanitize [[META25]]
+// CHECK-NEXT:    tail call void @__cfi_slowpath(i64 9080559750644022485, ptr [[F]]) #[[ATTR6:[0-9]+]], !dbg [[DBG20]], !nosanitize [[META24]]
+// CHECK-NEXT:    br label %[[CFI_CONT]], !dbg [[DBG20]], !nosanitize [[META24]]
 // CHECK:       [[CFI_CONT]]:
-// CHECK-NEXT:    tail call void [[F]]() #[[ATTR6]], !dbg [[DBG24:![0-9]+]]
-// CHECK-NEXT:    ret void, !dbg [[DBG27:![0-9]+]]
+// CHECK-NEXT:    tail call void [[F]]() #[[ATTR6]], !dbg [[DBG23:![0-9]+]]
+// CHECK-NEXT:    ret void, !dbg [[DBG26:![0-9]+]]
 //
 void caller(void (*f)(void)) {
   f();
 }
 //.
 // CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
+// CHECK: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
 // CHECK: [[DBG7]] = distinct !DISubprogram(name: "caller", scope: [[META8:![0-9]+]], file: [[META8]], line: 22, type: [[META9:![0-9]+]], scopeLine: 22, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META14:![0-9]+]])
 // CHECK: [[META8]] = !DIFile(filename: "{{.*}}cfi-check-fail-debuginfo.c", directory: {{.*}})
 // CHECK: [[META9]] = !DISubroutineType(types: [[META10:![0-9]+]])
@@ -38,12 +38,11 @@ void caller(void (*f)(void)) {
 // CHECK: [[META17]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // CHECK: [[META18]] = !{i64 0, i64 2451761621477796417}
 // CHECK: [[META19]] = !DILocation(line: 0, scope: [[DBG7]])
-// CHECK: [[DBG20]] = !DILocation(line: 0, scope: [[META21:![0-9]+]], inlinedAt: [[META23:![0-9]+]])
+// CHECK: [[DBG20]] = !DILocation(line: 0, scope: [[META21:![0-9]+]], inlinedAt: [[DBG23]])
 // CHECK: [[META21]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META8]], file: [[META8]], type: [[META22:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META22]] = !DISubroutineType(types: null)
-// CHECK: [[META23]] = !DILocation(line: 0, scope: [[META21]], inlinedAt: [[DBG24]])
-// CHECK: [[DBG24]] = !DILocation(line: 23, column: 3, scope: [[DBG7]])
-// CHECK: [[META25]] = !{}
-// CHECK: [[PROF26]] = !{!"branch_weights", i32 1048575, i32 1}
-// CHECK: [[DBG27]] = !DILocation(line: 24, column: 1, scope: [[DBG7]])
+// CHECK: [[DBG23]] = !DILocation(line: 23, column: 3, scope: [[DBG7]])
+// CHECK: [[META24]] = !{}
+// CHECK: [[PROF25]] = !{!"branch_weights", i32 1048575, i32 1}
+// CHECK: [[DBG26]] = !DILocation(line: 24, column: 1, scope: [[DBG7]])
 //.
diff --git a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
index 6f06fe7d89750..7e590fc75d789 100644
--- a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
+++ b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
@@ -27,27 +27,27 @@ int** f(const char *a, const char **b) {
 // UNGENERALIZED-SAME: ptr noundef [[FP:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !dbg [[DBG25:![0-9]+]] !type [[META31:![0-9]+]] !type [[META32:![0-9]+]] {
 // UNGENERALIZED-NEXT:  [[ENTRY:.*:]]
 // UNGENERALIZED-NEXT:      #dbg_value(ptr [[FP]], [[META30:![0-9]+]], !DIExpression(), [[META33:![0-9]+]])
-// UNGENERALIZED-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FP]], metadata !"_ZTSFPPiPKcPS2_E"), !dbg [[DBG34:![0-9]+]], !nosanitize [[META39:![0-9]+]]
-// UNGENERALIZED-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF40:![0-9]+]], !nosanitize [[META39]]
+// UNGENERALIZED-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FP]], metadata !"_ZTSFPPiPKcPS2_E"), !dbg [[DBG34:![0-9]+]], !nosanitize [[META38:![0-9]+]]
+// UNGENERALIZED-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF39:![0-9]+]], !nosanitize [[META38]]
 // UNGENERALIZED:       [[TRAP]]:
-// UNGENERALIZED-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], !dbg [[DBG34]], !nosanitize [[META39]]
-// UNGENERALIZED-NEXT:    unreachable, !dbg [[DBG34]], !nosanitize [[META39]]
+// UNGENERALIZED-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], !dbg [[DBG34]], !nosanitize [[META38]]
+// UNGENERALIZED-NEXT:    unreachable, !dbg [[DBG34]], !nosanitize [[META38]]
 // UNGENERALIZED:       [[CONT]]:
-// UNGENERALIZED-NEXT:    [[CALL:%.*]] = tail call ptr [[FP]](ptr noundef null, ptr noundef null) #[[ATTR5:[0-9]+]], !dbg [[DBG38:![0-9]+]]
-// UNGENERALIZED-NEXT:    ret void, !dbg [[DBG41:![0-9]+]]
+// UNGENERALIZED-NEXT:    [[CALL:%.*]] = tail call ptr [[FP]](ptr noundef null, ptr noundef null) #[[ATTR5:[0-9]+]], !dbg [[DBG37:![0-9]+]]
+// UNGENERALIZED-NEXT:    ret void, !dbg [[DBG40:![0-9]+]]
 //
 // GENERALIZED-LABEL: define dso_local void @g(
 // GENERALIZED-SAME: ptr noundef [[FP:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !dbg [[DBG25:![0-9]+]] !type [[META31:![0-9]+]] !type [[META32:![0-9]+]] {
 // GENERALIZED-NEXT:  [[ENTRY:.*:]]
 // GENERALIZED-NEXT:      #dbg_value(ptr [[FP]], [[META30:![0-9]+]], !DIExpression(), [[META33:![0-9]+]])
-// GENERALIZED-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FP]], metadata !"_ZTSFPvPKvS_E.generalized"), !dbg [[DBG34:![0-9]+]], !nosanitize [[META39:![0-9]+]]
-// GENERALIZED-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF40:![0-9]+]], !nosanitize [[META39]]
+// GENERALIZED-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FP]], metadata !"_ZTSFPvPKvS_E.generalized"), !dbg [[DBG34:![0-9]+]], !nosanitize [[META38:![0-9]+]]
+// GENERALIZED-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF39:![0-9]+]], !nosanitize [[META38]]
 // GENERALIZED:       [[TRAP]]:
-// GENERALIZED-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], !dbg [[DBG34]], !nosanitize [[META39]]
-// GENERALIZED-NEXT:    unreachable, !dbg [[DBG34]], !nosanitize [[META39]]
+// GENERALIZED-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], !dbg [[DBG34]], !nosanitize [[META38]]
+// GENERALIZED-NEXT:    unreachable, !dbg [[DBG34]], !nosanitize [[META38]]
 // GENERALIZED:       [[CONT]]:
-// GENERALIZED-NEXT:    [[CALL:%.*]] = tail call ptr [[FP]](ptr noundef null, ptr noundef null) #[[ATTR5:[0-9]+]], !dbg [[DBG38:![0-9]+]]
-// GENERALIZED-NEXT:    ret void, !dbg [[DBG41:![0-9]+]]
+// GENERALIZED-NEXT:    [[CALL:%.*]] = tail call ptr [[FP]](ptr noundef null, ptr noundef null) #[[ATTR5:[0-9]+]], !dbg [[DBG37:![0-9]+]]
+// GENERALIZED-NEXT:    ret void, !dbg [[DBG40:![0-9]+]]
 //
 void g(int** (*fp)(const char *, const char **)) {
   fp(0, 0);
@@ -55,7 +55,7 @@ void g(int** (*fp)(const char *, const char **)) {
 
 //.
 // UNGENERALIZED: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: [[META2:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
-// UNGENERALIZED: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
+// UNGENERALIZED: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
 // UNGENERALIZED: [[META2]] = !{[[META3:![0-9]+]]}
 // UNGENERALIZED: [[META3]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META4:![0-9]+]], size: 64)
 // UNGENERALIZED: [[META4]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META5:![0-9]+]], size: 64)
@@ -84,17 +84,16 @@ void g(int** (*fp)(const char *, const char **)) {
 // UNGENERALIZED: [[META31]] = !{i64 0, !"_ZTSFvPFPPiPKcPS2_EE"}
 // UNGENERALIZED: [[META32]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // UNGENERALIZED: [[META33]] = !DILocation(line: 0, scope: [[DBG25]])
-// UNGENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[META37:![0-9]+]])
+// UNGENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[DBG37]])
 // UNGENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // UNGENERALIZED: [[META36]] = !DISubroutineType(types: null)
-// UNGENERALIZED: [[META37]] = !DILocation(line: 0, scope: [[META35]], inlinedAt: [[DBG38]])
-// UNGENERALIZED: [[DBG38]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
-// UNGENERALIZED: [[META39]] = !{}
-// UNGENERALIZED: [[PROF40]] = !{!"branch_weights", i32 1048575, i32 1}
-// UNGENERALIZED: [[DBG41]] = !DILocation(line: 54, column: 1, scope: [[DBG25]])
+// UNGENERALIZED: [[DBG37]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
+// UNGENERALIZED: [[META38]] = !{}
+// UNGENERALIZED: [[PROF39]] = !{!"branch_weights", i32 1048575, i32 1}
+// UNGENERALIZED: [[DBG40]] = !DILocation(line: 54, column: 1, scope: [[DBG25]])
 //.
 // GENERALIZED: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: [[META2:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
-// GENERALIZED: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
+// GENERALIZED: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
 // GENERALIZED: [[META2]] = !{[[META3:![0-9]+]]}
 // GENERALIZED: [[META3]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META4:![0-9]+]], size: 64)
 // GENERALIZED: [[META4]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META5:![0-9]+]], size: 64)
@@ -123,12 +122,11 @@ void g(int** (*fp)(const char *, const char **)) {
 // GENERALIZED: [[META31]] = !{i64 0, !"_ZTSFvPFPPiPKcPS2_EE"}
 // GENERALIZED: [[META32]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // GENERALIZED: [[META33]] = !DILocation(line: 0, scope: [[DBG25]])
-// GENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[META37:![0-9]+]])
+// GENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[DBG37]])
 // GENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // GENERALIZED: [[META36]] = !DISubroutineType(types: null)
-// GENERALIZED: [[META37]] = !DILocation(line: 0, scope: [[META35]], inlinedAt: [[DBG38]])
-// GENERALIZED: [[DBG38]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
-// GENERALIZED: [[META39]] = !{}
-// GENERALIZED: [[PROF40]] = !{!"branch_weights", i32 1048575, i32 1}
-// GENERALIZED: [[DBG41]] = !DILocation(line: 54, column: 1, scope: [[DBG25]])
+// GENERALIZED: [[DBG37]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
+// GENERALIZED: [[META38]] = !{}
+// GENERALIZED: [[PROF39]] = !{!"branch_weights", i32 1048575, i32 1}
+// GENERALIZED: [[DBG40]] = !DILocation(line: 54, column: 1, scope: [[DBG25]])
 //.
diff --git a/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c b/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
index a5336b47398fa..c7a0700ae8616 100644
--- a/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
+++ b/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
@@ -12,53 +12,53 @@
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:      #dbg_value(ptr [[FN]], [[META16:![0-9]+]], !DIExpression(), [[META20:![0-9]+]])
 // CHECK-NEXT:      #dbg_value(i32 [[ARG]], [[META17:![0-9]+]], !DIExpression(), [[META20]])
-// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32E.normalized"), !dbg [[DBG21:![0-9]+]], !nosanitize [[META26:![0-9]+]]
-// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG21]], !prof [[PROF27:![0-9]+]], !nosanitize [[META26]]
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32E.normalized"), !dbg [[DBG21:![0-9]+]], !nosanitize [[META25:![0-9]+]]
+// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG21]], !prof [[PROF26:![0-9]+]], !nosanitize [[META25]]
 // CHECK:       [[TRAP]]:
-// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3:[0-9]+]], !dbg [[DBG21]], !nosanitize [[META26]]
-// CHECK-NEXT:    unreachable, !dbg [[DBG21]], !nosanitize [[META26]]
+// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3:[0-9]+]], !dbg [[DBG21]], !nosanitize [[META25]]
+// CHECK-NEXT:    unreachable, !dbg [[DBG21]], !nosanitize [[META25]]
 // CHECK:       [[CONT]]:
-// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG]]) #[[ATTR4:[0-9]+]], !dbg [[DBG25:![0-9]+]]
-// CHECK-NEXT:    ret void, !dbg [[DBG28:![0-9]+]]
+// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG]]) #[[ATTR4:[0-9]+]], !dbg [[DBG24:![0-9]+]]
+// CHECK-NEXT:    ret void, !dbg [[DBG27:![0-9]+]]
 //
 void foo(void (*fn)(int), int arg) {
     fn(arg);
 }
 
 // CHECK-LABEL: define dso_local void @bar(
-// CHECK-SAME: ptr noundef [[FN:%.*]], i32 noundef [[ARG1:%.*]], i32 noundef [[ARG2:%.*]]) local_unnamed_addr #[[ATTR0]] !dbg [[DBG29:![0-9]+]] !type [[META39:![0-9]+]] !type [[META40:![0-9]+]] {
+// CHECK-SAME: ptr noundef [[FN:%.*]], i32 noundef [[ARG1:%.*]], i32 noundef [[ARG2:%.*]]) local_unnamed_addr #[[ATTR0]] !dbg [[DBG28:![0-9]+]] !type [[META38:![0-9]+]] !type [[META39:![0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:      #dbg_value(ptr [[FN]], [[META36:![0-9]+]], !DIExpression(), [[META41:![0-9]+]])
-// CHECK-NEXT:      #dbg_value(i32 [[ARG1]], [[META37:![0-9]+]], !DIExpression(), [[META41]])
-// CHECK-NEXT:      #dbg_value(i32 [[ARG2]], [[META38:![0-9]+]], !DIExpression(), [[META41]])
-// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32S_E.normalized"), !dbg [[DBG42:![0-9]+]], !nosanitize [[META26]]
-// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG42]], !prof [[PROF27]], !nosanitize [[META26]]
+// CHECK-NEXT:      #dbg_value(ptr [[FN]], [[META35:![0-9]+]], !DIExpression(), [[META40:![0-9]+]])
+// CHECK-NEXT:      #dbg_value(i32 [[ARG1]], [[META36:![0-9]+]], !DIExpression(), [[META40]])
+// CHECK-NEXT:      #dbg_value(i32 [[ARG2]], [[META37:![0-9]+]], !DIExpression(), [[META40]])
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32S_E.normalized"), !dbg [[DBG41:![0-9]+]], !nosanitize [[META25]]
+// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG41]], !prof [[PROF26]], !nosanitize [[META25]]
 // CHECK:       [[TRAP]]:
-// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3]], !dbg [[DBG42]], !nosanitize [[META26]]
-// CHECK-NEXT:    unreachable, !dbg [[DBG42]], !nosanitize [[META26]]
+// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3]], !dbg [[DBG41]], !nosanitize [[META25]]
+// CHECK-NEXT:    unreachable, !dbg [[DBG41]], !nosanitize [[META25]]
 // CHECK:       [[CONT]]:
-// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG1]], i32 noundef [[ARG2]]) #[[ATTR4]], !dbg [[DBG44:![0-9]+]]
-// CHECK-NEXT:    ret void, !dbg [[DBG45:![0-9]+]]
+// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG1]], i32 noundef [[ARG2]]) #[[ATTR4]], !dbg [[DBG42:![0-9]+]]
+// CHECK-NEXT:    ret void, !dbg [[DBG43:![0-9]+]]
 //
 void bar(void (*fn)(int, int), int arg1, int arg2) {
     fn(arg1, arg2);
 }
 
 // CHECK-LABEL: define dso_local void @baz(
-// CHECK-SAME: ptr noundef [[FN:%.*]], i32 noundef [[ARG1:%.*]], i32 noundef [[ARG2:%.*]], i32 noundef [[ARG3:%.*]]) local_unnamed_addr #[[ATTR0]] !dbg [[DBG46:![0-9]+]] !type [[META57:![0-9]+]] !type [[META58:![0-9]+]] {
+// CHECK-SAME: ptr noundef [[FN:%.*]], i32 noundef [[ARG1:%.*]], i32 noundef [[ARG2:%.*]], i32 noundef [[ARG3:%.*]]) local_unnamed_addr #[[ATTR0]] !dbg [[DBG44:![0-9]+]] !type [[META55:![0-9]+]] !type [[META56:![0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:      #dbg_value(ptr [[FN]], [[META53:![0-9]+]], !DIExpression(), [[META59:![0-9]+]])
-// CHECK-NEXT:      #dbg_value(i32 [[ARG1]], [[META54:![0-9]+]], !DIExpression(), [[META59]])
-// CHECK-NEXT:      #dbg_value(i32 [[ARG2]], [[META55:![0-9]+]], !DIExpression(), [[META59]])
-// CHECK-NEXT:      #dbg_value(i32 [[ARG3]], [[META56:![0-9]+]], !DIExpression(), [[META59]])
-// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32S_S_E.normalized"), !dbg [[DBG60:![0-9]+]], !nosanitize [[META26]]
-// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG60]], !prof [[PROF27]], !nosanitize [[META26]]
+// CHECK-NEXT:      #dbg_value(ptr [[FN]], [[META51:![0-9]+]], !DIExpression(), [[META57:![0-9]+]])
+// CHECK-NEXT:      #dbg_value(i32 [[ARG1]], [[META52:![0-9]+]], !DIExpression(), [[META57]])
+// CHECK-NEXT:      #dbg_value(i32 [[ARG2]], [[META53:![0-9]+]], !DIExpression(), [[META57]])
+// CHECK-NEXT:      #dbg_value(i32 [[ARG3]], [[META54:![0-9]+]], !DIExpression(), [[META57]])
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[FN]], metadata !"_ZTSFvu3i32S_S_E.normalized"), !dbg [[DBG58:![0-9]+]], !nosanitize [[META25]]
+// CHECK-NEXT:    br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG58]], !prof [[PROF26]], !nosanitize [[META25]]
 // CHECK:       [[TRAP]]:
-// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3]], !dbg [[DBG60]], !nosanitize [[META26]]
-// CHECK-NEXT:    unreachable, !dbg [[DBG60]], !nosanitize [[META26]]
+// CHECK-NEXT:    tail call void @llvm.ubsantrap(i8 2) #[[ATTR3]], !dbg [[DBG58]], !nosanitize [[META25]]
+// CHECK-NEXT:    unreachable, !dbg [[DBG58]], !nosanitize [[META25]]
 // CHECK:       [[CONT]]:
-// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG1]], i32 noundef [[ARG2]], i32 noundef [[ARG3]]) #[[ATTR4]], !dbg [[DBG62:![0-9]+]]
-// CHECK-NEXT:    ret void, !dbg [[DBG63:![0-9]+]]
+// CHECK-NEXT:    tail call void [[FN]](i32 noundef [[ARG1]], i32 noundef [[ARG2]], i32 noundef [[ARG3]]) #[[ATTR4]], !dbg [[DBG59:![0-9]+]]
+// CHECK-NEXT:    ret void, !dbg [[DBG60:![0-9]+]]
 //
 void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) {
     fn(arg1, arg2, arg3);
@@ -66,7 +66,7 @@ void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) {
 
 //.
 // CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
+// CHECK: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
 // CHECK: [[DBG7]] = distinct !DISubprogram(name: "foo", scope: [[META8:![0-9]+]], file: [[META8]], line: 24, type: [[META9:![0-9]+]], scopeLine: 24, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META15:![0-9]+]])
 // CHECK: [[META8]] = !DIFile(filename: "{{.*}}cfi-icall-normalize2-debuginfo.c", directory: {{.*}})
 // CHECK: [[META9]] = !DISubroutineType(types: [[META10:![0-9]+]])
@@ -81,47 +81,44 @@ void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) {
 // CHECK: [[META18]] = !{i64 0, !"_ZTSFvPFvu3i32ES_E.normalized"}
 // CHECK: [[META19]] = !{i64 0, !"_ZTSFvPvu3i32E.normalized.generalized"}
 // CHECK: [[META20]] = !DILocation(line: 0, scope: [[DBG7]])
-// CHECK: [[DBG21]] = !DILocation(line: 0, scope: [[META22:![0-9]+]], inlinedAt: [[META24:![0-9]+]])
+// CHECK: [[DBG21]] = !DILocation(line: 0, scope: [[META22:![0-9]+]], inlinedAt: [[DBG24]])
 // CHECK: [[META22]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META8]], file: [[META8]], type: [[META23:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META23]] = !DISubroutineType(types: null)
-// CHECK: [[META24]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[DBG25]])
-// CHECK: [[DBG25]] = !DILocation(line: 25, column: 5, scope: [[DBG7]])
-// CHECK: [[META26]] = !{}
-// CHECK: [[PROF27]] = !{!"branch_weights", i32 1048575, i32 1}
-// CHECK: [[DBG28]] = !DILocation(line: 26, column: 1, scope: [[DBG7]])
-// CHECK: [[DBG29]] = distinct !DISubprogram(name: "bar", scope: [[META8]], file: [[META8]], line: 43, type: [[META30:![0-9]+]], scopeLine: 43, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META35:![0-9]+]])
-// CHECK: [[META30]] = !DISubroutineType(types: [[META31:![0-9]+]])
-// CHECK: [[META31]] = !{null, [[META32:![0-9]+]], [[META14]], [[META14]]}
-// CHECK: [[META32]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META33:![0-9]+]], size: 64)
-// CHECK: [[META33]] = !DISubroutineType(types: [[META34:![0-9]+]])
-// CHECK: [[META34]] = !{null, [[META14]], [[META14]]}
-// CHECK: [[META35]] = !{[[META36]], [[META37]], [[META38]]}
-// CHECK: [[META36]] = !DILocalVariable(name: "fn", arg: 1, scope: [[DBG29]], file: [[META8]], line: 43, type: [[META32]])
-// CHECK: [[META37]] = !DILocalVariable(name: "arg1", arg: 2, scope: [[DBG29]], file: [[META8]], line: 43, type: [[META14]])
-// CHECK: [[META38]] = !DILocalVariable(name: "arg2", arg: 3, scope: [[DBG29]], file: [[META8]], line: 43, type: [[META14]])
-// CHECK: [[META39]] = !{i64 0, !"_ZTSFvPFvu3i32S_ES_S_E.normalized"}
-// CHECK: [[META40]] = !{i64 0, !"_ZTSFvPvu3i32S0_E.normalized.generalized"}
-// CHECK: [[META41]] = !DILocation(line: 0, scope: [[DBG29]])
-// CHECK: [[DBG42]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[META43:![0-9]+]])
-// CHECK: [[META43]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[DBG44]])
-// CHECK: [[DBG44]] = !DILocation(line: 44, column: 5, scope: [[DBG29]])
-// CHECK: [[DBG45]] = !DILocation(line: 45, column: 1, scope: [[DBG29]])
-// CHECK: [[DBG46]] = distinct !DISubprogram(name: "baz", scope: [[META8]], file: [[META8]], line: 63, type: [[META47:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META52:![0-9]+]])
-// CHECK: [[META47]] = !DISubroutineType(types: [[META48:![0-9]+]])
-// CHECK: [[META48]] = !{null, [[META49:![0-9]+]], [[META14]], [[META14]], [[META14]]}
-// CHECK: [[META49]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META50:![0-9]+]], size: 64)
-// CHECK: [[META50]] = !DISubroutineType(types: [[META51:![0-9]+]])
-// CHECK: [[META51]] = !{null, [[META14]], [[META14]], [[META14]]}
-// CHECK: [[META52]] = !{[[META53]], [[META54]], [[META55]], [[META56]]}
-// CHECK: [[META53]] = !DILocalVariable(name: "fn", arg: 1, scope: [[DBG46]], file: [[META8]], line: 63, type: [[META49]])
-// CHECK: [[META54]] = !DILocalVariable(name: "arg1", arg: 2, scope: [[DBG46]], file: [[META8]], line: 63, type: [[META14]])
-// CHECK: [[META55]] = !DILocalVariable(name: "arg2", arg: 3, scope: [[DBG46]], file: [[META8]], line: 63, type: [[META14]])
-// CHECK: [[META56]] = !DILocalVariable(name: "arg3", arg: 4, scope: [[DBG46]], file: [[META8]], line: 63, type: [[META14]])
-// CHECK: [[META57]] = !{i64 0, !"_ZTSFvPFvu3i32S_S_ES_S_S_E.normalized"}
-// CHECK: [[META58]] = !{i64 0, !"_ZTSFvPvu3i32S0_S0_E.normalized.generalized"}
-// CHECK: [[META59]] = !DILocation(line: 0, scope: [[DBG46]])
-// CHECK: [[DBG60]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[META61:![0-9]+]])
-// CHECK: [[META61]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[DBG62]])
-// CHECK: [[DBG62]] = !DILocation(line: 64, column: 5, scope: [[DBG46]])
-// CHECK: [[DBG63]] = !DILocation(line: 65, column: 1, scope: [[DBG46]])
+// CHECK: [[DBG24]] = !DILocation(line: 25, column: 5, scope: [[DBG7]])
+// CHECK: [[META25]] = !{}
+// CHECK: [[PROF26]] = !{!"branch_weights", i32 1048575, i32 1}
+// CHECK: [[DBG27]] = !DILocation(line: 26, column: 1, scope: [[DBG7]])
+// CHECK: [[DBG28]] = distinct !DISubprogram(name: "bar", scope: [[META8]], file: [[META8]], line: 43, type: [[META29:![0-9]+]], scopeLine: 43, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META34:![0-9]+]])
+// CHECK: [[META29]] = !DISubroutineType(types: [[META30:![0-9]+]])
+// CHECK: [[META30]] = !{null, [[META31:![0-9]+]], [[META14]], [[META14]]}
+// CHECK: [[META31]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META32:![0-9]+]], size: 64)
+// CHECK: [[META32]] = !DISubroutineType(types: [[META33:![0-9]+]])
+// CHECK: [[META33]] = !{null, [[META14]], [[META14]]}
+// CHECK: [[META34]] = !{[[META35]], [[META36]], [[META37]]}
+// CHECK: [[META35]] = !DILocalVariable(name: "fn", arg: 1, scope: [[DBG28]], file: [[META8]], line: 43, type: [[META31]])
+// CHECK: [[META36]] = !DILocalVariable(name: "arg1", arg: 2, scope: [[DBG28]], file: [[META8]], line: 43, type: [[META14]])
+// CHECK: [[META37]] = !DILocalVariable(name: "arg2", arg: 3, scope: [[DBG28]], file: [[META8]], line: 43, type: [[META14]])
+// CHECK: [[META38]] = !{i64 0, !"_ZTSFvPFvu3i32S_ES_S_E.normalized"}
+// CHECK: [[META39]] = !{i64 0, !"_ZTSFvPvu3i32S0_E.normalized.generalized"}
+// CHECK: [[META40]] = !DILocation(line: 0, scope: [[DBG28]])
+// CHECK: [[DBG41]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[DBG42]])
+// CHECK: [[DBG42]] = !DILocation(line: 44, column: 5, scope: [[DBG28]])
+// CHECK: [[DBG43]] = !DILocation(line: 45, column: 1, scope: [[DBG28]])
+// CHECK: [[DBG44]] = distinct !DISubprogram(name: "baz", scope: [[META8]], file: [[META8]], line: 63, type: [[META45:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META50:![0-9]+]])
+// CHECK: [[META45]] = !DISubroutineType(types: [[META46:![0-9]+]])
+// CHECK: [[META46]] = !{null, [[META47:![0-9]+]], [[META14]], [[META14]], [[META14]]}
+// CHECK: [[META47]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META48:![0-9]+]], size: 64)
+// CHECK: [[META48]] = !DISubroutineType(types: [[META49:![0-9]+]])
+// CHECK: [[META49]] = !{null, [[META14]], [[META14]], [[META14]]}
+// CHECK: [[META50]] = !{[[META51]], [[META52]], [[META53]], [[META54]]}
+// CHECK: [[META51]] = !DILocalVariable(name: "fn", arg: 1, scope: [[DBG44]], file: [[META8]], line: 63, type: [[META47]])
+// CHECK: [[META52]] = !DILocalVariable(name: "arg1", arg: 2, scope: [[DBG44]], file: [[META8]], line: 63, type: [[META14]])
+// CHECK: [[META53]] = !DILocalVariable(name: "arg2", arg: 3, scope: [[DBG44]], file: [[META8]], line: 63, type: [[META14]])
+// CHECK: [[META54]] = !DILocalVariable(name: "arg3", arg: 4, scope: [[DBG44]], file: [[META8]], line: 63, type: [[META14]])
+// CHECK: [[META55]] = !{i64 0, !"_ZTSFvPFvu3i32S_S_ES_S_S_E.normalized"}
+// CHECK: [[META56]] = !{i64 0, !"_ZTSFvPvu3i32S0_S0_E.normalized.generalized"}
+// CHECK: [[META57]] = !DILocation(line: 0, scope: [[DBG44]])
+// CHECK: [[DBG58]] = !DILocation(line: 0, scope: [[META22]], inlinedAt: [[DBG59]])
+// CHECK: [[DBG59]] = !DILocation(line: 64, column: 5, scope: [[DBG44]])
+// CHECK: [[DBG60]] = !DILocation(line: 65, column: 1, scope: [[DBG44]])
 //.
diff --git a/clang/test/CodeGen/ubsan-function-debuginfo.c b/clang/test/CodeGen/ubsan-function-debuginfo.c
index 5bf490d498bb3..96382460f5b0d 100644
--- a/clang/test/CodeGen/ubsan-function-debuginfo.c
+++ b/clang/test/CodeGen/ubsan-function-debuginfo.c
@@ -37,7 +37,7 @@ void call_no_prototype(void (*f)()) { f(); }
 void call_prototype(void (*f)(void)) { f(); }
 //.
 // CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
+// CHECK: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
 // CHECK: [[DBG5]] = distinct !DISubprogram(name: "call_no_prototype", scope: [[META6:![0-9]+]], file: [[META6]], line: 14, type: [[META7:![0-9]+]], scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META12:![0-9]+]])
 // CHECK: [[META6]] = !DIFile(filename: "{{.*}}ubsan-function-debuginfo.c", directory: {{.*}})
 // CHECK: [[META7]] = !DISubroutineType(types: [[META8:![0-9]+]])
diff --git a/clang/test/CodeGen/unsigned-promotion-debuginfo.c b/clang/test/CodeGen/unsigned-promotion-debuginfo.c
index 6b758096aee77..a1a7ab9ce6148 100644
--- a/clang/test/CodeGen/unsigned-promotion-debuginfo.c
+++ b/clang/test/CodeGen/unsigned-promotion-debuginfo.c
@@ -50,7 +50,7 @@ void testshortmul(void) {
 // CHECKS: [[META0:![0-9]+]] = !DIGlobalVariableExpression(var: [[META1:![0-9]+]], expr: !DIExpression())
 // CHECKS: [[META1]] = distinct !DIGlobalVariable(name: "sj", scope: [[META2:![0-9]+]], file: [[META7:![0-9]+]], line: 12, type: [[META8:![0-9]+]], isLocal: false, isDefinition: true)
 // CHECKS: [[META2]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META3:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: [[META4:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
-// CHECKS: [[META3]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
+// CHECKS: [[META3]] = !DIFile(filename: "<stdin>", directory: {{.*}})
 // CHECKS: [[META4]] = !{[[META5:![0-9]+]], [[META0]], [[META9:![0-9]+]]}
 // CHECKS: [[META5]] = !DIGlobalVariableExpression(var: [[META6:![0-9]+]], expr: !DIExpression())
 // CHECKS: [[META6]] = distinct !DIGlobalVariable(name: "si", scope: [[META2]], file: [[META7]], line: 12, type: [[META8]], isLocal: false, isDefinition: true)
@@ -79,7 +79,7 @@ void testshortmul(void) {
 // CHECKU: [[META0:![0-9]+]] = !DIGlobalVariableExpression(var: [[META1:![0-9]+]], expr: !DIExpression())
 // CHECKU: [[META1]] = distinct !DIGlobalVariable(name: "sj", scope: [[META2:![0-9]+]], file: [[META7:![0-9]+]], line: 12, type: [[META8:![0-9]+]], isLocal: false, isDefinition: true)
 // CHECKU: [[META2]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META3:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: [[META4:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
-// CHECKU: [[META3]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
+// CHECKU: [[META3]] = !DIFile(filename: "<stdin>", directory: {{.*}})
 // CHECKU: [[META4]] = !{[[META5:![0-9]+]], [[META0]], [[META9:![0-9]+]]}
 // CHECKU: [[META5]] = !DIGlobalVariableExpression(var: [[META6:![0-9]+]], expr: !DIExpression())
 // CHECKU: [[META6]] = distinct !DIGlobalVariable(name: "si", scope: [[META2]], file: [[META7]], line: 12, type: [[META8]], isLocal: false, isDefinition: true)

>From 4f9a4dea42d9e67bb93e4f532ad82e8d5a0c5c89 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Thu, 29 May 2025 17:44:41 +0000
Subject: [PATCH 07/26] Add missing SanitizerOrdinal to SanitizerScope

---
 clang/lib/CodeGen/CGExprScalar.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 43ac70bd81b7c..8fd8dd91cc44a 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -1284,7 +1284,8 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
   // That's it. We can't rule out any more cases with the data we have.
 
   CodeGenFunction::SanitizerScope SanScope(
-      &CGF, {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
+      &CGF, {SanitizerKind::SO_ImplicitIntegerSignChange,
+             SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
              SanitizerKind::SO_ImplicitSignedIntegerTruncation});
 
   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,

>From 40412708a9bb5b5c4cdb85e6f1b8bb560e95fc02 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Fri, 30 May 2025 18:42:17 +0000
Subject: [PATCH 08/26] Rename to __ubsan_check_debug_info_anchor

---
 clang/lib/CodeGen/CGExpr.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 5bd782215b1b4..4707211d46cb9 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1258,7 +1258,7 @@ llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
          CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo.has(Ord)) &&
         CheckDI) {
       CheckDI = getDebugInfo()->CreateSyntheticInlineAt(
-          CheckDI, "__ubsan_check_singularity");
+          CheckDI, "__ubsan_check_debug_info_anchor");
       break;
     }
   }

>From 93ef35843ce4c77b7d3b82c808c5f45e9d0399fc Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Fri, 30 May 2025 18:52:27 +0000
Subject: [PATCH 09/26] Unnecessary braces

---
 clang/lib/CodeGen/CGExprScalar.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 8fd8dd91cc44a..d9811bd9c8f6a 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -4762,9 +4762,8 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
       Kinds.push_back(SanitizerKind::SO_ShiftBase);
     if (SanitizeUnsignedBase)
       Kinds.push_back(SanitizerKind::SO_UnsignedShiftBase);
-    if (SanitizeExponent) {
+    if (SanitizeExponent)
       Kinds.push_back(SanitizerKind::SO_ShiftExponent);
-    }
 
     CodeGenFunction::SanitizerScope SanScope(&CGF, Kinds);
     SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;

>From 5da37cd6c79a813205b6ebe24c81b09d4b1f76ff Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Fri, 30 May 2025 19:01:00 +0000
Subject: [PATCH 10/26] Update tests

---
 clang/test/CodeGen/bounds-checking-debuginfo.c      | 4 ++--
 clang/test/CodeGen/cfi-check-fail-debuginfo.c       | 2 +-
 clang/test/CodeGen/cfi-icall-generalize-debuginfo.c | 4 ++--
 clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c | 2 +-
 clang/test/CodeGen/ubsan-function-debuginfo.c       | 2 +-
 clang/test/CodeGen/unsigned-promotion-debuginfo.c   | 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/clang/test/CodeGen/bounds-checking-debuginfo.c b/clang/test/CodeGen/bounds-checking-debuginfo.c
index 4c0eb5a8559c4..c851ff23e0032 100644
--- a/clang/test/CodeGen/bounds-checking-debuginfo.c
+++ b/clang/test/CodeGen/bounds-checking-debuginfo.c
@@ -89,7 +89,7 @@ double f1(int b, int i) {
 // CHECK-TRAP: [[DBG21]] = !DILocation(line: 65, column: 3, scope: [[DBG4]])
 // CHECK-TRAP: [[DBG22]] = !DILocation(line: 66, column: 12, scope: [[DBG4]])
 // CHECK-TRAP: [[DBG23]] = !DILocation(line: 0, scope: [[META24:![0-9]+]], inlinedAt: [[DBG26]])
-// CHECK-TRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK-TRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK-TRAP: [[META25]] = !DISubroutineType(types: null)
 // CHECK-TRAP: [[DBG26]] = !DILocation(line: 66, column: 10, scope: [[DBG4]])
 // CHECK-TRAP: [[PROF27]] = !{!"branch_weights", i32 1048575, i32 1}
@@ -117,7 +117,7 @@ double f1(int b, int i) {
 // CHECK-NOTRAP: [[DBG21]] = !DILocation(line: 65, column: 3, scope: [[DBG4]])
 // CHECK-NOTRAP: [[DBG22]] = !DILocation(line: 66, column: 12, scope: [[DBG4]])
 // CHECK-NOTRAP: [[DBG23]] = !DILocation(line: 0, scope: [[META24:![0-9]+]], inlinedAt: [[DBG26]])
-// CHECK-NOTRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK-NOTRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK-NOTRAP: [[META25]] = !DISubroutineType(types: null)
 // CHECK-NOTRAP: [[DBG26]] = !DILocation(line: 66, column: 10, scope: [[DBG4]])
 // CHECK-NOTRAP: [[PROF27]] = !{!"branch_weights", i32 1048575, i32 1}
diff --git a/clang/test/CodeGen/cfi-check-fail-debuginfo.c b/clang/test/CodeGen/cfi-check-fail-debuginfo.c
index b5b06977f7b77..4725110a49d8b 100644
--- a/clang/test/CodeGen/cfi-check-fail-debuginfo.c
+++ b/clang/test/CodeGen/cfi-check-fail-debuginfo.c
@@ -39,7 +39,7 @@ void caller(void (*f)(void)) {
 // CHECK: [[META18]] = !{i64 0, i64 2451761621477796417}
 // CHECK: [[META19]] = !DILocation(line: 0, scope: [[DBG7]])
 // CHECK: [[DBG20]] = !DILocation(line: 0, scope: [[META21:![0-9]+]], inlinedAt: [[DBG23]])
-// CHECK: [[META21]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META8]], file: [[META8]], type: [[META22:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[META21]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META8]], file: [[META8]], type: [[META22:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META22]] = !DISubroutineType(types: null)
 // CHECK: [[DBG23]] = !DILocation(line: 23, column: 3, scope: [[DBG7]])
 // CHECK: [[META24]] = !{}
diff --git a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
index 7e590fc75d789..903bc7b730aa5 100644
--- a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
+++ b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
@@ -85,7 +85,7 @@ void g(int** (*fp)(const char *, const char **)) {
 // UNGENERALIZED: [[META32]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // UNGENERALIZED: [[META33]] = !DILocation(line: 0, scope: [[DBG25]])
 // UNGENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[DBG37]])
-// UNGENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// UNGENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // UNGENERALIZED: [[META36]] = !DISubroutineType(types: null)
 // UNGENERALIZED: [[DBG37]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
 // UNGENERALIZED: [[META38]] = !{}
@@ -123,7 +123,7 @@ void g(int** (*fp)(const char *, const char **)) {
 // GENERALIZED: [[META32]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // GENERALIZED: [[META33]] = !DILocation(line: 0, scope: [[DBG25]])
 // GENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[DBG37]])
-// GENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// GENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // GENERALIZED: [[META36]] = !DISubroutineType(types: null)
 // GENERALIZED: [[DBG37]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
 // GENERALIZED: [[META38]] = !{}
diff --git a/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c b/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
index c7a0700ae8616..b71cec8a4d2bb 100644
--- a/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
+++ b/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
@@ -82,7 +82,7 @@ void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) {
 // CHECK: [[META19]] = !{i64 0, !"_ZTSFvPvu3i32E.normalized.generalized"}
 // CHECK: [[META20]] = !DILocation(line: 0, scope: [[DBG7]])
 // CHECK: [[DBG21]] = !DILocation(line: 0, scope: [[META22:![0-9]+]], inlinedAt: [[DBG24]])
-// CHECK: [[META22]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META8]], file: [[META8]], type: [[META23:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[META22]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META8]], file: [[META8]], type: [[META23:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META23]] = !DISubroutineType(types: null)
 // CHECK: [[DBG24]] = !DILocation(line: 25, column: 5, scope: [[DBG7]])
 // CHECK: [[META25]] = !{}
diff --git a/clang/test/CodeGen/ubsan-function-debuginfo.c b/clang/test/CodeGen/ubsan-function-debuginfo.c
index 96382460f5b0d..84da58038aa3f 100644
--- a/clang/test/CodeGen/ubsan-function-debuginfo.c
+++ b/clang/test/CodeGen/ubsan-function-debuginfo.c
@@ -62,7 +62,7 @@ void call_prototype(void (*f)(void)) { f(); }
 // CHECK: [[META26]] = !{i32 -1056584962, i32 -747727454}
 // CHECK: [[META27]] = !DILocation(line: 0, scope: [[DBG18]])
 // CHECK: [[DBG28]] = !DILocation(line: 0, scope: [[META29:![0-9]+]], inlinedAt: [[DBG31]])
-// CHECK: [[META29]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META6]], file: [[META6]], type: [[META30:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[META29]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META6]], file: [[META6]], type: [[META30:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META30]] = !DISubroutineType(types: null)
 // CHECK: [[DBG31]] = !DILocation(line: 37, column: 40, scope: [[DBG18]])
 // CHECK: [[META32]] = !{}
diff --git a/clang/test/CodeGen/unsigned-promotion-debuginfo.c b/clang/test/CodeGen/unsigned-promotion-debuginfo.c
index a1a7ab9ce6148..3c0016104ac93 100644
--- a/clang/test/CodeGen/unsigned-promotion-debuginfo.c
+++ b/clang/test/CodeGen/unsigned-promotion-debuginfo.c
@@ -68,7 +68,7 @@ void testshortmul(void) {
 // CHECKS: [[META20]] = !{!"Simple C/C++ TBAA"}
 // CHECKS: [[DBG21]] = !DILocation(line: 47, column: 13, scope: [[DBG13]])
 // CHECKS: [[DBG22]] = !DILocation(line: 0, scope: [[META23:![0-9]+]], inlinedAt: [[META25:![0-9]+]])
-// CHECKS: [[META23]] = distinct !DISubprogram(name: "__ubsan_check_singularity", scope: [[META7]], file: [[META7]], type: [[META24:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META2]])
+// CHECKS: [[META23]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META7]], file: [[META7]], type: [[META24:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META2]])
 // CHECKS: [[META24]] = !DISubroutineType(types: null)
 // CHECKS: [[META25]] = !DILocation(line: 47, column: 11, scope: [[DBG13]])
 // CHECKS: [[META26]] = !{}

>From 9dee8ea4a28bc88902c2bad955e4504dc3e333da Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Sat, 31 May 2025 00:38:12 +0000
Subject: [PATCH 11/26] Use SanitizerHandler in name

---
 clang/lib/CodeGen/CGBuiltin.cpp               | 24 ++++--
 clang/lib/CodeGen/CGCall.cpp                  |  6 +-
 clang/lib/CodeGen/CGClass.cpp                 | 25 +++---
 clang/lib/CodeGen/CGDecl.cpp                  |  9 +-
 clang/lib/CodeGen/CGExpr.cpp                  | 83 +++++++++++--------
 clang/lib/CodeGen/CGExprScalar.cpp            | 81 +++++++++++-------
 clang/lib/CodeGen/CGObjC.cpp                  |  5 +-
 clang/lib/CodeGen/CodeGenFunction.cpp         | 31 ++++---
 clang/lib/CodeGen/CodeGenFunction.h           |  9 +-
 clang/lib/CodeGen/ItaniumCXXABI.cpp           | 18 ++--
 .../test/CodeGen/bounds-checking-debuginfo.c  |  4 +-
 clang/test/CodeGen/cfi-check-fail-debuginfo.c |  2 +-
 .../CodeGen/cfi-icall-generalize-debuginfo.c  |  4 +-
 .../CodeGen/cfi-icall-normalize2-debuginfo.c  |  2 +-
 clang/test/CodeGen/ubsan-function-debuginfo.c |  2 +-
 .../CodeGen/unsigned-promotion-debuginfo.c    |  2 +-
 16 files changed, 181 insertions(+), 126 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index b858770155472..5c54788e2a078 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2007,11 +2007,11 @@ Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
     return ArgValue;
 
   auto CheckOrdinal = SanitizerKind::SO_Builtin;
-  SanitizerScope SanScope(this, {CheckOrdinal});
+  auto CheckHandler = SanitizerHandler::InvalidBuiltin;
+  SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
   Value *Cond = Builder.CreateICmpNE(
       ArgValue, llvm::Constant::getNullValue(ArgValue->getType()));
-  EmitCheck(std::make_pair(Cond, CheckOrdinal),
-            SanitizerHandler::InvalidBuiltin,
+  EmitCheck(std::make_pair(Cond, CheckOrdinal), CheckHandler,
             {EmitCheckSourceLocation(E->getExprLoc()),
              llvm::ConstantInt::get(Builder.getInt8Ty(), Kind)},
             {});
@@ -2024,9 +2024,10 @@ Value *CodeGenFunction::EmitCheckedArgForAssume(const Expr *E) {
     return ArgValue;
 
   auto CheckOrdinal = SanitizerKind::SO_Builtin;
-  SanitizerScope SanScope(this, {CheckOrdinal});
+  auto CheckHandler = SanitizerHandler::InvalidBuiltin;
+  SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
   EmitCheck(
-      std::make_pair(ArgValue, CheckOrdinal), SanitizerHandler::InvalidBuiltin,
+      std::make_pair(ArgValue, CheckOrdinal), CheckHandler,
       {EmitCheckSourceLocation(E->getExprLoc()),
        llvm::ConstantInt::get(Builder.getInt8Ty(), BCK_AssumePassedFalse)},
       std::nullopt);
@@ -2050,9 +2051,14 @@ static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E,
   }
 
   SmallVector<SanitizerKind::SanitizerOrdinal, 1> Ordinals;
-  if (SanitizeOverflow)
+  SanitizerHandler CheckHandler;
+  if (SanitizeOverflow) {
     Ordinals.push_back(SanitizerKind::SO_SignedIntegerOverflow);
-  CodeGenFunction::SanitizerScope SanScope(&CGF, Ordinals);
+    CheckHandler = SanitizerHandler::NegateOverflow;
+  } else
+    CheckHandler = SanitizerHandler::SubOverflow;
+
+  CodeGenFunction::SanitizerScope SanScope(&CGF, Ordinals, CheckHandler);
 
   Constant *Zero = Constant::getNullValue(ArgValue->getType());
   Value *ResultAndOverflow = CGF.Builder.CreateBinaryIntrinsic(
@@ -2064,12 +2070,12 @@ static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E,
   // TODO: support -ftrapv-handler.
   if (SanitizeOverflow) {
     CGF.EmitCheck({{NotOverflow, SanitizerKind::SO_SignedIntegerOverflow}},
-                  SanitizerHandler::NegateOverflow,
+                  CheckHandler,
                   {CGF.EmitCheckSourceLocation(E->getArg(0)->getExprLoc()),
                    CGF.EmitCheckTypeDescriptor(E->getType())},
                   {ArgValue});
   } else
-    CGF.EmitTrapCheck(NotOverflow, SanitizerHandler::SubOverflow);
+    CGF.EmitTrapCheck(NotOverflow, CheckHandler);
 
   Value *CmpResult = CGF.Builder.CreateICmpSLT(ArgValue, Zero, "abscond");
   return CGF.Builder.CreateSelect(CmpResult, Result, ArgValue, "abs");
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index fedabea72d600..da6d4caaf5000 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4156,7 +4156,7 @@ void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV) {
     Handler = SanitizerHandler::NullabilityReturn;
   }
 
-  SanitizerScope SanScope(this, {CheckKind});
+  SanitizerScope SanScope(this, {CheckKind}, Handler);
 
   // Make sure the "return" source location is valid. If we're checking a
   // nullability annotation, make sure the preconditions for the check are met.
@@ -4541,7 +4541,7 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
     Handler = SanitizerHandler::NullabilityArg;
   }
 
-  SanitizerScope SanScope(this, {CheckKind});
+  SanitizerScope SanScope(this, {CheckKind}, Handler);
   llvm::Value *Cond = EmitNonNullRValueCheck(RV, ArgType);
   llvm::Constant *StaticData[] = {
       EmitCheckSourceLocation(ArgLoc),
@@ -5976,7 +5976,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
       // attribute to insert handler calls.
       if (SanOpts.hasOneOf(SanitizerKind::Address |
                            SanitizerKind::KernelAddress)) {
-        SanitizerScope SanScope(this, {});
+        SanitizerScope SanScope(this);
         llvm::IRBuilder<>::InsertPointGuard IPGuard(Builder);
         Builder.SetInsertPoint(CI);
         auto *FnType = llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 70f885de05cf9..b2815b08a3968 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1678,7 +1678,7 @@ namespace {
   static void EmitSanitizerDtorCallback(
       CodeGenFunction &CGF, StringRef Name, llvm::Value *Ptr,
       std::optional<CharUnits::QuantityType> PoisonSize = {}) {
-    CodeGenFunction::SanitizerScope SanScope(&CGF, {});
+    CodeGenFunction::SanitizerScope SanScope(&CGF);
     // Pass in void pointer and size of region as arguments to runtime
     // function
     SmallVector<llvm::Value *, 2> Args = {Ptr};
@@ -2817,7 +2817,9 @@ void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
     RD = LeastDerivedClassWithSameLayout(RD);
 
   auto [Ordinal, _] = SanitizerInfoFromCFICheckKind(TCK);
-  ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(Ordinal));
+  ApplyDebugLocation ApplyTrapDI(
+      *this,
+      SanitizerAnnotateDebugInfo(Ordinal, SanitizerHandler::CFICheckFail));
 
   EmitVTablePtrCheck(RD, VTable, TCK, Loc);
 }
@@ -2842,7 +2844,9 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived,
     ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl);
 
   auto [Ordinal, _] = SanitizerInfoFromCFICheckKind(TCK);
-  ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(Ordinal));
+  ApplyDebugLocation ApplyTrapDI(
+      *this,
+      SanitizerAnnotateDebugInfo(Ordinal, SanitizerHandler::CFICheckFail));
 
   llvm::BasicBlock *ContBlock = nullptr;
 
@@ -2885,7 +2889,8 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
           SanitizerMask::bitPosToMask(M), TypeName))
     return;
 
-  SanitizerScope SanScope(this, {M});
+  auto CheckHandler = SanitizerHandler::CFICheckFail;
+  SanitizerScope SanScope(this, {M}, CheckHandler);
   EmitSanitizerStatReport(SSK);
 
   llvm::Metadata *MD =
@@ -2909,7 +2914,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
 
   if (CGM.getCodeGenOpts().SanitizeTrap.has(M)) {
     bool NoMerge = !CGM.getCodeGenOpts().SanitizeMergeHandlers.has(M);
-    EmitTrapCheck(TypeTest, SanitizerHandler::CFICheckFail, NoMerge);
+    EmitTrapCheck(TypeTest, CheckHandler, NoMerge);
     return;
   }
 
@@ -2918,8 +2923,8 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
       llvm::MDString::get(CGM.getLLVMContext(), "all-vtables"));
   llvm::Value *ValidVtable = Builder.CreateCall(
       CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
-  EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
-            StaticData, {VTable, ValidVtable});
+  EmitCheck(std::make_pair(TypeTest, M), CheckHandler, StaticData,
+            {VTable, ValidVtable});
 }
 
 bool CodeGenFunction::ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD) {
@@ -2943,7 +2948,8 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
     const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy,
     uint64_t VTableByteOffset) {
   auto CheckOrdinal = SanitizerKind::SO_CFIVCall;
-  SanitizerScope SanScope(this, {CheckOrdinal});
+  auto CheckHandler = SanitizerHandler::CFICheckFail;
+  SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
 
   EmitSanitizerStatReport(llvm::SanStat_CFI_VCall);
 
@@ -2964,8 +2970,7 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
   if (SanOpts.has(SanitizerKind::CFIVCall) &&
       !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
                                                      TypeName)) {
-    EmitCheck(std::make_pair(CheckResult, CheckOrdinal),
-              SanitizerHandler::CFICheckFail, {}, {});
+    EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler, {}, {});
   }
 
   return Builder.CreateBitCast(Builder.CreateExtractValue(CheckedLoad, 0),
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 139cc567f101b..aaa6fd479cadf 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -766,14 +766,14 @@ void CodeGenFunction::EmitNullabilityCheck(LValue LHS, llvm::Value *RHS,
   // Check if the right hand side of the assignment is nonnull, if the left
   // hand side must be nonnull.
   auto CheckOrdinal = SanitizerKind::SO_NullabilityAssign;
-  SanitizerScope SanScope(this, {CheckOrdinal});
+  auto CheckHandler = SanitizerHandler::TypeMismatch;
+  SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
   llvm::Value *IsNotNull = Builder.CreateIsNotNull(RHS);
   llvm::Constant *StaticData[] = {
       EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(LHS.getType()),
       llvm::ConstantInt::get(Int8Ty, 0), // The LogAlignment info is unused.
       llvm::ConstantInt::get(Int8Ty, TCK_NonnullAssign)};
-  EmitCheck({{IsNotNull, CheckOrdinal}}, SanitizerHandler::TypeMismatch,
-            StaticData, RHS);
+  EmitCheck({{IsNotNull, CheckOrdinal}}, CheckHandler, StaticData, RHS);
 }
 
 void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
@@ -2853,7 +2853,8 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
   if (requiresReturnValueNullabilityCheck()) {
     auto Nullability = Ty->getNullability();
     if (Nullability && *Nullability == NullabilityKind::NonNull) {
-      SanitizerScope SanScope(this, {});
+      SanitizerScope SanScope(this, {},
+                              SanitizerHandler::AddOverflow /* Unused */);
       RetValNullabilityPrecondition =
           Builder.CreateAnd(RetValNullabilityPrecondition,
                             Builder.CreateIsNotNull(Arg.getAnyValue()));
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 4707211d46cb9..d47dca338bdde 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -748,9 +748,11 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
   if (Ty.isVolatileQualified())
     return;
 
-  SanitizerScope SanScope(
-      this, {SanitizerKind::SO_Null, SanitizerKind::SO_ObjectSize,
-             SanitizerKind::SO_Alignment, SanitizerKind::SO_Vptr});
+  auto CheckHandler = SanitizerHandler::TypeMismatch;
+  SanitizerScope SanScope(this,
+                          {SanitizerKind::SO_Null, SanitizerKind::SO_ObjectSize,
+                           SanitizerKind::SO_Alignment, SanitizerKind::SO_Vptr},
+                          CheckHandler);
 
   SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 3>
       Checks;
@@ -846,8 +848,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
         EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(Ty),
         llvm::ConstantInt::get(Int8Ty, AlignVal ? llvm::Log2(*AlignVal) : 1),
         llvm::ConstantInt::get(Int8Ty, TCK)};
-    EmitCheck(Checks, SanitizerHandler::TypeMismatch, StaticData,
-              PtrAsInt ? PtrAsInt : Ptr);
+    EmitCheck(Checks, CheckHandler, StaticData, PtrAsInt ? PtrAsInt : Ptr);
   }
 
   // If possible, check that the vptr indicates that there is a subobject of
@@ -991,7 +992,7 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
     if (CE->getCastKind() == CK_ArrayToPointerDecay &&
         !CE->getSubExpr()->isFlexibleArrayMemberLike(CGF.getContext(),
                                                      StrictFlexArraysLevel)) {
-      CodeGenFunction::SanitizerScope SanScope(&CGF, {});
+      CodeGenFunction::SanitizerScope SanScope(&CGF);
 
       IndexedType = CE->getSubExpr()->getType();
       const ArrayType *AT = IndexedType->castAsArrayTypeUnsafe();
@@ -1004,7 +1005,7 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
     }
   }
 
-  CodeGenFunction::SanitizerScope SanScope(&CGF, {});
+  CodeGenFunction::SanitizerScope SanScope(&CGF);
 
   QualType EltTy{Base->getType()->getPointeeOrArrayElementType(), 0};
   if (llvm::Value *POS = CGF.LoadPassedObjectSize(Base, EltTy)) {
@@ -1227,7 +1228,8 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
     return;
 
   auto CheckKind = SanitizerKind::SO_ArrayBounds;
-  SanitizerScope SanScope(this, {CheckKind});
+  auto CheckHandler = SanitizerHandler::OutOfBounds;
+  SanitizerScope SanScope(this, {CheckKind}, CheckHandler);
 
   bool IndexSigned = IndexType->isSignedIntegerOrEnumerationType();
   llvm::Value *IndexVal = Builder.CreateIntCast(Index, SizeTy, IndexSigned);
@@ -1240,25 +1242,33 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
   };
   llvm::Value *Check = Accessed ? Builder.CreateICmpULT(IndexVal, BoundVal)
                                 : Builder.CreateICmpULE(IndexVal, BoundVal);
-  EmitCheck(std::make_pair(Check, CheckKind), SanitizerHandler::OutOfBounds,
-            StaticData, Index);
+  EmitCheck(std::make_pair(Check, CheckKind), CheckHandler, StaticData, Index);
 }
 
 llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
-    ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals) {
+    ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+    SanitizerHandler Handler) {
+  std::string Label;
+  switch (Handler) {
+#define SANITIZER_CHECK(Enum, Name, Version)                                   \
+  case Enum:                                                                   \
+    Label = "__ubsan_check_" #Name;                                            \
+    break;
+
+    LIST_SANITIZER_CHECKS
+#undef SANITIZER_CHECK
+  };
+
   llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
 
-  // TODO: the annotation could be more precise:
-  // 1) use the ordinal name if there is only one ordinal; and/or,
-  // 2) use the overarching SanitizerHandler if there are multiple ordinals
-  //    (this may be confusing to users)
+  // TODO: the annotation could be more precise e.g.,
+  //       use the ordinal name if there is only one ordinal
   for (auto Ord : Ordinals) {
     // TODO: deprecate ClArrayBoundsPseudoFn
     if (((ClArrayBoundsPseudoFn && Ord == SanitizerKind::SO_ArrayBounds) ||
          CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo.has(Ord)) &&
         CheckDI) {
-      CheckDI = getDebugInfo()->CreateSyntheticInlineAt(
-          CheckDI, "__ubsan_check_debug_info_anchor");
+      CheckDI = getDebugInfo()->CreateSyntheticInlineAt(CheckDI, Label);
       break;
     }
   }
@@ -1991,7 +2001,8 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
       NeedsEnumCheck ? SanitizerKind::SO_Enum : SanitizerKind::SO_Bool;
 
   auto &Ctx = getLLVMContext();
-  SanitizerScope SanScope(this, {Kind});
+  auto CheckHandler = SanitizerHandler::LoadInvalidValue;
+  SanitizerScope SanScope(this, {Kind}, CheckHandler);
   llvm::Value *Check;
   --End;
   if (!Min) {
@@ -2005,8 +2016,7 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
   }
   llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc),
                                   EmitCheckTypeDescriptor(Ty)};
-  EmitCheck(std::make_pair(Check, Kind), SanitizerHandler::LoadInvalidValue,
-            StaticArgs, Value);
+  EmitCheck(std::make_pair(Check, Kind), CheckHandler, StaticArgs, Value);
   return true;
 }
 
@@ -3925,14 +3935,17 @@ void CodeGenFunction::EmitCfiCheckStub() {
 // can be nullptr if the calling module has -fsanitize-trap behavior for this
 // check kind; in this case __cfi_check_fail traps as well.
 void CodeGenFunction::EmitCfiCheckFail() {
+  auto CheckHandler = SanitizerHandler::CFICheckFail;
   // TODO: the SanitizerKind is not yet determined for this check (and might
   // not even be available, if Data == nullptr). However, we still want to
   // annotate the instrumentation. We approximate this by using all the CFI
   // kinds.
   SanitizerScope SanScope(
-      this, {SanitizerKind::SO_CFIVCall, SanitizerKind::SO_CFINVCall,
-             SanitizerKind::SO_CFIDerivedCast,
-             SanitizerKind::SO_CFIUnrelatedCast, SanitizerKind::SO_CFIICall});
+      this,
+      {SanitizerKind::SO_CFIVCall, SanitizerKind::SO_CFINVCall,
+       SanitizerKind::SO_CFIDerivedCast, SanitizerKind::SO_CFIUnrelatedCast,
+       SanitizerKind::SO_CFIICall},
+      CheckHandler);
   FunctionArgList Args;
   ImplicitParamDecl ArgData(getContext(), getContext().VoidPtrTy,
                             ImplicitParamKind::Other);
@@ -4019,7 +4032,7 @@ void CodeGenFunction::EmitCfiCheckFail() {
       // Although the compiler allows SanitizeMergeHandlers to be set
       // independently of CGM.getLangOpts().Sanitize, Driver/SanitizerArgs.cpp
       // requires that SanitizeMergeHandlers is a subset of Sanitize.
-      EmitTrapCheck(Cond, SanitizerHandler::CFICheckFail, /*NoMerge=*/false);
+      EmitTrapCheck(Cond, CheckHandler, /*NoMerge=*/false);
   }
 
   FinishFunction();
@@ -4031,11 +4044,11 @@ void CodeGenFunction::EmitCfiCheckFail() {
 void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
   if (SanOpts.has(SanitizerKind::Unreachable)) {
     auto CheckOrdinal = SanitizerKind::SO_Unreachable;
-    SanitizerScope SanScope(this, {CheckOrdinal});
+    auto CheckHandler = SanitizerHandler::BuiltinUnreachable;
+    SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
     EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
                              CheckOrdinal),
-              SanitizerHandler::BuiltinUnreachable,
-              EmitCheckSourceLocation(Loc), {});
+              CheckHandler, EmitCheckSourceLocation(Loc), {});
   }
   Builder.CreateUnreachable();
 }
@@ -6273,7 +6286,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
     if (llvm::Constant *PrefixSig =
             CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
       auto CheckOrdinal = SanitizerKind::SO_Function;
-      SanitizerScope SanScope(this, {CheckOrdinal});
+      auto CheckHandler = SanitizerHandler::FunctionTypeMismatch;
+      SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
       auto *TypeHash = getUBSanFunctionTypeHash(PointeeType);
 
       llvm::Type *PrefixSigType = PrefixSig->getType();
@@ -6333,9 +6347,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
           Builder.CreateICmpEQ(CalleeTypeHash, TypeHash);
       llvm::Constant *StaticData[] = {EmitCheckSourceLocation(E->getBeginLoc()),
                                       EmitCheckTypeDescriptor(CalleeType)};
-      EmitCheck(std::make_pair(CalleeTypeHashMatch, CheckOrdinal),
-                SanitizerHandler::FunctionTypeMismatch, StaticData,
-                {CalleePtr});
+      EmitCheck(std::make_pair(CalleeTypeHashMatch, CheckOrdinal), CheckHandler,
+                StaticData, {CalleePtr});
 
       Builder.CreateBr(Cont);
       EmitBlock(Cont);
@@ -6353,7 +6366,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
   if (SanOpts.has(SanitizerKind::CFIICall) &&
       (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
     auto CheckOrdinal = SanitizerKind::SO_CFIICall;
-    SanitizerScope SanScope(this, {CheckOrdinal});
+    auto CheckHandler = SanitizerHandler::CFICheckFail;
+    SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
     EmitSanitizerStatReport(llvm::SanStat_CFI_ICall);
 
     llvm::Metadata *MD;
@@ -6378,9 +6392,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
       EmitCfiSlowPathCheck(CheckOrdinal, TypeTest, CrossDsoTypeId, CalleePtr,
                            StaticData);
     } else {
-      EmitCheck(std::make_pair(TypeTest, CheckOrdinal),
-                SanitizerHandler::CFICheckFail, StaticData,
-                {CalleePtr, llvm::UndefValue::get(IntPtrTy)});
+      EmitCheck(std::make_pair(TypeTest, CheckOrdinal), CheckHandler,
+                StaticData, {CalleePtr, llvm::UndefValue::get(IntPtrTy)});
     }
   }
 
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index d9811bd9c8f6a..0dcd17adb7be5 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -1000,7 +1000,8 @@ void ScalarExprEmitter::EmitFloatConversionCheck(
     return;
 
   auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
-  CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal});
+  auto CheckHandler = SanitizerHandler::FloatCastOverflow;
+  CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal}, CheckHandler);
   using llvm::APFloat;
   using llvm::APSInt;
 
@@ -1057,8 +1058,8 @@ void ScalarExprEmitter::EmitFloatConversionCheck(
   llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc),
                                   CGF.EmitCheckTypeDescriptor(OrigSrcType),
                                   CGF.EmitCheckTypeDescriptor(DstType)};
-  CGF.EmitCheck(std::make_pair(Check, CheckOrdinal),
-                SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
+  CGF.EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
+                OrigSrc);
 }
 
 // Should be called within CodeGenFunction::SanitizerScope RAII scope.
@@ -1139,13 +1140,16 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
             std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
       Check;
 
+  auto CheckHandler = SanitizerHandler::ImplicitConversion;
   {
     // We don't know the check kind until we call
     // EmitIntegerTruncationCheckHelper, but we want to annotate
     // EmitIntegerTruncationCheckHelper's instructions too.
     CodeGenFunction::SanitizerScope SanScope(
-        &CGF, {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
-               SanitizerKind::SO_ImplicitSignedIntegerTruncation});
+        &CGF,
+        {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
+         SanitizerKind::SO_ImplicitSignedIntegerTruncation},
+        CheckHandler);
     Check =
         EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
     // If the comparison result is 'i1 false', then the truncation was lossy.
@@ -1155,7 +1159,8 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
   if (!CGF.SanOpts.has(Check.second.second))
     return;
 
-  CodeGenFunction::SanitizerScope SanScope(&CGF, {Check.second.second});
+  CodeGenFunction::SanitizerScope SanScope(&CGF, {Check.second.second},
+                                           CheckHandler);
 
   // Does some SSCL ignore this type?
   if (CGF.getContext().isTypeIgnoredBySanitizer(
@@ -1168,8 +1173,7 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
       llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
       llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
 
-  CGF.EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
-                {Src, Dst});
+  CGF.EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
 }
 
 static llvm::Value *EmitIsNegativeTestHelper(Value *V, QualType VType,
@@ -1283,10 +1287,13 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
     return;
   // That's it. We can't rule out any more cases with the data we have.
 
+  auto CheckHandler = SanitizerHandler::ImplicitConversion;
   CodeGenFunction::SanitizerScope SanScope(
-      &CGF, {SanitizerKind::SO_ImplicitIntegerSignChange,
-             SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
-             SanitizerKind::SO_ImplicitSignedIntegerTruncation});
+      &CGF,
+      {SanitizerKind::SO_ImplicitIntegerSignChange,
+       SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
+       SanitizerKind::SO_ImplicitSignedIntegerTruncation},
+      CheckHandler);
 
   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
             std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
@@ -1322,8 +1329,7 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
       llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
       llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
   // EmitCheck() will 'and' all the checks together.
-  CGF.EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
-                {Src, Dst});
+  CGF.EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
 }
 
 // Should be called within CodeGenFunction::SanitizerScope RAII scope.
@@ -1407,8 +1413,9 @@ void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType,
   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
 
+  auto CheckHandler = SanitizerHandler::ImplicitConversion;
   CodeGenFunction::SanitizerScope SanScope(
-      this, {SanitizerKind::SO_ImplicitBitfieldConversion});
+      this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
 
   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
             std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
@@ -1454,8 +1461,7 @@ void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType,
       llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
       llvm::ConstantInt::get(Builder.getInt32Ty(), Info.Size)};
 
-  EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
-            {Src, Dst});
+  EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
 }
 
 Value *ScalarExprEmitter::EmitScalarCast(Value *Src, QualType SrcType,
@@ -3991,9 +3997,11 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
 Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
   {
     CodeGenFunction::SanitizerScope SanScope(
-        &CGF, {SanitizerKind::SO_IntegerDivideByZero,
-               SanitizerKind::SO_SignedIntegerOverflow,
-               SanitizerKind::SO_FloatDivideByZero});
+        &CGF,
+        {SanitizerKind::SO_IntegerDivideByZero,
+         SanitizerKind::SO_SignedIntegerOverflow,
+         SanitizerKind::SO_FloatDivideByZero},
+        SanitizerHandler::DivremOverflow);
     if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
          CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
         Ops.Ty->isIntegerType() &&
@@ -4048,8 +4056,10 @@ Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
       Ops.Ty->isIntegerType() &&
       (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
     CodeGenFunction::SanitizerScope SanScope(
-        &CGF, {SanitizerKind::SO_IntegerDivideByZero,
-               SanitizerKind::SO_SignedIntegerOverflow});
+        &CGF,
+        {SanitizerKind::SO_IntegerDivideByZero,
+         SanitizerKind::SO_SignedIntegerOverflow},
+        SanitizerHandler::DivremOverflow);
     llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
     EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
   }
@@ -4099,8 +4109,10 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
     OpID |= 1;
 
   CodeGenFunction::SanitizerScope SanScope(
-      &CGF, {SanitizerKind::SO_SignedIntegerOverflow,
-             SanitizerKind::SO_UnsignedIntegerOverflow});
+      &CGF,
+      {SanitizerKind::SO_SignedIntegerOverflow,
+       SanitizerKind::SO_UnsignedIntegerOverflow},
+      OverflowKind);
   llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
 
   llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
@@ -4226,8 +4238,9 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
                              PtrTy->getPointerAddressSpace()))
       return Ptr;
     // The inbounds GEP of null is valid iff the index is zero.
+    auto CheckHandler = SanitizerHandler::PointerOverflow;
     CodeGenFunction::SanitizerScope SanScope(
-        &CGF, {SanitizerKind::SO_PointerOverflow});
+        &CGF, {SanitizerKind::SO_PointerOverflow}, CheckHandler);
     Value *IsZeroIndex = CGF.Builder.CreateIsNull(index);
     llvm::Constant *StaticArgs[] = {
         CGF.EmitCheckSourceLocation(op.E->getExprLoc())};
@@ -4236,7 +4249,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
     Value *ComputedGEP = CGF.Builder.CreateZExtOrTrunc(index, IntPtrTy);
     Value *DynamicArgs[] = {IntPtr, ComputedGEP};
     CGF.EmitCheck({{IsZeroIndex, SanitizerKind::SO_PointerOverflow}},
-                  SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
+                  CheckHandler, StaticArgs, DynamicArgs);
     return Ptr;
   }
 
@@ -4765,7 +4778,8 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
     if (SanitizeExponent)
       Kinds.push_back(SanitizerKind::SO_ShiftExponent);
 
-    CodeGenFunction::SanitizerScope SanScope(&CGF, Kinds);
+    CodeGenFunction::SanitizerScope SanScope(
+        &CGF, Kinds, SanitizerHandler::ShiftOutOfBounds);
     SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
     bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
     llvm::Value *WidthMinusOne =
@@ -4836,8 +4850,9 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
     RHS = ConstrainShiftValue(Ops.LHS, RHS, "shr.mask");
   else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) &&
            isa<llvm::IntegerType>(Ops.LHS->getType())) {
-    CodeGenFunction::SanitizerScope SanScope(&CGF,
-                                             {SanitizerKind::SO_ShiftExponent});
+    CodeGenFunction::SanitizerScope SanScope(
+        &CGF, {SanitizerKind::SO_ShiftExponent},
+        SanitizerHandler::ShiftOutOfBounds);
     bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
     llvm::Value *Valid = Builder.CreateICmpULE(
         Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
@@ -6069,7 +6084,9 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
 
   const auto &DL = CGM.getDataLayout();
 
-  SanitizerScope SanScope(this, {SanitizerKind::SO_PointerOverflow});
+  auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
+  auto CheckHandler = SanitizerHandler::PointerOverflow;
+  SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
   llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
 
   GEPOffsetAndOverflow EvaluatedGEP =
@@ -6106,7 +6123,7 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
     auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
     auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
     auto *Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
-    Checks.emplace_back(Valid, SanitizerKind::SO_PointerOverflow);
+    Checks.emplace_back(Valid, CheckOrdinal);
   }
 
   if (PerformOverflowCheck) {
@@ -6142,7 +6159,7 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
       ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
     }
     ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
-    Checks.emplace_back(ValidGEP, SanitizerKind::SO_PointerOverflow);
+    Checks.emplace_back(ValidGEP, CheckOrdinal);
   }
 
   assert(!Checks.empty() && "Should have produced some checks.");
@@ -6150,7 +6167,7 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
   llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
   // Pass the computed GEP to the runtime to avoid emitting poisoned arguments.
   llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
-  EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
+  EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
 
   return GEPVal;
 }
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 1c85d02479fe0..1693d85c27429 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1968,7 +1968,8 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
         ObjPtrTy ? ObjPtrTy->getInterfaceType() : nullptr;
     if (InterfaceTy) {
       auto CheckOrdinal = SanitizerKind::SO_ObjCCast;
-      SanitizerScope SanScope(this, {CheckOrdinal});
+      auto CheckHandler = SanitizerHandler::InvalidObjCCast;
+      SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
       auto &C = CGM.getContext();
       assert(InterfaceTy->getDecl() && "No decl for ObjC interface type");
       Selector IsKindOfClassSel = GetUnarySelector("isKindOfClass", C);
@@ -1985,7 +1986,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
       llvm::Constant *StaticData[] = {
           EmitCheckSourceLocation(S.getBeginLoc()),
           EmitCheckTypeDescriptor(QualType(InterfaceTy, 0))};
-      EmitCheck({{IsClass, CheckOrdinal}}, SanitizerHandler::InvalidObjCCast,
+      EmitCheck({{IsClass, CheckOrdinal}}, CheckHandler,
                 ArrayRef<llvm::Constant *>(StaticData), CurrentItem);
     }
   }
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index a661bd51cab08..ac10647b1992a 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1633,10 +1633,10 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
         !CGM.MayDropFunctionReturn(FD->getASTContext(), FD->getReturnType());
     if (SanOpts.has(SanitizerKind::Return)) {
       auto CheckOrdinal = SanitizerKind::SO_Return;
-      SanitizerScope SanScope(this, {CheckOrdinal});
+      auto CheckHandler = SanitizerHandler::MissingReturn;
+      SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
       llvm::Value *IsFalse = Builder.getFalse();
-      EmitCheck(std::make_pair(IsFalse, CheckOrdinal),
-                SanitizerHandler::MissingReturn,
+      EmitCheck(std::make_pair(IsFalse, CheckOrdinal), CheckHandler,
                 EmitCheckSourceLocation(FD->getLocation()), {});
     } else if (ShouldEmitUnreachable) {
       if (CGM.getCodeGenOpts().OptimizationLevel == 0)
@@ -2539,7 +2539,8 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
           //   greater than zero.
           if (SanOpts.has(SanitizerKind::VLABound)) {
             auto CheckOrdinal = SanitizerKind::SO_VLABound;
-            SanitizerScope SanScope(this, {CheckOrdinal});
+            auto CheckHandler = SanitizerHandler::VLABoundNotPositive;
+            SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
             llvm::Value *Zero = llvm::Constant::getNullValue(size->getType());
             clang::QualType SEType = sizeExpr->getType();
             llvm::Value *CheckCondition =
@@ -2550,7 +2551,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
                 EmitCheckSourceLocation(sizeExpr->getBeginLoc()),
                 EmitCheckTypeDescriptor(SEType)};
             EmitCheck(std::make_pair(CheckCondition, CheckOrdinal),
-                      SanitizerHandler::VLABoundNotPositive, StaticArgs, size);
+                      CheckHandler, StaticArgs, size);
           }
 
           // Always zexting here would be wrong if it weren't
@@ -2753,15 +2754,20 @@ Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
 
 CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { }
 
-CodeGenFunction::SanitizerScope::SanitizerScope(
-    CodeGenFunction *CGF, ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals)
+CodeGenFunction::SanitizerScope::SanitizerScope(CodeGenFunction *CGF)
     : CGF(CGF) {
   assert(!CGF->IsSanitizerScope);
   CGF->IsSanitizerScope = true;
 
   assert(!this->ApplyTrapDI);
-  this->ApplyTrapDI =
-      new ApplyDebugLocation(*CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals));
+}
+
+CodeGenFunction::SanitizerScope::SanitizerScope(
+    CodeGenFunction *CGF, ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+    SanitizerHandler Handler)
+    : SanitizerScope(CGF) {
+  this->ApplyTrapDI = new ApplyDebugLocation(
+      *CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler));
 }
 
 CodeGenFunction::SanitizerScope::~SanitizerScope() {
@@ -3202,7 +3208,8 @@ void CodeGenFunction::emitAlignmentAssumptionCheck(
 
   {
     auto CheckOrdinal = SanitizerKind::SO_Alignment;
-    SanitizerScope SanScope(this, {CheckOrdinal});
+    auto CheckHandler = SanitizerHandler::AlignmentAssumption;
+    SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
 
     if (!OffsetValue)
       OffsetValue = Builder.getInt1(false); // no offset.
@@ -3211,8 +3218,8 @@ void CodeGenFunction::emitAlignmentAssumptionCheck(
                                     EmitCheckSourceLocation(SecondaryLoc),
                                     EmitCheckTypeDescriptor(Ty)};
     llvm::Value *DynamicData[] = {Ptr, Alignment, OffsetValue};
-    EmitCheck({std::make_pair(TheCheck, CheckOrdinal)},
-              SanitizerHandler::AlignmentAssumption, StaticData, DynamicData);
+    EmitCheck({std::make_pair(TheCheck, CheckOrdinal)}, CheckHandler,
+              StaticData, DynamicData);
   }
 
   // We are now in the (new, empty) "cont" basic block.
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index c6c9bce596e17..f0eafe2c8304c 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -602,8 +602,10 @@ class CodeGenFunction : public CodeGenTypeCache {
     void *ApplyTrapDI = nullptr;
 
   public:
+    SanitizerScope(CodeGenFunction *CGF);
     SanitizerScope(CodeGenFunction *CGF,
-                   ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals);
+                   ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+                   SanitizerHandler Handler);
     ~SanitizerScope();
   };
 
@@ -3398,8 +3400,9 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// Returns debug info, with additional annotation if
   /// CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[Ordinal] is enabled for
   /// any of the ordinals.
-  llvm::DILocation *SanitizerAnnotateDebugInfo(
-      ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals);
+  llvm::DILocation *
+  SanitizerAnnotateDebugInfo(ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+                             SanitizerHandler Handler);
 
   llvm::Value *GetCountedByFieldExprGEP(const Expr *Base, const FieldDecl *FD,
                                         const FieldDecl *CountDecl);
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 32e2b0ae0b723..fb379807bffa5 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -703,7 +703,9 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
 
   {
     auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
-    CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal});
+    auto CheckHandler = SanitizerHandler::CFICheckFail;
+    CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal},
+                                             CheckHandler);
 
     llvm::Value *TypeId = nullptr;
     llvm::Value *CheckResult = nullptr;
@@ -773,16 +775,15 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
       };
 
       if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
-        CGF.EmitTrapCheck(CheckResult, SanitizerHandler::CFICheckFail);
+        CGF.EmitTrapCheck(CheckResult, CheckHandler);
       } else {
         llvm::Value *AllVtables = llvm::MetadataAsValue::get(
             CGM.getLLVMContext(),
             llvm::MDString::get(CGM.getLLVMContext(), "all-vtables"));
         llvm::Value *ValidVtable = Builder.CreateCall(
             CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
-        CGF.EmitCheck(std::make_pair(CheckResult, CheckOrdinal),
-                      SanitizerHandler::CFICheckFail, StaticData,
-                      {VTable, ValidVtable});
+        CGF.EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler,
+                      StaticData, {VTable, ValidVtable});
       }
 
       FnVirtual = Builder.GetInsertBlock();
@@ -802,7 +803,9 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
     CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
     if (RD->hasDefinition()) {
       auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
-      CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal});
+      auto CheckHandler = SanitizerHandler::CFICheckFail;
+      CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal},
+                                               CheckHandler);
 
       llvm::Constant *StaticData[] = {
           llvm::ConstantInt::get(CGF.Int8Ty, CodeGenFunction::CFITCK_NVMFCall),
@@ -825,8 +828,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
         Bit = Builder.CreateOr(Bit, TypeTest);
       }
 
-      CGF.EmitCheck(std::make_pair(Bit, CheckOrdinal),
-                    SanitizerHandler::CFICheckFail, StaticData,
+      CGF.EmitCheck(std::make_pair(Bit, CheckOrdinal), CheckHandler, StaticData,
                     {NonVirtualFn, llvm::UndefValue::get(CGF.IntPtrTy)});
 
       FnNonVirtual = Builder.GetInsertBlock();
diff --git a/clang/test/CodeGen/bounds-checking-debuginfo.c b/clang/test/CodeGen/bounds-checking-debuginfo.c
index c851ff23e0032..31050f247fb2b 100644
--- a/clang/test/CodeGen/bounds-checking-debuginfo.c
+++ b/clang/test/CodeGen/bounds-checking-debuginfo.c
@@ -89,7 +89,7 @@ double f1(int b, int i) {
 // CHECK-TRAP: [[DBG21]] = !DILocation(line: 65, column: 3, scope: [[DBG4]])
 // CHECK-TRAP: [[DBG22]] = !DILocation(line: 66, column: 12, scope: [[DBG4]])
 // CHECK-TRAP: [[DBG23]] = !DILocation(line: 0, scope: [[META24:![0-9]+]], inlinedAt: [[DBG26]])
-// CHECK-TRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK-TRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_out_of_bounds", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK-TRAP: [[META25]] = !DISubroutineType(types: null)
 // CHECK-TRAP: [[DBG26]] = !DILocation(line: 66, column: 10, scope: [[DBG4]])
 // CHECK-TRAP: [[PROF27]] = !{!"branch_weights", i32 1048575, i32 1}
@@ -117,7 +117,7 @@ double f1(int b, int i) {
 // CHECK-NOTRAP: [[DBG21]] = !DILocation(line: 65, column: 3, scope: [[DBG4]])
 // CHECK-NOTRAP: [[DBG22]] = !DILocation(line: 66, column: 12, scope: [[DBG4]])
 // CHECK-NOTRAP: [[DBG23]] = !DILocation(line: 0, scope: [[META24:![0-9]+]], inlinedAt: [[DBG26]])
-// CHECK-NOTRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK-NOTRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_out_of_bounds", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK-NOTRAP: [[META25]] = !DISubroutineType(types: null)
 // CHECK-NOTRAP: [[DBG26]] = !DILocation(line: 66, column: 10, scope: [[DBG4]])
 // CHECK-NOTRAP: [[PROF27]] = !{!"branch_weights", i32 1048575, i32 1}
diff --git a/clang/test/CodeGen/cfi-check-fail-debuginfo.c b/clang/test/CodeGen/cfi-check-fail-debuginfo.c
index 4725110a49d8b..bade8071d8ed3 100644
--- a/clang/test/CodeGen/cfi-check-fail-debuginfo.c
+++ b/clang/test/CodeGen/cfi-check-fail-debuginfo.c
@@ -39,7 +39,7 @@ void caller(void (*f)(void)) {
 // CHECK: [[META18]] = !{i64 0, i64 2451761621477796417}
 // CHECK: [[META19]] = !DILocation(line: 0, scope: [[DBG7]])
 // CHECK: [[DBG20]] = !DILocation(line: 0, scope: [[META21:![0-9]+]], inlinedAt: [[DBG23]])
-// CHECK: [[META21]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META8]], file: [[META8]], type: [[META22:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[META21]] = distinct !DISubprogram(name: "__ubsan_check_cfi_check_fail", scope: [[META8]], file: [[META8]], type: [[META22:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META22]] = !DISubroutineType(types: null)
 // CHECK: [[DBG23]] = !DILocation(line: 23, column: 3, scope: [[DBG7]])
 // CHECK: [[META24]] = !{}
diff --git a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
index 903bc7b730aa5..4d446b8a64f67 100644
--- a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
+++ b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
@@ -85,7 +85,7 @@ void g(int** (*fp)(const char *, const char **)) {
 // UNGENERALIZED: [[META32]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // UNGENERALIZED: [[META33]] = !DILocation(line: 0, scope: [[DBG25]])
 // UNGENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[DBG37]])
-// UNGENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// UNGENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_cfi_check_fail", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // UNGENERALIZED: [[META36]] = !DISubroutineType(types: null)
 // UNGENERALIZED: [[DBG37]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
 // UNGENERALIZED: [[META38]] = !{}
@@ -123,7 +123,7 @@ void g(int** (*fp)(const char *, const char **)) {
 // GENERALIZED: [[META32]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // GENERALIZED: [[META33]] = !DILocation(line: 0, scope: [[DBG25]])
 // GENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[DBG37]])
-// GENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// GENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_cfi_check_fail", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // GENERALIZED: [[META36]] = !DISubroutineType(types: null)
 // GENERALIZED: [[DBG37]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
 // GENERALIZED: [[META38]] = !{}
diff --git a/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c b/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
index b71cec8a4d2bb..dde4ad2024b9b 100644
--- a/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
+++ b/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
@@ -82,7 +82,7 @@ void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) {
 // CHECK: [[META19]] = !{i64 0, !"_ZTSFvPvu3i32E.normalized.generalized"}
 // CHECK: [[META20]] = !DILocation(line: 0, scope: [[DBG7]])
 // CHECK: [[DBG21]] = !DILocation(line: 0, scope: [[META22:![0-9]+]], inlinedAt: [[DBG24]])
-// CHECK: [[META22]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META8]], file: [[META8]], type: [[META23:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[META22]] = distinct !DISubprogram(name: "__ubsan_check_cfi_check_fail", scope: [[META8]], file: [[META8]], type: [[META23:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META23]] = !DISubroutineType(types: null)
 // CHECK: [[DBG24]] = !DILocation(line: 25, column: 5, scope: [[DBG7]])
 // CHECK: [[META25]] = !{}
diff --git a/clang/test/CodeGen/ubsan-function-debuginfo.c b/clang/test/CodeGen/ubsan-function-debuginfo.c
index 84da58038aa3f..48619dcbf851e 100644
--- a/clang/test/CodeGen/ubsan-function-debuginfo.c
+++ b/clang/test/CodeGen/ubsan-function-debuginfo.c
@@ -62,7 +62,7 @@ void call_prototype(void (*f)(void)) { f(); }
 // CHECK: [[META26]] = !{i32 -1056584962, i32 -747727454}
 // CHECK: [[META27]] = !DILocation(line: 0, scope: [[DBG18]])
 // CHECK: [[DBG28]] = !DILocation(line: 0, scope: [[META29:![0-9]+]], inlinedAt: [[DBG31]])
-// CHECK: [[META29]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META6]], file: [[META6]], type: [[META30:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[META29]] = distinct !DISubprogram(name: "__ubsan_check_function_type_mismatch", scope: [[META6]], file: [[META6]], type: [[META30:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META30]] = !DISubroutineType(types: null)
 // CHECK: [[DBG31]] = !DILocation(line: 37, column: 40, scope: [[DBG18]])
 // CHECK: [[META32]] = !{}
diff --git a/clang/test/CodeGen/unsigned-promotion-debuginfo.c b/clang/test/CodeGen/unsigned-promotion-debuginfo.c
index 3c0016104ac93..88e691d65334c 100644
--- a/clang/test/CodeGen/unsigned-promotion-debuginfo.c
+++ b/clang/test/CodeGen/unsigned-promotion-debuginfo.c
@@ -68,7 +68,7 @@ void testshortmul(void) {
 // CHECKS: [[META20]] = !{!"Simple C/C++ TBAA"}
 // CHECKS: [[DBG21]] = !DILocation(line: 47, column: 13, scope: [[DBG13]])
 // CHECKS: [[DBG22]] = !DILocation(line: 0, scope: [[META23:![0-9]+]], inlinedAt: [[META25:![0-9]+]])
-// CHECKS: [[META23]] = distinct !DISubprogram(name: "__ubsan_check_debug_info_anchor", scope: [[META7]], file: [[META7]], type: [[META24:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META2]])
+// CHECKS: [[META23]] = distinct !DISubprogram(name: "__ubsan_check_mul_overflow", scope: [[META7]], file: [[META7]], type: [[META24:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META2]])
 // CHECKS: [[META24]] = !DISubroutineType(types: null)
 // CHECKS: [[META25]] = !DILocation(line: 47, column: 11, scope: [[DBG13]])
 // CHECKS: [[META26]] = !{}

>From 05d047b3dda708fcbfaa62afff797671ff79386c Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Mon, 2 Jun 2025 21:48:14 +0000
Subject: [PATCH 12/26] Simplify no-handler case

---
 clang/lib/CodeGen/CGDecl.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index aaa6fd479cadf..a99f0ecde8e33 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -2853,8 +2853,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
   if (requiresReturnValueNullabilityCheck()) {
     auto Nullability = Ty->getNullability();
     if (Nullability && *Nullability == NullabilityKind::NonNull) {
-      SanitizerScope SanScope(this, {},
-                              SanitizerHandler::AddOverflow /* Unused */);
+      SanitizerScope SanScope(this);
       RetValNullabilityPrecondition =
           Builder.CreateAnd(RetValNullabilityPrecondition,
                             Builder.CreateIsNotNull(Arg.getAnyValue()));

>From 827dcbd9cf1284b88f5f54494a9deced4f250075 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Mon, 2 Jun 2025 22:00:04 +0000
Subject: [PATCH 13/26] Add note about SO_Vptr ambiguity

---
 clang/lib/CodeGen/CGExpr.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d47dca338bdde..8722c65fa8ec2 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -749,6 +749,9 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
     return;
 
   auto CheckHandler = SanitizerHandler::TypeMismatch;
+  // SO_Vptr's corresponding handler is DynamicTypeCacheMiss, not TypeMismatch.
+  // However, it relies upon IsGuaranteedNonNull, hence the instructions cannot
+  // be fully separated from the TypeMismatch.
   SanitizerScope SanScope(this,
                           {SanitizerKind::SO_Null, SanitizerKind::SO_ObjectSize,
                            SanitizerKind::SO_Alignment, SanitizerKind::SO_Vptr},

>From 2a816fe9d18f8e024a3d02ba15eb0e1827a1e980 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Mon, 2 Jun 2025 22:38:39 +0000
Subject: [PATCH 14/26] Florian1 feedback

---
 clang/lib/CodeGen/CGExprScalar.cpp    | 19 ++++++++++---------
 clang/lib/CodeGen/CodeGenFunction.cpp | 10 +++-------
 clang/lib/CodeGen/CodeGenFunction.h   |  8 +++++---
 3 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 0dcd17adb7be5..f9f6efb4c9747 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -4238,9 +4238,10 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
                              PtrTy->getPointerAddressSpace()))
       return Ptr;
     // The inbounds GEP of null is valid iff the index is zero.
+    auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
     auto CheckHandler = SanitizerHandler::PointerOverflow;
-    CodeGenFunction::SanitizerScope SanScope(
-        &CGF, {SanitizerKind::SO_PointerOverflow}, CheckHandler);
+    CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal},
+                                             CheckHandler);
     Value *IsZeroIndex = CGF.Builder.CreateIsNull(index);
     llvm::Constant *StaticArgs[] = {
         CGF.EmitCheckSourceLocation(op.E->getExprLoc())};
@@ -4248,8 +4249,8 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
     Value *IntPtr = llvm::Constant::getNullValue(IntPtrTy);
     Value *ComputedGEP = CGF.Builder.CreateZExtOrTrunc(index, IntPtrTy);
     Value *DynamicArgs[] = {IntPtr, ComputedGEP};
-    CGF.EmitCheck({{IsZeroIndex, SanitizerKind::SO_PointerOverflow}},
-                  CheckHandler, StaticArgs, DynamicArgs);
+    CGF.EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
+                  DynamicArgs);
     return Ptr;
   }
 
@@ -4770,16 +4771,16 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
     RHS = ConstrainShiftValue(Ops.LHS, RHS, "shl.mask");
   else if ((SanitizeBase || SanitizeExponent) &&
            isa<llvm::IntegerType>(Ops.LHS->getType())) {
-    SmallVector<SanitizerKind::SanitizerOrdinal, 3> Kinds;
+    SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
     if (SanitizeSignedBase)
-      Kinds.push_back(SanitizerKind::SO_ShiftBase);
+      Ordinals.push_back(SanitizerKind::SO_ShiftBase);
     if (SanitizeUnsignedBase)
-      Kinds.push_back(SanitizerKind::SO_UnsignedShiftBase);
+      Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
     if (SanitizeExponent)
-      Kinds.push_back(SanitizerKind::SO_ShiftExponent);
+      Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
 
     CodeGenFunction::SanitizerScope SanScope(
-        &CGF, Kinds, SanitizerHandler::ShiftOutOfBounds);
+        &CGF, Ordinals, SanitizerHandler::ShiftOutOfBounds);
     SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
     bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
     llvm::Value *WidthMinusOne =
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index ac10647b1992a..a09c46b11398c 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2757,24 +2757,20 @@ CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { }
 CodeGenFunction::SanitizerScope::SanitizerScope(CodeGenFunction *CGF)
     : CGF(CGF) {
   assert(!CGF->IsSanitizerScope);
+  assert(!ApplyTrapDI);
   CGF->IsSanitizerScope = true;
-
-  assert(!this->ApplyTrapDI);
 }
 
 CodeGenFunction::SanitizerScope::SanitizerScope(
     CodeGenFunction *CGF, ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
     SanitizerHandler Handler)
     : SanitizerScope(CGF) {
-  this->ApplyTrapDI = new ApplyDebugLocation(
-      *CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler));
+  ApplyTrapDI = std::unique_ptr<ApplyDebugLocation>(new ApplyDebugLocation(
+      *CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler)));
 }
 
 CodeGenFunction::SanitizerScope::~SanitizerScope() {
   CGF->IsSanitizerScope = false;
-
-  delete ((ApplyDebugLocation *)this->ApplyTrapDI);
-  this->ApplyTrapDI = nullptr;
 }
 
 void CodeGenFunction::InsertHelper(llvm::Instruction *I,
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index f0eafe2c8304c..02a7f22147157 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -272,6 +272,10 @@ class ApplyAtomGroup {
   ~ApplyAtomGroup();
 };
 
+// CGDebugInfo.h is not #included in this header due to overhead
+// (b384d6d6ccc8f4452cd7086061c657ce76b41224)
+class ApplyDebugLocation;
+
 /// CodeGenFunction - This class organizes the per-function state that is used
 /// while generating LLVM code.
 class CodeGenFunction : public CodeGenTypeCache {
@@ -597,9 +601,7 @@ class CodeGenFunction : public CodeGenTypeCache {
   class SanitizerScope {
     CodeGenFunction *CGF;
 
-    // ApplyDebugLocation is undeclared: CGDebugInfo.h is not #included in this
-    // header due to overhead (b384d6d6ccc8f4452cd7086061c657ce76b41224)
-    void *ApplyTrapDI = nullptr;
+    std::unique_ptr<ApplyDebugLocation> ApplyTrapDI;
 
   public:
     SanitizerScope(CodeGenFunction *CGF);

>From ed2c9b5603750129a9cad1bfef50cd4459f94b99 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Mon, 2 Jun 2025 22:56:01 +0000
Subject: [PATCH 15/26] Use std::make_unique

---
 clang/lib/CodeGen/CodeGenFunction.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index a09c46b11398c..3b3484b33e496 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2765,8 +2765,8 @@ CodeGenFunction::SanitizerScope::SanitizerScope(
     CodeGenFunction *CGF, ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
     SanitizerHandler Handler)
     : SanitizerScope(CGF) {
-  ApplyTrapDI = std::unique_ptr<ApplyDebugLocation>(new ApplyDebugLocation(
-      *CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler)));
+  ApplyTrapDI = std::make_unique<ApplyDebugLocation>(
+      *CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler));
 }
 
 CodeGenFunction::SanitizerScope::~SanitizerScope() {

>From 16d6beef5b2e12cde5a350011800f905a1098d5a Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Mon, 2 Jun 2025 23:39:15 +0000
Subject: [PATCH 16/26] Remove useless assert

---
 clang/lib/CodeGen/CodeGenFunction.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 3b3484b33e496..a36afec498f26 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2757,7 +2757,6 @@ CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { }
 CodeGenFunction::SanitizerScope::SanitizerScope(CodeGenFunction *CGF)
     : CGF(CGF) {
   assert(!CGF->IsSanitizerScope);
-  assert(!ApplyTrapDI);
   CGF->IsSanitizerScope = true;
 }
 

>From 2eee78664b6d1eec10444e7e33c42d1c70da7a87 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Mon, 2 Jun 2025 22:45:01 -0700
Subject: [PATCH 17/26] SanitizerDebugLocation

---
 clang/lib/CodeGen/CGBuiltin.cpp       |  6 +--
 clang/lib/CodeGen/CGCall.cpp          |  4 +-
 clang/lib/CodeGen/CGClass.cpp         |  4 +-
 clang/lib/CodeGen/CGDebugInfo.cpp     | 51 +++++++++++++++++++++++
 clang/lib/CodeGen/CGDebugInfo.h       | 12 ++++++
 clang/lib/CodeGen/CGDecl.cpp          |  2 +-
 clang/lib/CodeGen/CGExpr.cpp          | 59 +++++----------------------
 clang/lib/CodeGen/CGExprScalar.cpp    | 54 +++++++++++-------------
 clang/lib/CodeGen/CGObjC.cpp          |  2 +-
 clang/lib/CodeGen/CodeGenFunction.cpp | 14 ++-----
 clang/lib/CodeGen/CodeGenFunction.h   | 44 +-------------------
 clang/lib/CodeGen/ItaniumCXXABI.cpp   |  6 +--
 clang/lib/CodeGen/SanitizerHandler.h  | 50 +++++++++++++++++++++++
 13 files changed, 163 insertions(+), 145 deletions(-)
 create mode 100644 clang/lib/CodeGen/SanitizerHandler.h

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 099158cc4ae84..31303cd8d777d 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2010,7 +2010,7 @@ Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
 
   auto CheckOrdinal = SanitizerKind::SO_Builtin;
   auto CheckHandler = SanitizerHandler::InvalidBuiltin;
-  SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+  SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
   Value *Cond = Builder.CreateICmpNE(
       ArgValue, llvm::Constant::getNullValue(ArgValue->getType()));
   EmitCheck(std::make_pair(Cond, CheckOrdinal), CheckHandler,
@@ -2027,7 +2027,7 @@ Value *CodeGenFunction::EmitCheckedArgForAssume(const Expr *E) {
 
   auto CheckOrdinal = SanitizerKind::SO_Builtin;
   auto CheckHandler = SanitizerHandler::InvalidBuiltin;
-  SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+  SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
   EmitCheck(
       std::make_pair(ArgValue, CheckOrdinal), CheckHandler,
       {EmitCheckSourceLocation(E->getExprLoc()),
@@ -2060,7 +2060,7 @@ static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E,
   } else
     CheckHandler = SanitizerHandler::SubOverflow;
 
-  CodeGenFunction::SanitizerScope SanScope(&CGF, Ordinals, CheckHandler);
+  SanitizerDebugLocation SanScope(&CGF, Ordinals, CheckHandler);
 
   Constant *Zero = Constant::getNullValue(ArgValue->getType());
   Value *ResultAndOverflow = CGF.Builder.CreateBinaryIntrinsic(
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 8db31eefd68f2..0a0b2bdf59ecd 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4157,7 +4157,7 @@ void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV) {
     Handler = SanitizerHandler::NullabilityReturn;
   }
 
-  SanitizerScope SanScope(this, {CheckKind}, Handler);
+  SanitizerDebugLocation SanScope(this, {CheckKind}, Handler);
 
   // Make sure the "return" source location is valid. If we're checking a
   // nullability annotation, make sure the preconditions for the check are met.
@@ -4542,7 +4542,7 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
     Handler = SanitizerHandler::NullabilityArg;
   }
 
-  SanitizerScope SanScope(this, {CheckKind}, Handler);
+  SanitizerDebugLocation SanScope(this, {CheckKind}, Handler);
   llvm::Value *Cond = EmitNonNullRValueCheck(RV, ArgType);
   llvm::Constant *StaticData[] = {
       EmitCheckSourceLocation(ArgLoc),
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index b2815b08a3968..e671fa38c1c9d 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2890,7 +2890,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
     return;
 
   auto CheckHandler = SanitizerHandler::CFICheckFail;
-  SanitizerScope SanScope(this, {M}, CheckHandler);
+  SanitizerDebugLocation SanScope(this, {M}, CheckHandler);
   EmitSanitizerStatReport(SSK);
 
   llvm::Metadata *MD =
@@ -2949,7 +2949,7 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
     uint64_t VTableByteOffset) {
   auto CheckOrdinal = SanitizerKind::SO_CFIVCall;
   auto CheckHandler = SanitizerHandler::CFICheckFail;
-  SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+  SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
 
   EmitSanitizerStatReport(llvm::SanStat_CFI_VCall);
 
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 7cb52597d9a00..30f63759e8cc6 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -58,6 +58,13 @@
 using namespace clang;
 using namespace clang::CodeGen;
 
+// TODO: consider deprecating ClArrayBoundsPseudoFn; functionality is subsumed
+//       by -fsanitize-annotate-debug-info
+static llvm::cl::opt<bool> ClArrayBoundsPseudoFn(
+    "array-bounds-pseudofn", llvm::cl::Hidden, llvm::cl::Optional,
+    llvm::cl::desc("Emit debug info that places array-bounds instrumentation "
+                   "in an inline function called __ubsan_check_array_bounds."));
+
 static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx) {
   auto TI = Ctx.getTypeInfo(Ty);
   if (TI.isAlignRequired())
@@ -6413,3 +6420,47 @@ CodeGenFunction::LexicalScope::~LexicalScope() {
     ForceCleanup();
   }
 }
+
+llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
+    ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+    SanitizerHandler Handler) {
+  std::string Label;
+  switch (Handler) {
+#define SANITIZER_CHECK(Enum, Name, Version)                                   \
+  case Enum:                                                                   \
+    Label = "__ubsan_check_" #Name;                                            \
+    break;
+
+    LIST_SANITIZER_CHECKS
+#undef SANITIZER_CHECK
+  };
+
+  llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
+
+  // TODO: the annotation could be more precise e.g.,
+  //       use the ordinal name if there is only one ordinal
+  for (auto Ord : Ordinals) {
+    // TODO: deprecate ClArrayBoundsPseudoFn
+    if (((ClArrayBoundsPseudoFn && Ord == SanitizerKind::SO_ArrayBounds) ||
+         CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo.has(Ord)) &&
+        CheckDI) {
+      return getDebugInfo()->CreateSyntheticInlineAt(CheckDI, Label);
+    }
+  }
+
+  return CheckDI;
+}
+
+SanitizerDebugLocation::SanitizerDebugLocation(
+    CodeGenFunction *CGF, ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+    SanitizerHandler Handler)
+    : CGF(CGF),
+      Apply(*CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler)) {
+  assert(!CGF->IsSanitizerScope);
+  CGF->IsSanitizerScope = true;
+}
+
+SanitizerDebugLocation::~SanitizerDebugLocation() {
+  assert(CGF->IsSanitizerScope);
+  CGF->IsSanitizerScope = false;
+}
\ No newline at end of file
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 855881744237c..16759f25123cd 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -14,6 +14,7 @@
 #define LLVM_CLANG_LIB_CODEGEN_CGDEBUGINFO_H
 
 #include "CGBuilder.h"
+#include "SanitizerHandler.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExternalASTSource.h"
@@ -974,6 +975,17 @@ class ApplyInlineDebugLocation {
   ~ApplyInlineDebugLocation();
 };
 
+class SanitizerDebugLocation {
+  CodeGenFunction *CGF;
+  ApplyDebugLocation Apply;
+
+public:
+  SanitizerDebugLocation(CodeGenFunction *CGF,
+                         ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+                         SanitizerHandler Handler);
+  ~SanitizerDebugLocation();
+};
+
 } // namespace CodeGen
 } // namespace clang
 
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index b14025b3b426f..04f13c7d7a6a3 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -768,7 +768,7 @@ void CodeGenFunction::EmitNullabilityCheck(LValue LHS, llvm::Value *RHS,
   // hand side must be nonnull.
   auto CheckOrdinal = SanitizerKind::SO_NullabilityAssign;
   auto CheckHandler = SanitizerHandler::TypeMismatch;
-  SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+  SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
   llvm::Value *IsNotNull = Builder.CreateIsNotNull(RHS);
   llvm::Constant *StaticData[] = {
       EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(LHS.getType()),
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 53c9c375535da..c8688e3b26d48 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -65,13 +65,6 @@ llvm::cl::opt<bool> ClSanitizeGuardChecks(
 
 } // namespace clang
 
-// TODO: consider deprecating ClArrayBoundsPseudoFn; functionality is subsumed
-//       by -fsanitize-annotate-debug-info
-static llvm::cl::opt<bool> ClArrayBoundsPseudoFn(
-    "array-bounds-pseudofn", llvm::cl::Hidden, llvm::cl::Optional,
-    llvm::cl::desc("Emit debug info that places array-bounds instrumentation "
-                   "in an inline function called __ubsan_check_array_bounds."));
-
 //===--------------------------------------------------------------------===//
 //                        Defines for metadata
 //===--------------------------------------------------------------------===//
@@ -755,10 +748,11 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
   // SO_Vptr's corresponding handler is DynamicTypeCacheMiss, not TypeMismatch.
   // However, it relies upon IsGuaranteedNonNull, hence the instructions cannot
   // be fully separated from the TypeMismatch.
-  SanitizerScope SanScope(this,
-                          {SanitizerKind::SO_Null, SanitizerKind::SO_ObjectSize,
-                           SanitizerKind::SO_Alignment, SanitizerKind::SO_Vptr},
-                          CheckHandler);
+  SanitizerDebugLocation SanScope(
+      this,
+      {SanitizerKind::SO_Null, SanitizerKind::SO_ObjectSize,
+       SanitizerKind::SO_Alignment, SanitizerKind::SO_Vptr},
+      CheckHandler);
 
   SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 3>
       Checks;
@@ -1235,7 +1229,7 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
 
   auto CheckKind = SanitizerKind::SO_ArrayBounds;
   auto CheckHandler = SanitizerHandler::OutOfBounds;
-  SanitizerScope SanScope(this, {CheckKind}, CheckHandler);
+  SanitizerDebugLocation SanScope(this, {CheckKind}, CheckHandler);
 
   bool IndexSigned = IndexType->isSignedIntegerOrEnumerationType();
   llvm::Value *IndexVal = Builder.CreateIntCast(Index, SizeTy, IndexSigned);
@@ -1251,37 +1245,6 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
   EmitCheck(std::make_pair(Check, CheckKind), CheckHandler, StaticData, Index);
 }
 
-llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
-    ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
-    SanitizerHandler Handler) {
-  std::string Label;
-  switch (Handler) {
-#define SANITIZER_CHECK(Enum, Name, Version)                                   \
-  case Enum:                                                                   \
-    Label = "__ubsan_check_" #Name;                                            \
-    break;
-
-    LIST_SANITIZER_CHECKS
-#undef SANITIZER_CHECK
-  };
-
-  llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
-
-  // TODO: the annotation could be more precise e.g.,
-  //       use the ordinal name if there is only one ordinal
-  for (auto Ord : Ordinals) {
-    // TODO: deprecate ClArrayBoundsPseudoFn
-    if (((ClArrayBoundsPseudoFn && Ord == SanitizerKind::SO_ArrayBounds) ||
-         CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo.has(Ord)) &&
-        CheckDI) {
-      CheckDI = getDebugInfo()->CreateSyntheticInlineAt(CheckDI, Label);
-      break;
-    }
-  }
-
-  return CheckDI;
-}
-
 CodeGenFunction::ComplexPairTy CodeGenFunction::
 EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
                          bool isInc, bool isPre) {
@@ -2008,7 +1971,7 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
 
   auto &Ctx = getLLVMContext();
   auto CheckHandler = SanitizerHandler::LoadInvalidValue;
-  SanitizerScope SanScope(this, {Kind}, CheckHandler);
+  SanitizerDebugLocation SanScope(this, {Kind}, CheckHandler);
   llvm::Value *Check;
   --End;
   if (!Min) {
@@ -3946,7 +3909,7 @@ void CodeGenFunction::EmitCfiCheckFail() {
   // not even be available, if Data == nullptr). However, we still want to
   // annotate the instrumentation. We approximate this by using all the CFI
   // kinds.
-  SanitizerScope SanScope(
+  SanitizerDebugLocation SanScope(
       this,
       {SanitizerKind::SO_CFIVCall, SanitizerKind::SO_CFINVCall,
        SanitizerKind::SO_CFIDerivedCast, SanitizerKind::SO_CFIUnrelatedCast,
@@ -4051,7 +4014,7 @@ void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
   if (SanOpts.has(SanitizerKind::Unreachable)) {
     auto CheckOrdinal = SanitizerKind::SO_Unreachable;
     auto CheckHandler = SanitizerHandler::BuiltinUnreachable;
-    SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+    SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
     EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
                              CheckOrdinal),
               CheckHandler, EmitCheckSourceLocation(Loc), {});
@@ -6293,7 +6256,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
             CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
       auto CheckOrdinal = SanitizerKind::SO_Function;
       auto CheckHandler = SanitizerHandler::FunctionTypeMismatch;
-      SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+      SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
       auto *TypeHash = getUBSanFunctionTypeHash(PointeeType);
 
       llvm::Type *PrefixSigType = PrefixSig->getType();
@@ -6373,7 +6336,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
       (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
     auto CheckOrdinal = SanitizerKind::SO_CFIICall;
     auto CheckHandler = SanitizerHandler::CFICheckFail;
-    SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+    SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
     EmitSanitizerStatReport(llvm::SanStat_CFI_ICall);
 
     llvm::Metadata *MD;
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index f9f6efb4c9747..193710bef2d16 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -1001,7 +1001,7 @@ void ScalarExprEmitter::EmitFloatConversionCheck(
 
   auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
   auto CheckHandler = SanitizerHandler::FloatCastOverflow;
-  CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal}, CheckHandler);
+  SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
   using llvm::APFloat;
   using llvm::APSInt;
 
@@ -1145,7 +1145,7 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
     // We don't know the check kind until we call
     // EmitIntegerTruncationCheckHelper, but we want to annotate
     // EmitIntegerTruncationCheckHelper's instructions too.
-    CodeGenFunction::SanitizerScope SanScope(
+    SanitizerDebugLocation SanScope(
         &CGF,
         {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
          SanitizerKind::SO_ImplicitSignedIntegerTruncation},
@@ -1159,8 +1159,7 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
   if (!CGF.SanOpts.has(Check.second.second))
     return;
 
-  CodeGenFunction::SanitizerScope SanScope(&CGF, {Check.second.second},
-                                           CheckHandler);
+  SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
 
   // Does some SSCL ignore this type?
   if (CGF.getContext().isTypeIgnoredBySanitizer(
@@ -1288,7 +1287,7 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
   // That's it. We can't rule out any more cases with the data we have.
 
   auto CheckHandler = SanitizerHandler::ImplicitConversion;
-  CodeGenFunction::SanitizerScope SanScope(
+  SanitizerDebugLocation SanScope(
       &CGF,
       {SanitizerKind::SO_ImplicitIntegerSignChange,
        SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
@@ -1414,7 +1413,7 @@ void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType,
   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
 
   auto CheckHandler = SanitizerHandler::ImplicitConversion;
-  CodeGenFunction::SanitizerScope SanScope(
+  SanitizerDebugLocation SanScope(
       this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
 
   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
@@ -3996,12 +3995,11 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
 
 Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
   {
-    CodeGenFunction::SanitizerScope SanScope(
-        &CGF,
-        {SanitizerKind::SO_IntegerDivideByZero,
-         SanitizerKind::SO_SignedIntegerOverflow,
-         SanitizerKind::SO_FloatDivideByZero},
-        SanitizerHandler::DivremOverflow);
+    SanitizerDebugLocation SanScope(&CGF,
+                                    {SanitizerKind::SO_IntegerDivideByZero,
+                                     SanitizerKind::SO_SignedIntegerOverflow,
+                                     SanitizerKind::SO_FloatDivideByZero},
+                                    SanitizerHandler::DivremOverflow);
     if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
          CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
         Ops.Ty->isIntegerType() &&
@@ -4055,11 +4053,10 @@ Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
        CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
       Ops.Ty->isIntegerType() &&
       (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
-    CodeGenFunction::SanitizerScope SanScope(
-        &CGF,
-        {SanitizerKind::SO_IntegerDivideByZero,
-         SanitizerKind::SO_SignedIntegerOverflow},
-        SanitizerHandler::DivremOverflow);
+    SanitizerDebugLocation SanScope(&CGF,
+                                    {SanitizerKind::SO_IntegerDivideByZero,
+                                     SanitizerKind::SO_SignedIntegerOverflow},
+                                    SanitizerHandler::DivremOverflow);
     llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
     EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
   }
@@ -4108,11 +4105,10 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
   if (isSigned)
     OpID |= 1;
 
-  CodeGenFunction::SanitizerScope SanScope(
-      &CGF,
-      {SanitizerKind::SO_SignedIntegerOverflow,
-       SanitizerKind::SO_UnsignedIntegerOverflow},
-      OverflowKind);
+  SanitizerDebugLocation SanScope(&CGF,
+                                  {SanitizerKind::SO_SignedIntegerOverflow,
+                                   SanitizerKind::SO_UnsignedIntegerOverflow},
+                                  OverflowKind);
   llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
 
   llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
@@ -4240,8 +4236,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
     // The inbounds GEP of null is valid iff the index is zero.
     auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
     auto CheckHandler = SanitizerHandler::PointerOverflow;
-    CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal},
-                                             CheckHandler);
+    SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
     Value *IsZeroIndex = CGF.Builder.CreateIsNull(index);
     llvm::Constant *StaticArgs[] = {
         CGF.EmitCheckSourceLocation(op.E->getExprLoc())};
@@ -4779,8 +4774,8 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
     if (SanitizeExponent)
       Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
 
-    CodeGenFunction::SanitizerScope SanScope(
-        &CGF, Ordinals, SanitizerHandler::ShiftOutOfBounds);
+    SanitizerDebugLocation SanScope(&CGF, Ordinals,
+                                    SanitizerHandler::ShiftOutOfBounds);
     SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
     bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
     llvm::Value *WidthMinusOne =
@@ -4851,9 +4846,8 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
     RHS = ConstrainShiftValue(Ops.LHS, RHS, "shr.mask");
   else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) &&
            isa<llvm::IntegerType>(Ops.LHS->getType())) {
-    CodeGenFunction::SanitizerScope SanScope(
-        &CGF, {SanitizerKind::SO_ShiftExponent},
-        SanitizerHandler::ShiftOutOfBounds);
+    SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
+                                    SanitizerHandler::ShiftOutOfBounds);
     bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
     llvm::Value *Valid = Builder.CreateICmpULE(
         Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
@@ -6087,7 +6081,7 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
 
   auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
   auto CheckHandler = SanitizerHandler::PointerOverflow;
-  SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+  SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
   llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
 
   GEPOffsetAndOverflow EvaluatedGEP =
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 41c6bd06e8826..8a1b44a0c157c 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1970,7 +1970,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
     if (InterfaceTy) {
       auto CheckOrdinal = SanitizerKind::SO_ObjCCast;
       auto CheckHandler = SanitizerHandler::InvalidObjCCast;
-      SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+      SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
       auto &C = CGM.getContext();
       assert(InterfaceTy->getDecl() && "No decl for ObjC interface type");
       Selector IsKindOfClassSel = GetUnarySelector("isKindOfClass", C);
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 77ae5ee4c5d21..33fd4a31cdd1a 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1635,7 +1635,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
     if (SanOpts.has(SanitizerKind::Return)) {
       auto CheckOrdinal = SanitizerKind::SO_Return;
       auto CheckHandler = SanitizerHandler::MissingReturn;
-      SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+      SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
       llvm::Value *IsFalse = Builder.getFalse();
       EmitCheck(std::make_pair(IsFalse, CheckOrdinal), CheckHandler,
                 EmitCheckSourceLocation(FD->getLocation()), {});
@@ -2541,7 +2541,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
           if (SanOpts.has(SanitizerKind::VLABound)) {
             auto CheckOrdinal = SanitizerKind::SO_VLABound;
             auto CheckHandler = SanitizerHandler::VLABoundNotPositive;
-            SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+            SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
             llvm::Value *Zero = llvm::Constant::getNullValue(size->getType());
             clang::QualType SEType = sizeExpr->getType();
             llvm::Value *CheckCondition =
@@ -2761,14 +2761,6 @@ CodeGenFunction::SanitizerScope::SanitizerScope(CodeGenFunction *CGF)
   CGF->IsSanitizerScope = true;
 }
 
-CodeGenFunction::SanitizerScope::SanitizerScope(
-    CodeGenFunction *CGF, ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
-    SanitizerHandler Handler)
-    : SanitizerScope(CGF) {
-  ApplyTrapDI = std::make_unique<ApplyDebugLocation>(
-      *CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler));
-}
-
 CodeGenFunction::SanitizerScope::~SanitizerScope() {
   CGF->IsSanitizerScope = false;
 }
@@ -3205,7 +3197,7 @@ void CodeGenFunction::emitAlignmentAssumptionCheck(
   {
     auto CheckOrdinal = SanitizerKind::SO_Alignment;
     auto CheckHandler = SanitizerHandler::AlignmentAssumption;
-    SanitizerScope SanScope(this, {CheckOrdinal}, CheckHandler);
+    SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
 
     if (!OffsetValue)
       OffsetValue = Builder.getInt1(false); // no offset.
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 44810c62e19b7..ec478c159e15f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -18,6 +18,7 @@
 #include "CGValue.h"
 #include "CodeGenModule.h"
 #include "EHScopeStack.h"
+#include "SanitizerHandler.h"
 #include "VarBypassDetector.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/CurrentSourceLocExprScope.h"
@@ -115,40 +116,6 @@ enum TypeEvaluationKind {
 };
 // clang-format on
 
-#define LIST_SANITIZER_CHECKS                                                  \
-  SANITIZER_CHECK(AddOverflow, add_overflow, 0)                                \
-  SANITIZER_CHECK(BuiltinUnreachable, builtin_unreachable, 0)                  \
-  SANITIZER_CHECK(CFICheckFail, cfi_check_fail, 0)                             \
-  SANITIZER_CHECK(DivremOverflow, divrem_overflow, 0)                          \
-  SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0)            \
-  SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0)                   \
-  SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 0)             \
-  SANITIZER_CHECK(ImplicitConversion, implicit_conversion, 0)                  \
-  SANITIZER_CHECK(InvalidBuiltin, invalid_builtin, 0)                          \
-  SANITIZER_CHECK(InvalidObjCCast, invalid_objc_cast, 0)                       \
-  SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0)                     \
-  SANITIZER_CHECK(MissingReturn, missing_return, 0)                            \
-  SANITIZER_CHECK(MulOverflow, mul_overflow, 0)                                \
-  SANITIZER_CHECK(NegateOverflow, negate_overflow, 0)                          \
-  SANITIZER_CHECK(NullabilityArg, nullability_arg, 0)                          \
-  SANITIZER_CHECK(NullabilityReturn, nullability_return, 1)                    \
-  SANITIZER_CHECK(NonnullArg, nonnull_arg, 0)                                  \
-  SANITIZER_CHECK(NonnullReturn, nonnull_return, 1)                            \
-  SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0)                               \
-  SANITIZER_CHECK(PointerOverflow, pointer_overflow, 0)                        \
-  SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0)                    \
-  SANITIZER_CHECK(SubOverflow, sub_overflow, 0)                                \
-  SANITIZER_CHECK(TypeMismatch, type_mismatch, 1)                              \
-  SANITIZER_CHECK(AlignmentAssumption, alignment_assumption, 0)                \
-  SANITIZER_CHECK(VLABoundNotPositive, vla_bound_not_positive, 0)              \
-  SANITIZER_CHECK(BoundsSafety, bounds_safety, 0)
-
-enum SanitizerHandler {
-#define SANITIZER_CHECK(Enum, Name, Version) Enum,
-  LIST_SANITIZER_CHECKS
-#undef SANITIZER_CHECK
-};
-
 /// Helper class with most of the code for saving a value for a
 /// conditional expression cleanup.
 struct DominatingLLVMValue {
@@ -272,10 +239,6 @@ class ApplyAtomGroup {
   ~ApplyAtomGroup();
 };
 
-// CGDebugInfo.h is not #included in this header due to overhead
-// (b384d6d6ccc8f4452cd7086061c657ce76b41224)
-class ApplyDebugLocation;
-
 /// CodeGenFunction - This class organizes the per-function state that is used
 /// while generating LLVM code.
 class CodeGenFunction : public CodeGenTypeCache {
@@ -601,13 +564,8 @@ class CodeGenFunction : public CodeGenTypeCache {
   class SanitizerScope {
     CodeGenFunction *CGF;
 
-    std::unique_ptr<ApplyDebugLocation> ApplyTrapDI;
-
   public:
     SanitizerScope(CodeGenFunction *CGF);
-    SanitizerScope(CodeGenFunction *CGF,
-                   ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
-                   SanitizerHandler Handler);
     ~SanitizerScope();
   };
 
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index fb379807bffa5..5d2c9303730f8 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -704,8 +704,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
   {
     auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
     auto CheckHandler = SanitizerHandler::CFICheckFail;
-    CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal},
-                                             CheckHandler);
+    SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
 
     llvm::Value *TypeId = nullptr;
     llvm::Value *CheckResult = nullptr;
@@ -804,8 +803,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
     if (RD->hasDefinition()) {
       auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
       auto CheckHandler = SanitizerHandler::CFICheckFail;
-      CodeGenFunction::SanitizerScope SanScope(&CGF, {CheckOrdinal},
-                                               CheckHandler);
+      SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
 
       llvm::Constant *StaticData[] = {
           llvm::ConstantInt::get(CGF.Int8Ty, CodeGenFunction::CFITCK_NVMFCall),
diff --git a/clang/lib/CodeGen/SanitizerHandler.h b/clang/lib/CodeGen/SanitizerHandler.h
new file mode 100644
index 0000000000000..bb42e3947cf14
--- /dev/null
+++ b/clang/lib/CodeGen/SanitizerHandler.h
@@ -0,0 +1,50 @@
+//===-- SanitizerHandler.h - Definition of sanitizer handlers ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the internal per-function state used for llvm translation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_CODEGEN_SANITIZER_HANDLER_H
+#define LLVM_CLANG_LIB_CODEGEN_SANITIZER_HANDLER_H
+
+#define LIST_SANITIZER_CHECKS                                                  \
+  SANITIZER_CHECK(AddOverflow, add_overflow, 0)                                \
+  SANITIZER_CHECK(BuiltinUnreachable, builtin_unreachable, 0)                  \
+  SANITIZER_CHECK(CFICheckFail, cfi_check_fail, 0)                             \
+  SANITIZER_CHECK(DivremOverflow, divrem_overflow, 0)                          \
+  SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0)            \
+  SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0)                   \
+  SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 0)             \
+  SANITIZER_CHECK(ImplicitConversion, implicit_conversion, 0)                  \
+  SANITIZER_CHECK(InvalidBuiltin, invalid_builtin, 0)                          \
+  SANITIZER_CHECK(InvalidObjCCast, invalid_objc_cast, 0)                       \
+  SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0)                     \
+  SANITIZER_CHECK(MissingReturn, missing_return, 0)                            \
+  SANITIZER_CHECK(MulOverflow, mul_overflow, 0)                                \
+  SANITIZER_CHECK(NegateOverflow, negate_overflow, 0)                          \
+  SANITIZER_CHECK(NullabilityArg, nullability_arg, 0)                          \
+  SANITIZER_CHECK(NullabilityReturn, nullability_return, 1)                    \
+  SANITIZER_CHECK(NonnullArg, nonnull_arg, 0)                                  \
+  SANITIZER_CHECK(NonnullReturn, nonnull_return, 1)                            \
+  SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0)                               \
+  SANITIZER_CHECK(PointerOverflow, pointer_overflow, 0)                        \
+  SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0)                    \
+  SANITIZER_CHECK(SubOverflow, sub_overflow, 0)                                \
+  SANITIZER_CHECK(TypeMismatch, type_mismatch, 1)                              \
+  SANITIZER_CHECK(AlignmentAssumption, alignment_assumption, 0)                \
+  SANITIZER_CHECK(VLABoundNotPositive, vla_bound_not_positive, 0)              \
+  SANITIZER_CHECK(BoundsSafety, bounds_safety, 0)
+
+enum SanitizerHandler {
+#define SANITIZER_CHECK(Enum, Name, Version) Enum,
+  LIST_SANITIZER_CHECKS
+#undef SANITIZER_CHECK
+};
+
+#endif // LLVM_CLANG_LIB_CODEGEN_SANITIZER_HANDLER_H

>From ff5ffbf9d4ad126d21147b818629c9bb01f1e90d Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 3 Jun 2025 16:17:31 +0000
Subject: [PATCH 18/26] Replace manual ApplyDebugLocation annotation with
 SanitizerDebugLocation

---
 clang/lib/CodeGen/CGClass.cpp | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index e671fa38c1c9d..dbffa85b4da7d 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2817,9 +2817,8 @@ void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
     RD = LeastDerivedClassWithSameLayout(RD);
 
   auto [Ordinal, _] = SanitizerInfoFromCFICheckKind(TCK);
-  ApplyDebugLocation ApplyTrapDI(
-      *this,
-      SanitizerAnnotateDebugInfo(Ordinal, SanitizerHandler::CFICheckFail));
+  SanitizerDebugLocation SanScope(this, {Ordinal},
+                                  SanitizerHandler::CFICheckFail);
 
   EmitVTablePtrCheck(RD, VTable, TCK, Loc);
 }
@@ -2844,9 +2843,8 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived,
     ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl);
 
   auto [Ordinal, _] = SanitizerInfoFromCFICheckKind(TCK);
-  ApplyDebugLocation ApplyTrapDI(
-      *this,
-      SanitizerAnnotateDebugInfo(Ordinal, SanitizerHandler::CFICheckFail));
+  SanitizerDebugLocation SanScope(this, {Ordinal},
+                                  SanitizerHandler::CFICheckFail);
 
   llvm::BasicBlock *ContBlock = nullptr;
 

>From 1df8fe42a3634cc235550a47d0ff980906f9a006 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 3 Jun 2025 17:12:25 +0000
Subject: [PATCH 19/26] Revert "Replace manual ApplyDebugLocation annotation
 with SanitizerDebugLocation"

This reverts commit ff5ffbf9d4ad126d21147b818629c9bb01f1e90d.
Already in sanitizerscope
---
 clang/lib/CodeGen/CGClass.cpp | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index dbffa85b4da7d..e671fa38c1c9d 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2817,8 +2817,9 @@ void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
     RD = LeastDerivedClassWithSameLayout(RD);
 
   auto [Ordinal, _] = SanitizerInfoFromCFICheckKind(TCK);
-  SanitizerDebugLocation SanScope(this, {Ordinal},
-                                  SanitizerHandler::CFICheckFail);
+  ApplyDebugLocation ApplyTrapDI(
+      *this,
+      SanitizerAnnotateDebugInfo(Ordinal, SanitizerHandler::CFICheckFail));
 
   EmitVTablePtrCheck(RD, VTable, TCK, Loc);
 }
@@ -2843,8 +2844,9 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived,
     ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl);
 
   auto [Ordinal, _] = SanitizerInfoFromCFICheckKind(TCK);
-  SanitizerDebugLocation SanScope(this, {Ordinal},
-                                  SanitizerHandler::CFICheckFail);
+  ApplyDebugLocation ApplyTrapDI(
+      *this,
+      SanitizerAnnotateDebugInfo(Ordinal, SanitizerHandler::CFICheckFail));
 
   llvm::BasicBlock *ContBlock = nullptr;
 

>From aead894277f56e16bb63b5f9e40b6e6dfcebb01a Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 3 Jun 2025 17:44:42 +0000
Subject: [PATCH 20/26] Replace manual ApplyDebugLocation with
 SanitizerDebugLocation, and also remove redundant SanitizerDebugLocation from
 EmitVTablePtrCheck

---
 clang/lib/CodeGen/CGClass.cpp | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index e671fa38c1c9d..d3ded7314538f 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2817,9 +2817,8 @@ void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
     RD = LeastDerivedClassWithSameLayout(RD);
 
   auto [Ordinal, _] = SanitizerInfoFromCFICheckKind(TCK);
-  ApplyDebugLocation ApplyTrapDI(
-      *this,
-      SanitizerAnnotateDebugInfo(Ordinal, SanitizerHandler::CFICheckFail));
+  SanitizerDebugLocation SanScope(this, {Ordinal},
+                                  SanitizerHandler::CFICheckFail);
 
   EmitVTablePtrCheck(RD, VTable, TCK, Loc);
 }
@@ -2844,9 +2843,8 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived,
     ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl);
 
   auto [Ordinal, _] = SanitizerInfoFromCFICheckKind(TCK);
-  ApplyDebugLocation ApplyTrapDI(
-      *this,
-      SanitizerAnnotateDebugInfo(Ordinal, SanitizerHandler::CFICheckFail));
+  SanitizerDebugLocation SanScope(this, {Ordinal},
+                                  SanitizerHandler::CFICheckFail);
 
   llvm::BasicBlock *ContBlock = nullptr;
 
@@ -2878,6 +2876,8 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
                                          llvm::Value *VTable,
                                          CFITypeCheckKind TCK,
                                          SourceLocation Loc) {
+  // N.B. all callers have established SanitizerDebugLocation
+
   if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
       !CGM.HasHiddenLTOVisibility(RD))
     return;
@@ -2889,8 +2889,6 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
           SanitizerMask::bitPosToMask(M), TypeName))
     return;
 
-  auto CheckHandler = SanitizerHandler::CFICheckFail;
-  SanitizerDebugLocation SanScope(this, {M}, CheckHandler);
   EmitSanitizerStatReport(SSK);
 
   llvm::Metadata *MD =
@@ -2914,7 +2912,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
 
   if (CGM.getCodeGenOpts().SanitizeTrap.has(M)) {
     bool NoMerge = !CGM.getCodeGenOpts().SanitizeMergeHandlers.has(M);
-    EmitTrapCheck(TypeTest, CheckHandler, NoMerge);
+    EmitTrapCheck(TypeTest, SanitizerHandler::CFICheckFail, NoMerge);
     return;
   }
 
@@ -2923,8 +2921,8 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
       llvm::MDString::get(CGM.getLLVMContext(), "all-vtables"));
   llvm::Value *ValidVtable = Builder.CreateCall(
       CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
-  EmitCheck(std::make_pair(TypeTest, M), CheckHandler, StaticData,
-            {VTable, ValidVtable});
+  EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
+            StaticData, {VTable, ValidVtable});
 }
 
 bool CodeGenFunction::ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD) {

>From 11a74d1542c037cc954277d7c42161bf7f41e4d1 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 3 Jun 2025 21:42:11 +0000
Subject: [PATCH 21/26] Refactor EmitTypeCheck into three more precise
 SanitizerDebugLocations

---
 clang/lib/CodeGen/CGExpr.cpp | 191 +++++++++++++++++++----------------
 1 file changed, 102 insertions(+), 89 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c8688e3b26d48..74579c7d9910a 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -744,111 +744,116 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
   if (Ty.isVolatileQualified())
     return;
 
-  auto CheckHandler = SanitizerHandler::TypeMismatch;
-  // SO_Vptr's corresponding handler is DynamicTypeCacheMiss, not TypeMismatch.
-  // However, it relies upon IsGuaranteedNonNull, hence the instructions cannot
-  // be fully separated from the TypeMismatch.
-  SanitizerDebugLocation SanScope(
-      this,
-      {SanitizerKind::SO_Null, SanitizerKind::SO_ObjectSize,
-       SanitizerKind::SO_Alignment, SanitizerKind::SO_Vptr},
-      CheckHandler);
-
-  SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 3>
-      Checks;
-  llvm::BasicBlock *Done = nullptr;
-
   // Quickly determine whether we have a pointer to an alloca. It's possible
   // to skip null checks, and some alignment checks, for these pointers. This
   // can reduce compile-time significantly.
   auto PtrToAlloca = dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCasts());
 
-  llvm::Value *True = llvm::ConstantInt::getTrue(getLLVMContext());
   llvm::Value *IsNonNull = nullptr;
   bool IsGuaranteedNonNull =
       SkippedChecks.has(SanitizerKind::Null) || PtrToAlloca;
-  bool AllowNullPointers = isNullPointerAllowed(TCK);
-  if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
-      !IsGuaranteedNonNull) {
-    // The glvalue must not be an empty glvalue.
-    IsNonNull = Builder.CreateIsNotNull(Ptr);
 
-    // The IR builder can constant-fold the null check if the pointer points to
-    // a constant.
-    IsGuaranteedNonNull = IsNonNull == True;
-
-    // Skip the null check if the pointer is known to be non-null.
-    if (!IsGuaranteedNonNull) {
-      if (AllowNullPointers) {
-        // When performing pointer casts, it's OK if the value is null.
-        // Skip the remaining checks in that case.
-        Done = createBasicBlock("null");
-        llvm::BasicBlock *Rest = createBasicBlock("not.null");
-        Builder.CreateCondBr(IsNonNull, Rest, Done);
-        EmitBlock(Rest);
-      } else {
-        Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::SO_Null));
+  llvm::BasicBlock *Done = nullptr;
+  bool DoneViaNullSanitize = false;
+
+  {
+    auto CheckHandler = SanitizerHandler::TypeMismatch;
+    SanitizerDebugLocation SanScope(this,
+                                    {SanitizerKind::SO_Null,
+                                     SanitizerKind::SO_ObjectSize,
+                                     SanitizerKind::SO_Alignment},
+                                    CheckHandler);
+
+    SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 3>
+        Checks;
+
+    llvm::Value *True = llvm::ConstantInt::getTrue(getLLVMContext());
+    bool AllowNullPointers = isNullPointerAllowed(TCK);
+    if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
+        !IsGuaranteedNonNull) {
+      // The glvalue must not be an empty glvalue.
+      IsNonNull = Builder.CreateIsNotNull(Ptr);
+
+      // The IR builder can constant-fold the null check if the pointer points
+      // to a constant.
+      IsGuaranteedNonNull = IsNonNull == True;
+
+      // Skip the null check if the pointer is known to be non-null.
+      if (!IsGuaranteedNonNull) {
+        if (AllowNullPointers) {
+          // When performing pointer casts, it's OK if the value is null.
+          // Skip the remaining checks in that case.
+          Done = createBasicBlock("null");
+          DoneViaNullSanitize = true;
+          llvm::BasicBlock *Rest = createBasicBlock("not.null");
+          Builder.CreateCondBr(IsNonNull, Rest, Done);
+          EmitBlock(Rest);
+        } else {
+          Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::SO_Null));
+        }
       }
     }
-  }
 
-  if (SanOpts.has(SanitizerKind::ObjectSize) &&
-      !SkippedChecks.has(SanitizerKind::ObjectSize) &&
-      !Ty->isIncompleteType()) {
-    uint64_t TySize = CGM.getMinimumObjectSize(Ty).getQuantity();
-    llvm::Value *Size = llvm::ConstantInt::get(IntPtrTy, TySize);
-    if (ArraySize)
-      Size = Builder.CreateMul(Size, ArraySize);
-
-    // Degenerate case: new X[0] does not need an objectsize check.
-    llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
-    if (!ConstantSize || !ConstantSize->isNullValue()) {
-      // The glvalue must refer to a large enough storage region.
-      // FIXME: If Address Sanitizer is enabled, insert dynamic instrumentation
-      //        to check this.
-      // FIXME: Get object address space
-      llvm::Type *Tys[2] = { IntPtrTy, Int8PtrTy };
-      llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
-      llvm::Value *Min = Builder.getFalse();
-      llvm::Value *NullIsUnknown = Builder.getFalse();
-      llvm::Value *Dynamic = Builder.getFalse();
-      llvm::Value *LargeEnough = Builder.CreateICmpUGE(
-          Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}), Size);
-      Checks.push_back(
-          std::make_pair(LargeEnough, SanitizerKind::SO_ObjectSize));
+    if (SanOpts.has(SanitizerKind::ObjectSize) &&
+        !SkippedChecks.has(SanitizerKind::ObjectSize) &&
+        !Ty->isIncompleteType()) {
+      uint64_t TySize = CGM.getMinimumObjectSize(Ty).getQuantity();
+      llvm::Value *Size = llvm::ConstantInt::get(IntPtrTy, TySize);
+      if (ArraySize)
+        Size = Builder.CreateMul(Size, ArraySize);
+
+      // Degenerate case: new X[0] does not need an objectsize check.
+      llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
+      if (!ConstantSize || !ConstantSize->isNullValue()) {
+        // The glvalue must refer to a large enough storage region.
+        // FIXME: If Address Sanitizer is enabled, insert dynamic
+        // instrumentation
+        //        to check this.
+        // FIXME: Get object address space
+        llvm::Type *Tys[2] = {IntPtrTy, Int8PtrTy};
+        llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
+        llvm::Value *Min = Builder.getFalse();
+        llvm::Value *NullIsUnknown = Builder.getFalse();
+        llvm::Value *Dynamic = Builder.getFalse();
+        llvm::Value *LargeEnough = Builder.CreateICmpUGE(
+            Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}), Size);
+        Checks.push_back(
+            std::make_pair(LargeEnough, SanitizerKind::SO_ObjectSize));
+      }
     }
-  }
 
-  llvm::MaybeAlign AlignVal;
-  llvm::Value *PtrAsInt = nullptr;
-
-  if (SanOpts.has(SanitizerKind::Alignment) &&
-      !SkippedChecks.has(SanitizerKind::Alignment)) {
-    AlignVal = Alignment.getAsMaybeAlign();
-    if (!Ty->isIncompleteType() && !AlignVal)
-      AlignVal = CGM.getNaturalTypeAlignment(Ty, nullptr, nullptr,
-                                             /*ForPointeeType=*/true)
-                     .getAsMaybeAlign();
-
-    // The glvalue must be suitably aligned.
-    if (AlignVal && *AlignVal > llvm::Align(1) &&
-        (!PtrToAlloca || PtrToAlloca->getAlign() < *AlignVal)) {
-      PtrAsInt = Builder.CreatePtrToInt(Ptr, IntPtrTy);
-      llvm::Value *Align = Builder.CreateAnd(
-          PtrAsInt, llvm::ConstantInt::get(IntPtrTy, AlignVal->value() - 1));
-      llvm::Value *Aligned =
-          Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0));
-      if (Aligned != True)
-        Checks.push_back(std::make_pair(Aligned, SanitizerKind::SO_Alignment));
+    llvm::MaybeAlign AlignVal;
+    llvm::Value *PtrAsInt = nullptr;
+
+    if (SanOpts.has(SanitizerKind::Alignment) &&
+        !SkippedChecks.has(SanitizerKind::Alignment)) {
+      AlignVal = Alignment.getAsMaybeAlign();
+      if (!Ty->isIncompleteType() && !AlignVal)
+        AlignVal = CGM.getNaturalTypeAlignment(Ty, nullptr, nullptr,
+                                               /*ForPointeeType=*/true)
+                       .getAsMaybeAlign();
+
+      // The glvalue must be suitably aligned.
+      if (AlignVal && *AlignVal > llvm::Align(1) &&
+          (!PtrToAlloca || PtrToAlloca->getAlign() < *AlignVal)) {
+        PtrAsInt = Builder.CreatePtrToInt(Ptr, IntPtrTy);
+        llvm::Value *Align = Builder.CreateAnd(
+            PtrAsInt, llvm::ConstantInt::get(IntPtrTy, AlignVal->value() - 1));
+        llvm::Value *Aligned =
+            Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0));
+        if (Aligned != True)
+          Checks.push_back(
+              std::make_pair(Aligned, SanitizerKind::SO_Alignment));
+      }
     }
-  }
 
-  if (Checks.size() > 0) {
-    llvm::Constant *StaticData[] = {
-        EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(Ty),
-        llvm::ConstantInt::get(Int8Ty, AlignVal ? llvm::Log2(*AlignVal) : 1),
-        llvm::ConstantInt::get(Int8Ty, TCK)};
-    EmitCheck(Checks, CheckHandler, StaticData, PtrAsInt ? PtrAsInt : Ptr);
+    if (Checks.size() > 0) {
+      llvm::Constant *StaticData[] = {
+          EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(Ty),
+          llvm::ConstantInt::get(Int8Ty, AlignVal ? llvm::Log2(*AlignVal) : 1),
+          llvm::ConstantInt::get(Int8Ty, TCK)};
+      EmitCheck(Checks, CheckHandler, StaticData, PtrAsInt ? PtrAsInt : Ptr);
+    }
   }
 
   // If possible, check that the vptr indicates that there is a subobject of
@@ -861,6 +866,9 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
   //       or call a non-static member function
   if (SanOpts.has(SanitizerKind::Vptr) &&
       !SkippedChecks.has(SanitizerKind::Vptr) && isVptrCheckRequired(TCK, Ty)) {
+    SanitizerDebugLocation SanScope(this, {SanitizerKind::SO_Vptr},
+                                    SanitizerHandler::DynamicTypeCacheMiss);
+
     // Ensure that the pointer is non-null before loading it. If there is no
     // compile-time guarantee, reuse the run-time null check or emit a new one.
     if (!IsGuaranteedNonNull) {
@@ -929,6 +937,11 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
   }
 
   if (Done) {
+    SanitizerDebugLocation SanScope(
+        this,
+        {DoneViaNullSanitize ? SanitizerKind::SO_Null : SanitizerKind::SO_Vptr},
+        DoneViaNullSanitize ? SanitizerHandler::TypeMismatch
+                            : SanitizerHandler::DynamicTypeCacheMiss);
     Builder.CreateBr(Done);
     EmitBlock(Done);
   }

>From be32bd73a99f96932979b56ffb1580fedf256dc1 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 3 Jun 2025 22:39:03 +0000
Subject: [PATCH 22/26] assert(IsSanitizerScope); in EmitVTablePtrCheck

---
 clang/lib/CodeGen/CGClass.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index d3ded7314538f..13792c1042046 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2876,7 +2876,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
                                          llvm::Value *VTable,
                                          CFITypeCheckKind TCK,
                                          SourceLocation Loc) {
-  // N.B. all callers have established SanitizerDebugLocation
+  assert(IsSanitizerScope);
 
   if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
       !CGM.HasHiddenLTOVisibility(RD))

>From 81ecf62663d3db019602ca2a8107bbab5c7a0731 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 3 Jun 2025 23:32:10 +0000
Subject: [PATCH 23/26] Re-run CI


>From 5a510a37de968f98a2e97ba292061e48c7fde093 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Wed, 4 Jun 2025 19:01:36 +0000
Subject: [PATCH 24/26] Use ordinal for label if unique

---
 clang/lib/CodeGen/CGDebugInfo.cpp             | 44 ++++++++++++++++---
 .../test/CodeGen/bounds-checking-debuginfo.c  |  8 ++--
 clang/test/CodeGen/cfi-check-fail-debuginfo.c |  4 +-
 .../CodeGen/cfi-icall-generalize-debuginfo.c  |  8 ++--
 .../CodeGen/cfi-icall-normalize2-debuginfo.c  |  4 +-
 clang/test/CodeGen/ubsan-function-debuginfo.c |  4 +-
 6 files changed, 52 insertions(+), 20 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 30f63759e8cc6..40262e369b2e1 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -6421,9 +6421,7 @@ CodeGenFunction::LexicalScope::~LexicalScope() {
   }
 }
 
-llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
-    ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
-    SanitizerHandler Handler) {
+static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler) {
   std::string Label;
   switch (Handler) {
 #define SANITIZER_CHECK(Enum, Name, Version)                                   \
@@ -6435,10 +6433,44 @@ llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
 #undef SANITIZER_CHECK
   };
 
+  // Label doesn't require sanitization
+
+  return Label;
+}
+
+static std::string
+SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal) {
+  std::string Label;
+  switch (Ordinal) {
+#define SANITIZER(NAME, ID)                                                    \
+  case SanitizerKind::SO_##ID:                                                 \
+    Label = "__ubsan_check_" NAME;                                             \
+    break;
+#include "clang/Basic/Sanitizers.def"
+  default:
+    llvm_unreachable("unexpected sanitizer kind");
+  }
+
+  // Sanitize label (convert hyphens to underscores; also futureproof against
+  // non-alpha)
+  for (unsigned int i = 0; i < Label.length(); i++)
+    if (!std::isalpha(Label[i]))
+      Label[i] = '_';
+
+  return Label;
+}
+
+llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
+    ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+    SanitizerHandler Handler) {
+  std::string Label;
+  if (Ordinals.size() == 1)
+    Label = SanitizerOrdinalToCheckLabel(Ordinals[0]);
+  else
+    Label = SanitizerHandlerToCheckLabel(Handler);
+
   llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
 
-  // TODO: the annotation could be more precise e.g.,
-  //       use the ordinal name if there is only one ordinal
   for (auto Ord : Ordinals) {
     // TODO: deprecate ClArrayBoundsPseudoFn
     if (((ClArrayBoundsPseudoFn && Ord == SanitizerKind::SO_ArrayBounds) ||
@@ -6463,4 +6495,4 @@ SanitizerDebugLocation::SanitizerDebugLocation(
 SanitizerDebugLocation::~SanitizerDebugLocation() {
   assert(CGF->IsSanitizerScope);
   CGF->IsSanitizerScope = false;
-}
\ No newline at end of file
+}
diff --git a/clang/test/CodeGen/bounds-checking-debuginfo.c b/clang/test/CodeGen/bounds-checking-debuginfo.c
index 31050f247fb2b..43762eed9e2fe 100644
--- a/clang/test/CodeGen/bounds-checking-debuginfo.c
+++ b/clang/test/CodeGen/bounds-checking-debuginfo.c
@@ -68,7 +68,7 @@ double f1(int b, int i) {
 
 //.
 // CHECK-TRAP: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK-TRAP: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// CHECK-TRAP: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // CHECK-TRAP: [[DBG4]] = distinct !DISubprogram(name: "f1", scope: [[META5:![0-9]+]], file: [[META5]], line: 63, type: [[META6:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]], retainedNodes: [[META10]])
 // CHECK-TRAP: [[META5]] = !DIFile(filename: "{{.*}}bounds-checking-debuginfo.c", directory: {{.*}})
 // CHECK-TRAP: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
@@ -89,14 +89,14 @@ double f1(int b, int i) {
 // CHECK-TRAP: [[DBG21]] = !DILocation(line: 65, column: 3, scope: [[DBG4]])
 // CHECK-TRAP: [[DBG22]] = !DILocation(line: 66, column: 12, scope: [[DBG4]])
 // CHECK-TRAP: [[DBG23]] = !DILocation(line: 0, scope: [[META24:![0-9]+]], inlinedAt: [[DBG26]])
-// CHECK-TRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_out_of_bounds", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK-TRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_array_bounds", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK-TRAP: [[META25]] = !DISubroutineType(types: null)
 // CHECK-TRAP: [[DBG26]] = !DILocation(line: 66, column: 10, scope: [[DBG4]])
 // CHECK-TRAP: [[PROF27]] = !{!"branch_weights", i32 1048575, i32 1}
 // CHECK-TRAP: [[DBG28]] = !DILocation(line: 66, column: 3, scope: [[DBG4]])
 //.
 // CHECK-NOTRAP: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // CHECK-NOTRAP: [[DBG4]] = distinct !DISubprogram(name: "f1", scope: [[META5:![0-9]+]], file: [[META5]], line: 63, type: [[META6:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]], retainedNodes: [[META10]])
 // CHECK-NOTRAP: [[META5]] = !DIFile(filename: "{{.*}}bounds-checking-debuginfo.c", directory: {{.*}})
 // CHECK-NOTRAP: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
@@ -117,7 +117,7 @@ double f1(int b, int i) {
 // CHECK-NOTRAP: [[DBG21]] = !DILocation(line: 65, column: 3, scope: [[DBG4]])
 // CHECK-NOTRAP: [[DBG22]] = !DILocation(line: 66, column: 12, scope: [[DBG4]])
 // CHECK-NOTRAP: [[DBG23]] = !DILocation(line: 0, scope: [[META24:![0-9]+]], inlinedAt: [[DBG26]])
-// CHECK-NOTRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_out_of_bounds", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK-NOTRAP: [[META24]] = distinct !DISubprogram(name: "__ubsan_check_array_bounds", scope: [[META5]], file: [[META5]], type: [[META25:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK-NOTRAP: [[META25]] = !DISubroutineType(types: null)
 // CHECK-NOTRAP: [[DBG26]] = !DILocation(line: 66, column: 10, scope: [[DBG4]])
 // CHECK-NOTRAP: [[PROF27]] = !{!"branch_weights", i32 1048575, i32 1}
diff --git a/clang/test/CodeGen/cfi-check-fail-debuginfo.c b/clang/test/CodeGen/cfi-check-fail-debuginfo.c
index bade8071d8ed3..74ed5564ec704 100644
--- a/clang/test/CodeGen/cfi-check-fail-debuginfo.c
+++ b/clang/test/CodeGen/cfi-check-fail-debuginfo.c
@@ -24,7 +24,7 @@ void caller(void (*f)(void)) {
 }
 //.
 // CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// CHECK: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // CHECK: [[DBG7]] = distinct !DISubprogram(name: "caller", scope: [[META8:![0-9]+]], file: [[META8]], line: 22, type: [[META9:![0-9]+]], scopeLine: 22, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META14:![0-9]+]])
 // CHECK: [[META8]] = !DIFile(filename: "{{.*}}cfi-check-fail-debuginfo.c", directory: {{.*}})
 // CHECK: [[META9]] = !DISubroutineType(types: [[META10:![0-9]+]])
@@ -39,7 +39,7 @@ void caller(void (*f)(void)) {
 // CHECK: [[META18]] = !{i64 0, i64 2451761621477796417}
 // CHECK: [[META19]] = !DILocation(line: 0, scope: [[DBG7]])
 // CHECK: [[DBG20]] = !DILocation(line: 0, scope: [[META21:![0-9]+]], inlinedAt: [[DBG23]])
-// CHECK: [[META21]] = distinct !DISubprogram(name: "__ubsan_check_cfi_check_fail", scope: [[META8]], file: [[META8]], type: [[META22:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[META21]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall", scope: [[META8]], file: [[META8]], type: [[META22:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META22]] = !DISubroutineType(types: null)
 // CHECK: [[DBG23]] = !DILocation(line: 23, column: 3, scope: [[DBG7]])
 // CHECK: [[META24]] = !{}
diff --git a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
index 4d446b8a64f67..304b60539c3d1 100644
--- a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
+++ b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
@@ -55,7 +55,7 @@ void g(int** (*fp)(const char *, const char **)) {
 
 //.
 // UNGENERALIZED: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: [[META2:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
-// UNGENERALIZED: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// UNGENERALIZED: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // UNGENERALIZED: [[META2]] = !{[[META3:![0-9]+]]}
 // UNGENERALIZED: [[META3]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META4:![0-9]+]], size: 64)
 // UNGENERALIZED: [[META4]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META5:![0-9]+]], size: 64)
@@ -85,7 +85,7 @@ void g(int** (*fp)(const char *, const char **)) {
 // UNGENERALIZED: [[META32]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // UNGENERALIZED: [[META33]] = !DILocation(line: 0, scope: [[DBG25]])
 // UNGENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[DBG37]])
-// UNGENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_cfi_check_fail", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// UNGENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // UNGENERALIZED: [[META36]] = !DISubroutineType(types: null)
 // UNGENERALIZED: [[DBG37]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
 // UNGENERALIZED: [[META38]] = !{}
@@ -93,7 +93,7 @@ void g(int** (*fp)(const char *, const char **)) {
 // UNGENERALIZED: [[DBG40]] = !DILocation(line: 54, column: 1, scope: [[DBG25]])
 //.
 // GENERALIZED: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: [[META2:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
-// GENERALIZED: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// GENERALIZED: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // GENERALIZED: [[META2]] = !{[[META3:![0-9]+]]}
 // GENERALIZED: [[META3]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META4:![0-9]+]], size: 64)
 // GENERALIZED: [[META4]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META5:![0-9]+]], size: 64)
@@ -123,7 +123,7 @@ void g(int** (*fp)(const char *, const char **)) {
 // GENERALIZED: [[META32]] = !{i64 0, !"_ZTSFvPvE.generalized"}
 // GENERALIZED: [[META33]] = !DILocation(line: 0, scope: [[DBG25]])
 // GENERALIZED: [[DBG34]] = !DILocation(line: 0, scope: [[META35:![0-9]+]], inlinedAt: [[DBG37]])
-// GENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_cfi_check_fail", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// GENERALIZED: [[META35]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall", scope: [[META11]], file: [[META11]], type: [[META36:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // GENERALIZED: [[META36]] = !DISubroutineType(types: null)
 // GENERALIZED: [[DBG37]] = !DILocation(line: 53, column: 3, scope: [[DBG25]])
 // GENERALIZED: [[META38]] = !{}
diff --git a/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c b/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
index dde4ad2024b9b..a2f6ee0c6805c 100644
--- a/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
+++ b/clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
@@ -66,7 +66,7 @@ void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) {
 
 //.
 // CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// CHECK: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // CHECK: [[DBG7]] = distinct !DISubprogram(name: "foo", scope: [[META8:![0-9]+]], file: [[META8]], line: 24, type: [[META9:![0-9]+]], scopeLine: 24, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META15:![0-9]+]])
 // CHECK: [[META8]] = !DIFile(filename: "{{.*}}cfi-icall-normalize2-debuginfo.c", directory: {{.*}})
 // CHECK: [[META9]] = !DISubroutineType(types: [[META10:![0-9]+]])
@@ -82,7 +82,7 @@ void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) {
 // CHECK: [[META19]] = !{i64 0, !"_ZTSFvPvu3i32E.normalized.generalized"}
 // CHECK: [[META20]] = !DILocation(line: 0, scope: [[DBG7]])
 // CHECK: [[DBG21]] = !DILocation(line: 0, scope: [[META22:![0-9]+]], inlinedAt: [[DBG24]])
-// CHECK: [[META22]] = distinct !DISubprogram(name: "__ubsan_check_cfi_check_fail", scope: [[META8]], file: [[META8]], type: [[META23:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[META22]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall", scope: [[META8]], file: [[META8]], type: [[META23:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META23]] = !DISubroutineType(types: null)
 // CHECK: [[DBG24]] = !DILocation(line: 25, column: 5, scope: [[DBG7]])
 // CHECK: [[META25]] = !{}
diff --git a/clang/test/CodeGen/ubsan-function-debuginfo.c b/clang/test/CodeGen/ubsan-function-debuginfo.c
index 48619dcbf851e..106aeceadf369 100644
--- a/clang/test/CodeGen/ubsan-function-debuginfo.c
+++ b/clang/test/CodeGen/ubsan-function-debuginfo.c
@@ -37,7 +37,7 @@ void call_no_prototype(void (*f)()) { f(); }
 void call_prototype(void (*f)(void)) { f(); }
 //.
 // CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
+// CHECK: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
 // CHECK: [[DBG5]] = distinct !DISubprogram(name: "call_no_prototype", scope: [[META6:![0-9]+]], file: [[META6]], line: 14, type: [[META7:![0-9]+]], scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META12:![0-9]+]])
 // CHECK: [[META6]] = !DIFile(filename: "{{.*}}ubsan-function-debuginfo.c", directory: {{.*}})
 // CHECK: [[META7]] = !DISubroutineType(types: [[META8:![0-9]+]])
@@ -62,7 +62,7 @@ void call_prototype(void (*f)(void)) { f(); }
 // CHECK: [[META26]] = !{i32 -1056584962, i32 -747727454}
 // CHECK: [[META27]] = !DILocation(line: 0, scope: [[DBG18]])
 // CHECK: [[DBG28]] = !DILocation(line: 0, scope: [[META29:![0-9]+]], inlinedAt: [[DBG31]])
-// CHECK: [[META29]] = distinct !DISubprogram(name: "__ubsan_check_function_type_mismatch", scope: [[META6]], file: [[META6]], type: [[META30:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK: [[META29]] = distinct !DISubprogram(name: "__ubsan_check_function", scope: [[META6]], file: [[META6]], type: [[META30:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK: [[META30]] = !DISubroutineType(types: null)
 // CHECK: [[DBG31]] = !DILocation(line: 37, column: 40, scope: [[DBG18]])
 // CHECK: [[META32]] = !{}

>From 31291d02dcdcbb5a873bdd0c15a29f69793967a8 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Wed, 4 Jun 2025 19:05:02 +0000
Subject: [PATCH 25/26] Undo test change

---
 clang/test/CodeGen/bounds-checking-debuginfo.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/CodeGen/bounds-checking-debuginfo.c b/clang/test/CodeGen/bounds-checking-debuginfo.c
index 43762eed9e2fe..74c06665dfe02 100644
--- a/clang/test/CodeGen/bounds-checking-debuginfo.c
+++ b/clang/test/CodeGen/bounds-checking-debuginfo.c
@@ -68,9 +68,9 @@ double f1(int b, int i) {
 
 //.
 // CHECK-TRAP: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK-TRAP: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
+// CHECK-TRAP: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
 // CHECK-TRAP: [[DBG4]] = distinct !DISubprogram(name: "f1", scope: [[META5:![0-9]+]], file: [[META5]], line: 63, type: [[META6:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]], retainedNodes: [[META10]])
-// CHECK-TRAP: [[META5]] = !DIFile(filename: "{{.*}}bounds-checking-debuginfo.c", directory: {{.*}})
+// CHECK-TRAP: [[META5]] = !DIFile(filename: "bounds-checking-debuginfo.c", directory: {{.*}})
 // CHECK-TRAP: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
 // CHECK-TRAP: [[META7]] = !{[[META8:![0-9]+]], [[META9:![0-9]+]], [[META9]]}
 // CHECK-TRAP: [[META8]] = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)
@@ -96,9 +96,9 @@ double f1(int b, int i) {
 // CHECK-TRAP: [[DBG28]] = !DILocation(line: 66, column: 3, scope: [[DBG4]])
 //.
 // CHECK-NOTRAP: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "{{.*}}<stdin>", directory: {{.*}})
+// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "<stdin>", directory: {{.*}})
 // CHECK-NOTRAP: [[DBG4]] = distinct !DISubprogram(name: "f1", scope: [[META5:![0-9]+]], file: [[META5]], line: 63, type: [[META6:![0-9]+]], scopeLine: 63, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]], retainedNodes: [[META10]])
-// CHECK-NOTRAP: [[META5]] = !DIFile(filename: "{{.*}}bounds-checking-debuginfo.c", directory: {{.*}})
+// CHECK-NOTRAP: [[META5]] = !DIFile(filename: "bounds-checking-debuginfo.c", directory: {{.*}})
 // CHECK-NOTRAP: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
 // CHECK-NOTRAP: [[META7]] = !{[[META8:![0-9]+]], [[META9:![0-9]+]], [[META9]]}
 // CHECK-NOTRAP: [[META8]] = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)

>From 3dedb83007085f697b83ff79fbf666a125d5094f Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Wed, 4 Jun 2025 19:58:46 +0000
Subject: [PATCH 26/26] Remove newline

---
 clang/lib/CodeGen/CGDebugInfo.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 40262e369b2e1..45ac66e4863c8 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -6434,7 +6434,6 @@ static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler) {
   };
 
   // Label doesn't require sanitization
-
   return Label;
 }
 



More information about the cfe-commits mailing list