[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