https://github.com/thurstond created https://github.com/llvm/llvm-project/pull/122511
The `Checked` parameter of `CodeGenFunction::EmitCheck` is of type `ArrayRef<std::pair<llvm::Value *, SanitizerMask>>`, which is overly generalized: SanitizerMask can denote that zero or more sanitizers are enabled, but `EmitCheck` requires that exactly one sanitizer is specified in the SanitizerMask (e.g., `SanitizeTrap.has(Checked[i].second)` enforces that). This patch replaces SanitizerMask with SanitizerOrdinal in `EmitCheck` and code that calls it transitively. This should not affect the behavior of UBSan, but it has the advantage that specifying the wrong number of sanitizers in `Checked[i].second` will be detected as a compile-time error, rather than a runtime assertion failure. Suggested by Vitaly in https://github.com/llvm/llvm-project/pull/122392 as an alternative to adding an explicit runtime assertion that the SanitizerMask contains exactly one sanitizer. >From c116bd6154e9681c03793fc63eedd2ecb603b090 Mon Sep 17 00:00:00 2001 From: Thurston Dang <thurs...@google.com> Date: Fri, 10 Jan 2025 01:08:00 +0000 Subject: [PATCH] [ubsan] Use SanitizerOrdinal of SanitizerMask for check kind The `Checked` parameter of `CodeGenFunction::EmitCheck` is of type `ArrayRef<std::pair<llvm::Value *, SanitizerMask>>`, which is overly generalized: SanitizerMask can denote that zero or more sanitizers are enabled, but `EmitCheck` requires that exactly one sanitizer is specified in the SanitizerMask (e.g., `SanitizeTrap.has(Checked[i].second)` enforces that). This patch replaces SanitizerMask with SanitizerOrdinal for `EmitCheck` and code that calls it transitively. This should not affect the behavior of UBSan, but it has the advantage that specifying the wrong number of sanitizers in `Checked[i].second` will be detected as a compile-time error, rather than a runtime assertion failure. Suggested by Vitaly in https://github.com/llvm/llvm-project/pull/122392 as an alternative to adding an explicit runtime assertion that the SanitizerMask contains exactly one sanitizer. --- clang/include/clang/Basic/Sanitizers.h | 4 ++ clang/lib/CodeGen/CGBuiltin.cpp | 6 +- clang/lib/CodeGen/CGCall.cpp | 12 ++-- clang/lib/CodeGen/CGClass.cpp | 15 ++--- clang/lib/CodeGen/CGDecl.cpp | 2 +- clang/lib/CodeGen/CGExpr.cpp | 73 +++++++++++----------- clang/lib/CodeGen/CGExprScalar.cpp | 84 ++++++++++++++------------ clang/lib/CodeGen/CGObjC.cpp | 2 +- clang/lib/CodeGen/CodeGenFunction.cpp | 9 +-- clang/lib/CodeGen/CodeGenFunction.h | 13 ++-- clang/lib/CodeGen/ItaniumCXXABI.cpp | 4 +- 11 files changed, 124 insertions(+), 100 deletions(-) diff --git a/clang/include/clang/Basic/Sanitizers.h b/clang/include/clang/Basic/Sanitizers.h index c890242269b334..a12e779215bcf0 100644 --- a/clang/include/clang/Basic/Sanitizers.h +++ b/clang/include/clang/Basic/Sanitizers.h @@ -161,6 +161,10 @@ struct SanitizerSet { return static_cast<bool>(Mask & K); } + bool has(SanitizerKind::SanitizerOrdinal O) const { + return has(SanitizerMask::bitPosToMask(O)); + } + /// Check if one or more sanitizers are enabled. bool hasOneOf(SanitizerMask K) const { return static_cast<bool>(Mask & K); } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ca03fb665d423d..8941e66b92a2df 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2240,7 +2240,7 @@ Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E, SanitizerScope SanScope(this); Value *Cond = Builder.CreateICmpNE( ArgValue, llvm::Constant::getNullValue(ArgValue->getType())); - EmitCheck(std::make_pair(Cond, SanitizerKind::Builtin), + EmitCheck(std::make_pair(Cond, SanitizerKind::SO_Builtin), SanitizerHandler::InvalidBuiltin, {EmitCheckSourceLocation(E->getExprLoc()), llvm::ConstantInt::get(Builder.getInt8Ty(), Kind)}, @@ -2255,7 +2255,7 @@ Value *CodeGenFunction::EmitCheckedArgForAssume(const Expr *E) { SanitizerScope SanScope(this); EmitCheck( - std::make_pair(ArgValue, SanitizerKind::Builtin), + std::make_pair(ArgValue, SanitizerKind::SO_Builtin), SanitizerHandler::InvalidBuiltin, {EmitCheckSourceLocation(E->getExprLoc()), llvm::ConstantInt::get(Builder.getInt8Ty(), BCK_AssumePassedFalse)}, @@ -2290,7 +2290,7 @@ static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E, // TODO: support -ftrapv-handler. if (SanitizeOverflow) { - CGF.EmitCheck({{NotOverflow, SanitizerKind::SignedIntegerOverflow}}, + CGF.EmitCheck({{NotOverflow, SanitizerKind::SO_SignedIntegerOverflow}}, SanitizerHandler::NegateOverflow, {CGF.EmitCheckSourceLocation(E->getArg(0)->getExprLoc()), CGF.EmitCheckTypeDescriptor(E->getType())}, diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 7b0ef4be986193..379ce00b739aed 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -4024,20 +4024,20 @@ void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV) { // Prefer the returns_nonnull attribute if it's present. SourceLocation AttrLoc; - SanitizerMask CheckKind; + SanitizerKind::SanitizerOrdinal CheckKind; SanitizerHandler Handler; if (RetNNAttr) { assert(!requiresReturnValueNullabilityCheck() && "Cannot check nullability and the nonnull attribute"); AttrLoc = RetNNAttr->getLocation(); - CheckKind = SanitizerKind::ReturnsNonnullAttribute; + CheckKind = SanitizerKind::SO_ReturnsNonnullAttribute; Handler = SanitizerHandler::NonnullReturn; } else { if (auto *DD = dyn_cast<DeclaratorDecl>(CurCodeDecl)) if (auto *TSI = DD->getTypeSourceInfo()) if (auto FTL = TSI->getTypeLoc().getAsAdjusted<FunctionTypeLoc>()) AttrLoc = FTL.getReturnLoc().findNullabilityLoc(); - CheckKind = SanitizerKind::NullabilityReturn; + CheckKind = SanitizerKind::SO_NullabilityReturn; Handler = SanitizerHandler::NullabilityReturn; } @@ -4419,15 +4419,15 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType, return; SourceLocation AttrLoc; - SanitizerMask CheckKind; + SanitizerKind::SanitizerOrdinal CheckKind; SanitizerHandler Handler; if (NNAttr) { AttrLoc = NNAttr->getLocation(); - CheckKind = SanitizerKind::NonnullAttribute; + CheckKind = SanitizerKind::SO_NonnullAttribute; Handler = SanitizerHandler::NonnullArg; } else { AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc(); - CheckKind = SanitizerKind::NullabilityArg; + CheckKind = SanitizerKind::SO_NullabilityArg; Handler = SanitizerHandler::NullabilityArg; } diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index c45688bd1ed3ce..16a1c1cebdaa44 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -2843,23 +2843,23 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD, !CGM.HasHiddenLTOVisibility(RD)) return; - SanitizerMask M; + SanitizerKind::SanitizerOrdinal M; llvm::SanitizerStatKind SSK; switch (TCK) { case CFITCK_VCall: - M = SanitizerKind::CFIVCall; + M = SanitizerKind::SO_CFIVCall; SSK = llvm::SanStat_CFI_VCall; break; case CFITCK_NVCall: - M = SanitizerKind::CFINVCall; + M = SanitizerKind::SO_CFINVCall; SSK = llvm::SanStat_CFI_NVCall; break; case CFITCK_DerivedCast: - M = SanitizerKind::CFIDerivedCast; + M = SanitizerKind::SO_CFIDerivedCast; SSK = llvm::SanStat_CFI_DerivedCast; break; case CFITCK_UnrelatedCast: - M = SanitizerKind::CFIUnrelatedCast; + M = SanitizerKind::SO_CFIUnrelatedCast; SSK = llvm::SanStat_CFI_UnrelatedCast; break; case CFITCK_ICall: @@ -2869,7 +2869,8 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD, } std::string TypeName = RD->getQualifiedNameAsString(); - if (getContext().getNoSanitizeList().containsType(M, TypeName)) + if (getContext().getNoSanitizeList().containsType( + SanitizerMask::bitPosToMask(M), TypeName)) return; SanitizerScope SanScope(this); @@ -2945,7 +2946,7 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad( if (SanOpts.has(SanitizerKind::CFIVCall) && !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall, TypeName)) { - EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIVCall), + EmitCheck(std::make_pair(CheckResult, SanitizerKind::SO_CFIVCall), SanitizerHandler::CFICheckFail, {}, {}); } diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 6f3ff050cb6978..f85e0b2c404f92 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -762,7 +762,7 @@ void CodeGenFunction::EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(LHS.getType()), llvm::ConstantInt::get(Int8Ty, 0), // The LogAlignment info is unused. llvm::ConstantInt::get(Int8Ty, TCK_NonnullAssign)}; - EmitCheck({{IsNotNull, SanitizerKind::NullabilityAssign}}, + EmitCheck({{IsNotNull, SanitizerKind::SO_NullabilityAssign}}, SanitizerHandler::TypeMismatch, StaticData, RHS); } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 1bad7a722da07a..060d02b7f14873 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -735,7 +735,8 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, SanitizerScope SanScope(this); - SmallVector<std::pair<llvm::Value *, SanitizerMask>, 3> Checks; + SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 3> + Checks; llvm::BasicBlock *Done = nullptr; // Quickly determine whether we have a pointer to an alloca. It's possible @@ -767,7 +768,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, Builder.CreateCondBr(IsNonNull, Rest, Done); EmitBlock(Rest); } else { - Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null)); + Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::SO_Null)); } } } @@ -794,7 +795,8 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, 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::ObjectSize)); + Checks.push_back( + std::make_pair(LargeEnough, SanitizerKind::SO_ObjectSize)); } } @@ -818,7 +820,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *Aligned = Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0)); if (Aligned != True) - Checks.push_back(std::make_pair(Aligned, SanitizerKind::Alignment)); + Checks.push_back(std::make_pair(Aligned, SanitizerKind::SO_Alignment)); } } @@ -902,7 +904,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::ConstantInt::get(Int8Ty, TCK) }; llvm::Value *DynamicData[] = { Ptr, Hash }; - EmitCheck(std::make_pair(EqualHash, SanitizerKind::Vptr), + EmitCheck(std::make_pair(EqualHash, SanitizerKind::SO_Vptr), SanitizerHandler::DynamicTypeCacheMiss, StaticData, DynamicData); } @@ -1220,7 +1222,7 @@ 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, SanitizerKind::ArrayBounds), + EmitCheck(std::make_pair(Check, SanitizerKind::SO_ArrayBounds), SanitizerHandler::OutOfBounds, StaticData, Index); } @@ -1960,8 +1962,8 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, } llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(Ty)}; - SanitizerMask Kind = - NeedsEnumCheck ? SanitizerKind::Enum : SanitizerKind::Bool; + SanitizerKind::SanitizerOrdinal Kind = + NeedsEnumCheck ? SanitizerKind::SO_Enum : SanitizerKind::SO_Bool; EmitCheck(std::make_pair(Check, Kind), SanitizerHandler::LoadInvalidValue, StaticArgs, EmitCheckValue(Value)); return true; @@ -3513,11 +3515,12 @@ enum class CheckRecoverableKind { }; } -static CheckRecoverableKind getRecoverableKind(SanitizerMask Kind) { - assert(Kind.countPopulation() == 1); - if (Kind == SanitizerKind::Vptr) +static CheckRecoverableKind +getRecoverableKind(SanitizerKind::SanitizerOrdinal Ordinal) { + if (Ordinal == SanitizerKind::SO_Vptr) return CheckRecoverableKind::AlwaysRecoverable; - else if (Kind == SanitizerKind::Return || Kind == SanitizerKind::Unreachable) + else if (Ordinal == SanitizerKind::SO_Return || + Ordinal == SanitizerKind::SO_Unreachable) return CheckRecoverableKind::Unrecoverable; else return CheckRecoverableKind::Recoverable; @@ -3589,7 +3592,7 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF, } void CodeGenFunction::EmitCheck( - ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked, + ArrayRef<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> Checked, SanitizerHandler CheckHandler, ArrayRef<llvm::Constant *> StaticArgs, ArrayRef<llvm::Value *> DynamicArgs) { assert(IsSanitizerScope); @@ -3715,8 +3718,9 @@ void CodeGenFunction::EmitCheck( } void CodeGenFunction::EmitCfiSlowPathCheck( - SanitizerMask Kind, llvm::Value *Cond, llvm::ConstantInt *TypeId, - llvm::Value *Ptr, ArrayRef<llvm::Constant *> StaticArgs) { + SanitizerKind::SanitizerOrdinal Ordinal, llvm::Value *Cond, + llvm::ConstantInt *TypeId, llvm::Value *Ptr, + ArrayRef<llvm::Constant *> StaticArgs) { llvm::BasicBlock *Cont = createBasicBlock("cfi.cont"); llvm::BasicBlock *CheckBB = createBasicBlock("cfi.slowpath"); @@ -3728,7 +3732,7 @@ void CodeGenFunction::EmitCfiSlowPathCheck( EmitBlock(CheckBB); - bool WithDiag = !CGM.getCodeGenOpts().SanitizeTrap.has(Kind); + bool WithDiag = !CGM.getCodeGenOpts().SanitizeTrap.has(Ordinal); llvm::CallInst *CheckCall; llvm::FunctionCallee SlowPathFn; @@ -3860,22 +3864,23 @@ void CodeGenFunction::EmitCfiCheckFail() { {Addr, AllVtables}), IntPtrTy); - const std::pair<int, SanitizerMask> CheckKinds[] = { - {CFITCK_VCall, SanitizerKind::CFIVCall}, - {CFITCK_NVCall, SanitizerKind::CFINVCall}, - {CFITCK_DerivedCast, SanitizerKind::CFIDerivedCast}, - {CFITCK_UnrelatedCast, SanitizerKind::CFIUnrelatedCast}, - {CFITCK_ICall, SanitizerKind::CFIICall}}; - - SmallVector<std::pair<llvm::Value *, SanitizerMask>, 5> Checks; - for (auto CheckKindMaskPair : CheckKinds) { - int Kind = CheckKindMaskPair.first; - SanitizerMask Mask = CheckKindMaskPair.second; + const std::pair<int, SanitizerKind::SanitizerOrdinal> CheckKinds[] = { + {CFITCK_VCall, SanitizerKind::SO_CFIVCall}, + {CFITCK_NVCall, SanitizerKind::SO_CFINVCall}, + {CFITCK_DerivedCast, SanitizerKind::SO_CFIDerivedCast}, + {CFITCK_UnrelatedCast, SanitizerKind::SO_CFIUnrelatedCast}, + {CFITCK_ICall, SanitizerKind::SO_CFIICall}}; + + SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 5> + Checks; + for (auto CheckKindOrdinalPair : CheckKinds) { + int Kind = CheckKindOrdinalPair.first; + SanitizerKind::SanitizerOrdinal Ordinal = CheckKindOrdinalPair.second; llvm::Value *Cond = Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(Int8Ty, Kind)); - if (CGM.getLangOpts().Sanitize.has(Mask)) - EmitCheck(std::make_pair(Cond, Mask), SanitizerHandler::CFICheckFail, {}, - {Data, Addr, ValidVtable}); + if (CGM.getLangOpts().Sanitize.has(Ordinal)) + EmitCheck(std::make_pair(Cond, Ordinal), SanitizerHandler::CFICheckFail, + {}, {Data, Addr, ValidVtable}); else EmitTrapCheck(Cond, SanitizerHandler::CFICheckFail); } @@ -3890,7 +3895,7 @@ void CodeGenFunction::EmitUnreachable(SourceLocation Loc) { if (SanOpts.has(SanitizerKind::Unreachable)) { SanitizerScope SanScope(this); EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()), - SanitizerKind::Unreachable), + SanitizerKind::SO_Unreachable), SanitizerHandler::BuiltinUnreachable, EmitCheckSourceLocation(Loc), {}); } @@ -6054,7 +6059,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, Builder.CreateICmpEQ(CalleeTypeHash, TypeHash); llvm::Constant *StaticData[] = {EmitCheckSourceLocation(E->getBeginLoc()), EmitCheckTypeDescriptor(CalleeType)}; - EmitCheck(std::make_pair(CalleeTypeHashMatch, SanitizerKind::Function), + EmitCheck(std::make_pair(CalleeTypeHashMatch, SanitizerKind::SO_Function), SanitizerHandler::FunctionTypeMismatch, StaticData, {CalleePtr}); @@ -6091,10 +6096,10 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, EmitCheckTypeDescriptor(QualType(FnType, 0)), }; if (CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) { - EmitCfiSlowPathCheck(SanitizerKind::CFIICall, TypeTest, CrossDsoTypeId, + EmitCfiSlowPathCheck(SanitizerKind::SO_CFIICall, TypeTest, CrossDsoTypeId, CalleePtr, StaticData); } else { - EmitCheck(std::make_pair(TypeTest, SanitizerKind::CFIICall), + EmitCheck(std::make_pair(TypeTest, SanitizerKind::SO_CFIICall), SanitizerHandler::CFICheckFail, StaticData, {CalleePtr, llvm::UndefValue::get(IntPtrTy)}); } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 090c4fb3ea39ee..ac499e490ee87e 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -280,8 +280,9 @@ class ScalarExprEmitter return CGF.EmitCheckedLValue(E, TCK); } - void EmitBinOpCheck(ArrayRef<std::pair<Value *, SanitizerMask>> Checks, - const BinOpInfo &Info); + void EmitBinOpCheck( + ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks, + const BinOpInfo &Info); Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) { return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal(); @@ -1047,14 +1048,14 @@ void ScalarExprEmitter::EmitFloatConversionCheck( llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(OrigSrcType), CGF.EmitCheckTypeDescriptor(DstType)}; - CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow), + CGF.EmitCheck(std::make_pair(Check, SanitizerKind::SO_FloatCastOverflow), SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc); } // Should be called within CodeGenFunction::SanitizerScope RAII scope. // Returns 'i1 false' when the truncation Src -> Dst was lossy. static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, - std::pair<llvm::Value *, SanitizerMask>> + std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder) { llvm::Type *SrcTy = Src->getType(); @@ -1073,13 +1074,13 @@ EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, // If both (src and dst) types are unsigned, then it's an unsigned truncation. // Else, it is a signed truncation. ScalarExprEmitter::ImplicitConversionCheckKind Kind; - SanitizerMask Mask; + SanitizerKind::SanitizerOrdinal Ordinal; if (!SrcSigned && !DstSigned) { Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation; - Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation; + Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation; } else { Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation; - Mask = SanitizerKind::ImplicitSignedIntegerTruncation; + Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation; } llvm::Value *Check = nullptr; @@ -1088,7 +1089,7 @@ EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, // 2. Equality-compare with the original source value Check = Builder.CreateICmpEQ(Check, Src, "truncheck"); // If the comparison result is 'i1 false', then the truncation was lossy. - return std::make_pair(Kind, std::make_pair(Check, Mask)); + return std::make_pair(Kind, std::make_pair(Check, Ordinal)); } static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck( @@ -1128,7 +1129,7 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType, CodeGenFunction::SanitizerScope SanScope(&CGF); std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, - std::pair<llvm::Value *, SanitizerMask>> + std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> Check = EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder); // If the comparison result is 'i1 false', then the truncation was lossy. @@ -1138,7 +1139,8 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType, return; // Does some SSCL ignore this type? - if (CGF.getContext().isTypeIgnoredBySanitizer(Check.second.second, DstType)) + if (CGF.getContext().isTypeIgnoredBySanitizer( + SanitizerMask::bitPosToMask(Check.second.second), DstType)) return; llvm::Constant *StaticArgs[] = { @@ -1169,7 +1171,7 @@ static llvm::Value *EmitIsNegativeTestHelper(Value *V, QualType VType, // Should be called within CodeGenFunction::SanitizerScope RAII scope. // Returns 'i1 false' when the conversion Src -> Dst changed the sign. static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, - std::pair<llvm::Value *, SanitizerMask>> + std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder) { llvm::Type *SrcTy = Src->getType(); @@ -1205,13 +1207,13 @@ EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, // If the comparison result is 'false', then the conversion changed the sign. return std::make_pair( ScalarExprEmitter::ICCK_IntegerSignChange, - std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange)); + std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange)); } void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, Value *Dst, QualType DstType, SourceLocation Loc) { - if (!CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) + if (!CGF.SanOpts.has(SanitizerKind::SO_ImplicitIntegerSignChange)) return; llvm::Type *SrcTy = Src->getType(); @@ -1265,12 +1267,14 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, CodeGenFunction::SanitizerScope SanScope(&CGF); std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, - std::pair<llvm::Value *, SanitizerMask>> + std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> Check; // Each of these checks needs to return 'false' when an issue was detected. ImplicitConversionCheckKind CheckKind; - llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks; + llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, + 2> + Checks; // So we can 'and' all the checks together, and still get 'false', // if at least one of the checks detected an issue. @@ -1303,7 +1307,7 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, // Should be called within CodeGenFunction::SanitizerScope RAII scope. // Returns 'i1 false' when the truncation Src -> Dst was lossy. static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, - std::pair<llvm::Value *, SanitizerMask>> + std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder) { bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); @@ -1323,13 +1327,14 @@ EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, // If the comparison result is 'i1 false', then the truncation was lossy. return std::make_pair( - Kind, std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion)); + Kind, + std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion)); } // Should be called within CodeGenFunction::SanitizerScope RAII scope. // Returns 'i1 false' when the conversion Src -> Dst changed the sign. static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, - std::pair<llvm::Value *, SanitizerMask>> + std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder) { // 1. Was the old Value negative? @@ -1348,7 +1353,7 @@ EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, // If the comparison result is 'false', then the conversion changed the sign. return std::make_pair( ScalarExprEmitter::ICCK_IntegerSignChange, - std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion)); + std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion)); } void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType, @@ -1383,7 +1388,7 @@ void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType, CodeGenFunction::SanitizerScope SanScope(this); std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, - std::pair<llvm::Value *, SanitizerMask>> + std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> Check; // Truncation @@ -1774,7 +1779,8 @@ Value *ScalarExprEmitter::EmitNullValue(QualType Ty) { /// operation). The check passes if all values in \p Checks (which are \c i1), /// are \c true. void ScalarExprEmitter::EmitBinOpCheck( - ArrayRef<std::pair<Value *, SanitizerMask>> Checks, const BinOpInfo &Info) { + ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks, + const BinOpInfo &Info) { assert(CGF.IsSanitizerScope); SanitizerHandler Check; SmallVector<llvm::Constant *, 4> StaticData; @@ -3773,11 +3779,12 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E, void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck( const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) { - SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks; + SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2> + Checks; if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) { Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero), - SanitizerKind::IntegerDivideByZero)); + SanitizerKind::SO_IntegerDivideByZero)); } const auto *BO = cast<BinaryOperator>(Ops.E); @@ -3795,7 +3802,7 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck( llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne); llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp, "or"); Checks.push_back( - std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow)); + std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow)); } if (Checks.size() > 0) @@ -3816,8 +3823,8 @@ Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { Ops.mayHaveFloatDivisionByZero()) { llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero); - EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero), - Ops); + EmitBinOpCheck( + std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops); } } @@ -3921,9 +3928,10 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) { // runtime. Otherwise, this is a -ftrapv check, so just emit a trap. if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) { llvm::Value *NotOverflow = Builder.CreateNot(overflow); - SanitizerMask Kind = isSigned ? SanitizerKind::SignedIntegerOverflow - : SanitizerKind::UnsignedIntegerOverflow; - EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops); + SanitizerKind::SanitizerOrdinal Ordinal = + isSigned ? SanitizerKind::SO_SignedIntegerOverflow + : SanitizerKind::SO_UnsignedIntegerOverflow; + EmitBinOpCheck(std::make_pair(NotOverflow, Ordinal), Ops); } else CGF.EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind); return result; @@ -4543,7 +4551,7 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) { else if ((SanitizeBase || SanitizeExponent) && isa<llvm::IntegerType>(Ops.LHS->getType())) { CodeGenFunction::SanitizerScope SanScope(&CGF); - SmallVector<std::pair<Value *, SanitizerMask>, 2> Checks; + SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks; bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation(); llvm::Value *WidthMinusOne = GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned); @@ -4551,7 +4559,7 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) { if (SanitizeExponent) { Checks.push_back( - std::make_pair(ValidExponent, SanitizerKind::ShiftExponent)); + std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent)); } if (SanitizeBase) { @@ -4586,8 +4594,8 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) { BaseCheck->addIncoming(Builder.getTrue(), Orig); BaseCheck->addIncoming(ValidBase, CheckShiftBase); Checks.push_back(std::make_pair( - BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase - : SanitizerKind::UnsignedShiftBase)); + BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase + : SanitizerKind::SO_UnsignedShiftBase)); } assert(!Checks.empty()); @@ -4617,7 +4625,7 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) { bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation(); llvm::Value *Valid = Builder.CreateICmpULE( Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned)); - EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops); + EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::SO_ShiftExponent), Ops); } if (Ops.Ty->hasUnsignedIntegerRepresentation()) @@ -5850,7 +5858,9 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy); auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.TotalOffset); - llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks; + llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, + 2> + Checks; if (PerformNullCheck) { // If the base pointer evaluates to a null pointer value, @@ -5863,7 +5873,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::PointerOverflow); + Checks.emplace_back(Valid, SanitizerKind::SO_PointerOverflow); } if (PerformOverflowCheck) { @@ -5899,7 +5909,7 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr); } ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow); - Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow); + Checks.emplace_back(ValidGEP, SanitizerKind::SO_PointerOverflow); } assert(!Checks.empty() && "Should have produced some checks."); diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 98d98e2d97e888..27c7c2fa9cba1d 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -1984,7 +1984,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ llvm::Constant *StaticData[] = { EmitCheckSourceLocation(S.getBeginLoc()), EmitCheckTypeDescriptor(QualType(InterfaceTy, 0))}; - EmitCheck({{IsClass, SanitizerKind::ObjCCast}}, + EmitCheck({{IsClass, SanitizerKind::SO_ObjCCast}}, SanitizerHandler::InvalidObjCCast, ArrayRef<llvm::Constant *>(StaticData), CurrentItem); } diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 27ec68bd2a872d..d6f3716afabdf0 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1600,7 +1600,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, if (SanOpts.has(SanitizerKind::Return)) { SanitizerScope SanScope(this); llvm::Value *IsFalse = Builder.getFalse(); - EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return), + EmitCheck(std::make_pair(IsFalse, SanitizerKind::SO_Return), SanitizerHandler::MissingReturn, EmitCheckSourceLocation(FD->getLocation()), {}); } else if (ShouldEmitUnreachable) { @@ -2484,8 +2484,9 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { llvm::Constant *StaticArgs[] = { EmitCheckSourceLocation(sizeExpr->getBeginLoc()), EmitCheckTypeDescriptor(SEType)}; - EmitCheck(std::make_pair(CheckCondition, SanitizerKind::VLABound), - SanitizerHandler::VLABoundNotPositive, StaticArgs, size); + EmitCheck( + std::make_pair(CheckCondition, SanitizerKind::SO_VLABound), + SanitizerHandler::VLABoundNotPositive, StaticArgs, size); } // Always zexting here would be wrong if it weren't @@ -3139,7 +3140,7 @@ void CodeGenFunction::emitAlignmentAssumptionCheck( llvm::Value *DynamicData[] = {EmitCheckValue(Ptr), EmitCheckValue(Alignment), EmitCheckValue(OffsetValue)}; - EmitCheck({std::make_pair(TheCheck, SanitizerKind::Alignment)}, + EmitCheck({std::make_pair(TheCheck, SanitizerKind::SO_Alignment)}, SanitizerHandler::AlignmentAssumption, StaticData, DynamicData); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 457e1477bb2eed..23ddc869277a87 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -5185,14 +5185,17 @@ class CodeGenFunction : public CodeGenTypeCache { /// Create a basic block that will either trap or call a handler function in /// the UBSan runtime with the provided arguments, and create a conditional /// branch to it. - void EmitCheck(ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked, - SanitizerHandler Check, ArrayRef<llvm::Constant *> StaticArgs, - ArrayRef<llvm::Value *> DynamicArgs); + void + EmitCheck(ArrayRef<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> + Checked, + SanitizerHandler Check, ArrayRef<llvm::Constant *> StaticArgs, + ArrayRef<llvm::Value *> DynamicArgs); /// Emit a slow path cross-DSO CFI check which calls __cfi_slowpath /// if Cond if false. - void EmitCfiSlowPathCheck(SanitizerMask Kind, llvm::Value *Cond, - llvm::ConstantInt *TypeId, llvm::Value *Ptr, + void EmitCfiSlowPathCheck(SanitizerKind::SanitizerOrdinal Ordinal, + llvm::Value *Cond, llvm::ConstantInt *TypeId, + llvm::Value *Ptr, ArrayRef<llvm::Constant *> StaticArgs); /// Emit a reached-unreachable diagnostic if \p Loc is valid and runtime diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index cf9e338236e556..7c463f51f63dc5 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -779,7 +779,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::CFIMFCall), + CGF.EmitCheck(std::make_pair(CheckResult, SanitizerKind::SO_CFIMFCall), SanitizerHandler::CFICheckFail, StaticData, {VTable, ValidVtable}); } @@ -823,7 +823,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( Bit = Builder.CreateOr(Bit, TypeTest); } - CGF.EmitCheck(std::make_pair(Bit, SanitizerKind::CFIMFCall), + CGF.EmitCheck(std::make_pair(Bit, SanitizerKind::SO_CFIMFCall), SanitizerHandler::CFICheckFail, StaticData, {NonVirtualFn, llvm::UndefValue::get(CGF.IntPtrTy)}); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits