From 6bc5c7c752786530ae202ee2bb5a71b0900e67e4 Mon Sep 17 00:00:00 2001 From: Thurston Dang 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 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 PoisonSize = {}) { - CodeGenFunction::SanitizerScope SanScope(&CGF); + CodeGenFunction::SanitizerScope SanScope(&CGF, {}); // Pass in void pointer and size of region as arguments to runtime // function SmallVector 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, 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 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(Builder.getFalse()), SanitizerKind::SO_Unreachable), SanitizerHandler::BuiltinUnreachable, @@ -6271,7 +6270,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, !isa(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(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(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> - 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> @@ -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> @@ -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(Ops.LHS->getType())) { - CodeGenFunction::SanitizerScope SanScope(&CGF); + SmallVector 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, 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(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 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 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 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: "", directory: {{.*}}) +// CHECK-TRAP: [[META1]] = !DIFile(filename: "{{.*}}", 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: "", directory: {{.*}}) +// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "{{.*}}", 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: "{{.*}}", 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: "", directory: {{.*}}) +// CHECK: [[META1]] = !DIFile(filename: "{{.*}}", 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: "", directory: {{.*}}) +// CHECKS: [[META3]] = !DIFile(filename: "{{.*}}", 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: "", directory: {{.*}}) +// CHECKU: [[META3]] = !DIFile(filename: "{{.*}}", 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 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 Kinds; + SmallVector 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(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(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 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 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 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 Ordinals; + SmallVector 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(Builder.getFalse()), - SanitizerKind::SO_Unreachable), + CheckOrdinal), SanitizerHandler::BuiltinUnreachable, EmitCheckSourceLocation(Loc), {}); } @@ -6270,7 +6273,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, !isa(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(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 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 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: "{{.*}}", directory: {{.*}}) +// CHECK-TRAP: [[META1]] = !DIFile(filename: "", 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: "{{.*}}", directory: {{.*}}) +// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "", 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: "{{.*}}", directory: {{.*}}) +// CHECK: [[META1]] = !DIFile(filename: "", 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: "{{.*}}", directory: {{.*}}) +// UNGENERALIZED: [[META1]] = !DIFile(filename: "", 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: "{{.*}}", directory: {{.*}}) +// GENERALIZED: [[META1]] = !DIFile(filename: "", 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: "{{.*}}", directory: {{.*}}) +// CHECK: [[META1]] = !DIFile(filename: "", 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: "{{.*}}", directory: {{.*}}) +// CHECK: [[META1]] = !DIFile(filename: "", 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: "{{.*}}", directory: {{.*}}) +// CHECKS: [[META3]] = !DIFile(filename: "", 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: "{{.*}}", directory: {{.*}}) +// CHECKU: [[META3]] = !DIFile(filename: "", 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 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 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 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, 2> Checks; From 5da37cd6c79a813205b6ebe24c81b09d4b1f76ff Mon Sep 17 00:00:00 2001 From: Thurston Dang 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 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 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 PoisonSize = {}) { - CodeGenFunction::SanitizerScope SanScope(&CGF, {}); + CodeGenFunction::SanitizerScope SanScope(&CGF); // Pass in void pointer and size of region as arguments to runtime // function SmallVector 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, 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 Ordinals) { + ArrayRef 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(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(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> 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> @@ -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> @@ -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, 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(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(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 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 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 Ordinals); + ArrayRef 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 Ordinals); + llvm::DILocation * + SanitizerAnnotateDebugInfo(ArrayRef 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 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 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 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(Ops.LHS->getType())) { - SmallVector Kinds; + SmallVector 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, 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 Ordinals, SanitizerHandler Handler) : SanitizerScope(CGF) { - this->ApplyTrapDI = new ApplyDebugLocation( - *CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler)); + ApplyTrapDI = std::unique_ptr(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 ApplyTrapDI; public: SanitizerScope(CodeGenFunction *CGF); From ed2c9b5603750129a9cad1bfef50cd4459f94b99 Mon Sep 17 00:00:00 2001 From: Thurston Dang 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 Ordinals, SanitizerHandler Handler) : SanitizerScope(CGF) { - ApplyTrapDI = std::unique_ptr(new ApplyDebugLocation( - *CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler))); + ApplyTrapDI = std::make_unique( + *CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler)); } CodeGenFunction::SanitizerScope::~SanitizerScope() { From 16d6beef5b2e12cde5a350011800f905a1098d5a Mon Sep 17 00:00:00 2001 From: Thurston Dang 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 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 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 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 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 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 ClSanitizeGuardChecks( } // namespace clang -// TODO: consider deprecating ClArrayBoundsPseudoFn; functionality is subsumed -// by -fsanitize-annotate-debug-info -static llvm::cl::opt 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, 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 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(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(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::pairisIntegerType() && @@ -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, 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(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 Ordinals, - SanitizerHandler Handler) - : SanitizerScope(CGF) { - ApplyTrapDI = std::make_unique( - *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 ApplyTrapDI; - public: SanitizerScope(CodeGenFunction *CGF); - SanitizerScope(CodeGenFunction *CGF, - ArrayRef 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 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 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 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 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, 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(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, 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(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(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 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 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 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 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 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: "", directory: {{.*}}) +// CHECK-TRAP: [[META1]] = !DIFile(filename: "{{.*}}", 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: "", directory: {{.*}}) +// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "{{.*}}", 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: "", directory: {{.*}}) +// CHECK: [[META1]] = !DIFile(filename: "{{.*}}", 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: "", directory: {{.*}}) +// UNGENERALIZED: [[META1]] = !DIFile(filename: "{{.*}}", 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: "", directory: {{.*}}) +// GENERALIZED: [[META1]] = !DIFile(filename: "{{.*}}", 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: "", directory: {{.*}}) +// CHECK: [[META1]] = !DIFile(filename: "{{.*}}", 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: "", directory: {{.*}}) +// CHECK: [[META1]] = !DIFile(filename: "{{.*}}", 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 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: "{{.*}}", directory: {{.*}}) +// CHECK-TRAP: [[META1]] = !DIFile(filename: "", 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: "{{.*}}", directory: {{.*}}) +// CHECK-NOTRAP: [[META1]] = !DIFile(filename: "", 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 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; }