aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp28
-rw-r--r--clang/lib/CodeGen/CGCall.cpp4
-rw-r--r--clang/lib/CodeGen/CGClass.cpp18
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp82
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.h12
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp7
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp291
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp100
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp7
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp24
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h8
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp22
12 files changed, 376 insertions, 227 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index dff2334..c0b02a1 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2009,11 +2009,12 @@ Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
if (!SanOpts.has(SanitizerKind::Builtin))
return ArgValue;
- SanitizerScope SanScope(this);
+ auto CheckOrdinal = SanitizerKind::SO_Builtin;
+ auto CheckHandler = SanitizerHandler::InvalidBuiltin;
+ SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
Value *Cond = Builder.CreateICmpNE(
ArgValue, llvm::Constant::getNullValue(ArgValue->getType()));
- EmitCheck(std::make_pair(Cond, SanitizerKind::SO_Builtin),
- SanitizerHandler::InvalidBuiltin,
+ EmitCheck(std::make_pair(Cond, CheckOrdinal), CheckHandler,
{EmitCheckSourceLocation(E->getExprLoc()),
llvm::ConstantInt::get(Builder.getInt8Ty(), Kind)},
{});
@@ -2025,10 +2026,11 @@ Value *CodeGenFunction::EmitCheckedArgForAssume(const Expr *E) {
if (!SanOpts.has(SanitizerKind::Builtin))
return ArgValue;
- SanitizerScope SanScope(this);
+ auto CheckOrdinal = SanitizerKind::SO_Builtin;
+ auto CheckHandler = SanitizerHandler::InvalidBuiltin;
+ SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
EmitCheck(
- std::make_pair(ArgValue, SanitizerKind::SO_Builtin),
- SanitizerHandler::InvalidBuiltin,
+ std::make_pair(ArgValue, CheckOrdinal), CheckHandler,
{EmitCheckSourceLocation(E->getExprLoc()),
llvm::ConstantInt::get(Builder.getInt8Ty(), BCK_AssumePassedFalse)},
std::nullopt);
@@ -2051,7 +2053,15 @@ static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E,
return EmitAbs(CGF, ArgValue, true);
}
- CodeGenFunction::SanitizerScope SanScope(&CGF);
+ SmallVector<SanitizerKind::SanitizerOrdinal, 1> Ordinals;
+ SanitizerHandler CheckHandler;
+ if (SanitizeOverflow) {
+ Ordinals.push_back(SanitizerKind::SO_SignedIntegerOverflow);
+ CheckHandler = SanitizerHandler::NegateOverflow;
+ } else
+ CheckHandler = SanitizerHandler::SubOverflow;
+
+ SanitizerDebugLocation SanScope(&CGF, Ordinals, CheckHandler);
Constant *Zero = Constant::getNullValue(ArgValue->getType());
Value *ResultAndOverflow = CGF.Builder.CreateBinaryIntrinsic(
@@ -2063,12 +2073,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 46a5d64..75df821e 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4184,7 +4184,7 @@ void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV) {
Handler = SanitizerHandler::NullabilityReturn;
}
- SanitizerScope SanScope(this);
+ 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.
@@ -4569,7 +4569,7 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
Handler = SanitizerHandler::NullabilityArg;
}
- SanitizerScope SanScope(this);
+ 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 251b059..13792c1 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2817,7 +2817,8 @@ void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
RD = LeastDerivedClassWithSameLayout(RD);
auto [Ordinal, _] = SanitizerInfoFromCFICheckKind(TCK);
- ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(Ordinal));
+ SanitizerDebugLocation SanScope(this, {Ordinal},
+ SanitizerHandler::CFICheckFail);
EmitVTablePtrCheck(RD, VTable, TCK, Loc);
}
@@ -2842,7 +2843,8 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived,
ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl);
auto [Ordinal, _] = SanitizerInfoFromCFICheckKind(TCK);
- ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(Ordinal));
+ SanitizerDebugLocation SanScope(this, {Ordinal},
+ SanitizerHandler::CFICheckFail);
llvm::BasicBlock *ContBlock = nullptr;
@@ -2874,6 +2876,8 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
llvm::Value *VTable,
CFITypeCheckKind TCK,
SourceLocation Loc) {
+ assert(IsSanitizerScope);
+
if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
!CGM.HasHiddenLTOVisibility(RD))
return;
@@ -2885,7 +2889,6 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
SanitizerMask::bitPosToMask(M), TypeName))
return;
- SanitizerScope SanScope(this);
EmitSanitizerStatReport(SSK);
llvm::Metadata *MD =
@@ -2942,11 +2945,11 @@ 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);
+ auto CheckOrdinal = SanitizerKind::SO_CFIVCall;
+ auto CheckHandler = SanitizerHandler::CFICheckFail;
+ SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
EmitSanitizerStatReport(llvm::SanStat_CFI_VCall);
- ApplyDebugLocation ApplyTrapDI(
- *this, SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIVCall));
llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
@@ -2965,8 +2968,7 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
if (SanOpts.has(SanitizerKind::CFIVCall) &&
!getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
TypeName)) {
- EmitCheck(std::make_pair(CheckResult, SanitizerKind::SO_CFIVCall),
- SanitizerHandler::CFICheckFail, {}, {});
+ EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler, {}, {});
}
return Builder.CreateBitCast(Builder.CreateExtractValue(CheckedLoad, 0),
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index fbcc330a..001b208 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -58,6 +58,13 @@
using namespace clang;
using namespace clang::CodeGen;
+// TODO: consider deprecating ClArrayBoundsPseudoFn; functionality is subsumed
+// by -fsanitize-annotate-debug-info
+static llvm::cl::opt<bool> ClArrayBoundsPseudoFn(
+ "array-bounds-pseudofn", llvm::cl::Hidden, llvm::cl::Optional,
+ llvm::cl::desc("Emit debug info that places array-bounds instrumentation "
+ "in an inline function called __ubsan_check_array_bounds."));
+
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx) {
auto TI = Ctx.getTypeInfo(Ty);
if (TI.isAlignRequired())
@@ -6412,3 +6419,78 @@ CodeGenFunction::LexicalScope::~LexicalScope() {
ForceCleanup();
}
}
+
+static std::string SanitizerHandlerToCheckLabel(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
+ };
+
+ // Label doesn't require sanitization
+ return Label;
+}
+
+static std::string
+SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal) {
+ std::string Label;
+ switch (Ordinal) {
+#define SANITIZER(NAME, ID) \
+ case SanitizerKind::SO_##ID: \
+ Label = "__ubsan_check_" NAME; \
+ break;
+#include "clang/Basic/Sanitizers.def"
+ default:
+ llvm_unreachable("unexpected sanitizer kind");
+ }
+
+ // Sanitize label (convert hyphens to underscores; also futureproof against
+ // non-alpha)
+ for (unsigned int i = 0; i < Label.length(); i++)
+ if (!std::isalpha(Label[i]))
+ Label[i] = '_';
+
+ return Label;
+}
+
+llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
+ ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+ SanitizerHandler Handler) {
+ std::string Label;
+ if (Ordinals.size() == 1)
+ Label = SanitizerOrdinalToCheckLabel(Ordinals[0]);
+ else
+ Label = SanitizerHandlerToCheckLabel(Handler);
+
+ llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
+
+ for (auto Ord : Ordinals) {
+ // TODO: deprecate ClArrayBoundsPseudoFn
+ if (((ClArrayBoundsPseudoFn && Ord == SanitizerKind::SO_ArrayBounds) ||
+ CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo.has(Ord)) &&
+ CheckDI) {
+ return getDebugInfo()->CreateSyntheticInlineAt(CheckDI, Label);
+ }
+ }
+
+ return CheckDI;
+}
+
+SanitizerDebugLocation::SanitizerDebugLocation(
+ CodeGenFunction *CGF, ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+ SanitizerHandler Handler)
+ : CGF(CGF),
+ Apply(*CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler)) {
+ assert(!CGF->IsSanitizerScope);
+ CGF->IsSanitizerScope = true;
+}
+
+SanitizerDebugLocation::~SanitizerDebugLocation() {
+ assert(CGF->IsSanitizerScope);
+ CGF->IsSanitizerScope = false;
+}
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 8558817..16759f2 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 @@ public:
~ApplyInlineDebugLocation();
};
+class SanitizerDebugLocation {
+ CodeGenFunction *CGF;
+ ApplyDebugLocation Apply;
+
+public:
+ SanitizerDebugLocation(CodeGenFunction *CGF,
+ ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+ SanitizerHandler Handler);
+ ~SanitizerDebugLocation();
+};
+
} // namespace CodeGen
} // namespace clang
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index e487a2b..04f13c7 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -766,14 +766,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);
+ auto CheckOrdinal = SanitizerKind::SO_NullabilityAssign;
+ auto CheckHandler = SanitizerHandler::TypeMismatch;
+ SanitizerDebugLocation 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, SanitizerKind::SO_NullabilityAssign}},
- SanitizerHandler::TypeMismatch, StaticData, RHS);
+ EmitCheck({{IsNotNull, CheckOrdinal}}, CheckHandler, StaticData, RHS);
}
void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 1099a54..6cb348f 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -65,13 +65,6 @@ llvm::cl::opt<bool> ClSanitizeGuardChecks(
} // namespace clang
-// TODO: consider deprecating ClArrayBoundsPseudoFn; functionality is subsumed
-// by -fsanitize-annotate-debug-info
-static llvm::cl::opt<bool> ClArrayBoundsPseudoFn(
- "array-bounds-pseudofn", llvm::cl::Hidden, llvm::cl::Optional,
- llvm::cl::desc("Emit debug info that places array-bounds instrumentation "
- "in an inline function called __ubsan_check_array_bounds."));
-
//===--------------------------------------------------------------------===//
// Defines for metadata
//===--------------------------------------------------------------------===//
@@ -751,104 +744,116 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
if (Ty.isVolatileQualified())
return;
- SanitizerScope SanScope(this);
-
- SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 3>
- Checks;
- llvm::BasicBlock *Done = nullptr;
-
// Quickly determine whether we have a pointer to an alloca. It's possible
// to skip null checks, and some alignment checks, for these pointers. This
// can reduce compile-time significantly.
auto PtrToAlloca = dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCasts());
- llvm::Value *True = llvm::ConstantInt::getTrue(getLLVMContext());
llvm::Value *IsNonNull = nullptr;
bool IsGuaranteedNonNull =
SkippedChecks.has(SanitizerKind::Null) || PtrToAlloca;
- bool AllowNullPointers = isNullPointerAllowed(TCK);
- if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
- !IsGuaranteedNonNull) {
- // The glvalue must not be an empty glvalue.
- IsNonNull = Builder.CreateIsNotNull(Ptr);
- // The IR builder can constant-fold the null check if the pointer points to
- // a constant.
- IsGuaranteedNonNull = IsNonNull == True;
-
- // Skip the null check if the pointer is known to be non-null.
- if (!IsGuaranteedNonNull) {
- if (AllowNullPointers) {
- // When performing pointer casts, it's OK if the value is null.
- // Skip the remaining checks in that case.
- Done = createBasicBlock("null");
- llvm::BasicBlock *Rest = createBasicBlock("not.null");
- Builder.CreateCondBr(IsNonNull, Rest, Done);
- EmitBlock(Rest);
- } else {
- Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::SO_Null));
+ llvm::BasicBlock *Done = nullptr;
+ bool DoneViaNullSanitize = false;
+
+ {
+ auto CheckHandler = SanitizerHandler::TypeMismatch;
+ SanitizerDebugLocation SanScope(this,
+ {SanitizerKind::SO_Null,
+ SanitizerKind::SO_ObjectSize,
+ SanitizerKind::SO_Alignment},
+ CheckHandler);
+
+ SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 3>
+ Checks;
+
+ llvm::Value *True = llvm::ConstantInt::getTrue(getLLVMContext());
+ bool AllowNullPointers = isNullPointerAllowed(TCK);
+ if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
+ !IsGuaranteedNonNull) {
+ // The glvalue must not be an empty glvalue.
+ IsNonNull = Builder.CreateIsNotNull(Ptr);
+
+ // The IR builder can constant-fold the null check if the pointer points
+ // to a constant.
+ IsGuaranteedNonNull = IsNonNull == True;
+
+ // Skip the null check if the pointer is known to be non-null.
+ if (!IsGuaranteedNonNull) {
+ if (AllowNullPointers) {
+ // When performing pointer casts, it's OK if the value is null.
+ // Skip the remaining checks in that case.
+ Done = createBasicBlock("null");
+ DoneViaNullSanitize = true;
+ llvm::BasicBlock *Rest = createBasicBlock("not.null");
+ Builder.CreateCondBr(IsNonNull, Rest, Done);
+ EmitBlock(Rest);
+ } else {
+ Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::SO_Null));
+ }
}
}
- }
- if (SanOpts.has(SanitizerKind::ObjectSize) &&
- !SkippedChecks.has(SanitizerKind::ObjectSize) &&
- !Ty->isIncompleteType()) {
- uint64_t TySize = CGM.getMinimumObjectSize(Ty).getQuantity();
- llvm::Value *Size = llvm::ConstantInt::get(IntPtrTy, TySize);
- if (ArraySize)
- Size = Builder.CreateMul(Size, ArraySize);
-
- // Degenerate case: new X[0] does not need an objectsize check.
- llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
- if (!ConstantSize || !ConstantSize->isNullValue()) {
- // The glvalue must refer to a large enough storage region.
- // FIXME: If Address Sanitizer is enabled, insert dynamic instrumentation
- // to check this.
- // FIXME: Get object address space
- llvm::Type *Tys[2] = { IntPtrTy, Int8PtrTy };
- llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
- llvm::Value *Min = Builder.getFalse();
- llvm::Value *NullIsUnknown = Builder.getFalse();
- llvm::Value *Dynamic = Builder.getFalse();
- llvm::Value *LargeEnough = Builder.CreateICmpUGE(
- Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}), Size);
- Checks.push_back(
- std::make_pair(LargeEnough, SanitizerKind::SO_ObjectSize));
+ if (SanOpts.has(SanitizerKind::ObjectSize) &&
+ !SkippedChecks.has(SanitizerKind::ObjectSize) &&
+ !Ty->isIncompleteType()) {
+ uint64_t TySize = CGM.getMinimumObjectSize(Ty).getQuantity();
+ llvm::Value *Size = llvm::ConstantInt::get(IntPtrTy, TySize);
+ if (ArraySize)
+ Size = Builder.CreateMul(Size, ArraySize);
+
+ // Degenerate case: new X[0] does not need an objectsize check.
+ llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
+ if (!ConstantSize || !ConstantSize->isNullValue()) {
+ // The glvalue must refer to a large enough storage region.
+ // FIXME: If Address Sanitizer is enabled, insert dynamic
+ // instrumentation
+ // to check this.
+ // FIXME: Get object address space
+ llvm::Type *Tys[2] = {IntPtrTy, Int8PtrTy};
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
+ llvm::Value *Min = Builder.getFalse();
+ llvm::Value *NullIsUnknown = Builder.getFalse();
+ llvm::Value *Dynamic = Builder.getFalse();
+ llvm::Value *LargeEnough = Builder.CreateICmpUGE(
+ Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}), Size);
+ Checks.push_back(
+ std::make_pair(LargeEnough, SanitizerKind::SO_ObjectSize));
+ }
}
- }
- llvm::MaybeAlign AlignVal;
- llvm::Value *PtrAsInt = nullptr;
-
- if (SanOpts.has(SanitizerKind::Alignment) &&
- !SkippedChecks.has(SanitizerKind::Alignment)) {
- AlignVal = Alignment.getAsMaybeAlign();
- if (!Ty->isIncompleteType() && !AlignVal)
- AlignVal = CGM.getNaturalTypeAlignment(Ty, nullptr, nullptr,
- /*ForPointeeType=*/true)
- .getAsMaybeAlign();
-
- // The glvalue must be suitably aligned.
- if (AlignVal && *AlignVal > llvm::Align(1) &&
- (!PtrToAlloca || PtrToAlloca->getAlign() < *AlignVal)) {
- PtrAsInt = Builder.CreatePtrToInt(Ptr, IntPtrTy);
- llvm::Value *Align = Builder.CreateAnd(
- PtrAsInt, llvm::ConstantInt::get(IntPtrTy, AlignVal->value() - 1));
- llvm::Value *Aligned =
- Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0));
- if (Aligned != True)
- Checks.push_back(std::make_pair(Aligned, SanitizerKind::SO_Alignment));
+ llvm::MaybeAlign AlignVal;
+ llvm::Value *PtrAsInt = nullptr;
+
+ if (SanOpts.has(SanitizerKind::Alignment) &&
+ !SkippedChecks.has(SanitizerKind::Alignment)) {
+ AlignVal = Alignment.getAsMaybeAlign();
+ if (!Ty->isIncompleteType() && !AlignVal)
+ AlignVal = CGM.getNaturalTypeAlignment(Ty, nullptr, nullptr,
+ /*ForPointeeType=*/true)
+ .getAsMaybeAlign();
+
+ // The glvalue must be suitably aligned.
+ if (AlignVal && *AlignVal > llvm::Align(1) &&
+ (!PtrToAlloca || PtrToAlloca->getAlign() < *AlignVal)) {
+ PtrAsInt = Builder.CreatePtrToInt(Ptr, IntPtrTy);
+ llvm::Value *Align = Builder.CreateAnd(
+ PtrAsInt, llvm::ConstantInt::get(IntPtrTy, AlignVal->value() - 1));
+ llvm::Value *Aligned =
+ Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0));
+ if (Aligned != True)
+ Checks.push_back(
+ std::make_pair(Aligned, SanitizerKind::SO_Alignment));
+ }
}
- }
- if (Checks.size() > 0) {
- llvm::Constant *StaticData[] = {
- EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(Ty),
- llvm::ConstantInt::get(Int8Ty, AlignVal ? llvm::Log2(*AlignVal) : 1),
- llvm::ConstantInt::get(Int8Ty, TCK)};
- EmitCheck(Checks, SanitizerHandler::TypeMismatch, 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);
}
@@ -1227,10 +1240,9 @@ 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));
+ auto CheckHandler = SanitizerHandler::OutOfBounds;
+ SanitizerDebugLocation SanScope(this, {CheckKind}, CheckHandler);
bool IndexSigned = IndexType->isSignedIntegerOrEnumerationType();
llvm::Value *IndexVal = Builder.CreateIntCast(Index, SizeTy, IndexSigned);
@@ -1243,37 +1255,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, CheckKind), SanitizerHandler::OutOfBounds,
- StaticData, Index);
-}
-
-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] = '_';
-
- 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);
-
- return CheckDI;
+ EmitCheck(std::make_pair(Check, CheckKind), CheckHandler, StaticData, Index);
}
CodeGenFunction::ComplexPairTy CodeGenFunction::
@@ -1997,8 +1979,12 @@ 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);
+ auto CheckHandler = SanitizerHandler::LoadInvalidValue;
+ SanitizerDebugLocation SanScope(this, {Kind}, CheckHandler);
llvm::Value *Check;
--End;
if (!Min) {
@@ -2012,10 +1998,7 @@ 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);
+ EmitCheck(std::make_pair(Check, Kind), CheckHandler, StaticArgs, Value);
return true;
}
@@ -3938,7 +3921,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() {
- SanitizerScope SanScope(this);
+ 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.
+ SanitizerDebugLocation SanScope(
+ 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);
@@ -4001,8 +3994,6 @@ void CodeGenFunction::EmitCfiCheckFail() {
{Addr, AllVtables}),
IntPtrTy);
- // TODO: the instructions above are not annotated with debug info. It is
- // inconvenient to do so because we have not determined SanitizerKind yet.
const std::pair<int, SanitizerKind::SanitizerOrdinal> CheckKinds[] = {
{CFITCK_VCall, SanitizerKind::SO_CFIVCall},
{CFITCK_NVCall, SanitizerKind::SO_CFINVCall},
@@ -4014,7 +4005,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));
@@ -4026,7 +4018,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();
@@ -4037,11 +4029,12 @@ void CodeGenFunction::EmitCfiCheckFail() {
void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
if (SanOpts.has(SanitizerKind::Unreachable)) {
- SanitizerScope SanScope(this);
+ auto CheckOrdinal = SanitizerKind::SO_Unreachable;
+ auto CheckHandler = SanitizerHandler::BuiltinUnreachable;
+ SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
- SanitizerKind::SO_Unreachable),
- SanitizerHandler::BuiltinUnreachable,
- EmitCheckSourceLocation(Loc), {});
+ CheckOrdinal),
+ CheckHandler, EmitCheckSourceLocation(Loc), {});
}
Builder.CreateUnreachable();
}
@@ -6303,7 +6296,9 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
!isa<FunctionNoProtoType>(PointeeType)) {
if (llvm::Constant *PrefixSig =
CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
- SanitizerScope SanScope(this);
+ auto CheckOrdinal = SanitizerKind::SO_Function;
+ auto CheckHandler = SanitizerHandler::FunctionTypeMismatch;
+ SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
auto *TypeHash = getUBSanFunctionTypeHash(PointeeType);
llvm::Type *PrefixSigType = PrefixSig->getType();
@@ -6363,9 +6358,8 @@ 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),
- SanitizerHandler::FunctionTypeMismatch, StaticData,
- {CalleePtr});
+ EmitCheck(std::make_pair(CalleeTypeHashMatch, CheckOrdinal), CheckHandler,
+ StaticData, {CalleePtr});
Builder.CreateBr(Cont);
EmitBlock(Cont);
@@ -6385,10 +6379,10 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
// function pointer is a member of the bit set for the function type.
if (SanOpts.has(SanitizerKind::CFIICall) &&
(!TargetDecl || !isa<FunctionDecl>(TargetDecl)) && !CFIUnchecked) {
- SanitizerScope SanScope(this);
+ auto CheckOrdinal = SanitizerKind::SO_CFIICall;
+ auto CheckHandler = SanitizerHandler::CFICheckFail;
+ SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
EmitSanitizerStatReport(llvm::SanStat_CFI_ICall);
- ApplyDebugLocation ApplyTrapDI(
- *this, SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIICall));
llvm::Metadata *MD;
if (CGM.getCodeGenOpts().SanitizeCfiICallGeneralizePointers)
@@ -6409,12 +6403,11 @@ 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),
- 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 111b580..193710b 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -999,7 +999,9 @@ void ScalarExprEmitter::EmitFloatConversionCheck(
if (!isa<llvm::IntegerType>(DstTy))
return;
- CodeGenFunction::SanitizerScope SanScope(&CGF);
+ auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
+ auto CheckHandler = SanitizerHandler::FloatCastOverflow;
+ SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
using llvm::APFloat;
using llvm::APSInt;
@@ -1056,8 +1058,8 @@ void ScalarExprEmitter::EmitFloatConversionCheck(
llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc),
CGF.EmitCheckTypeDescriptor(OrigSrcType),
CGF.EmitCheckTypeDescriptor(DstType)};
- CGF.EmitCheck(std::make_pair(Check, SanitizerKind::SO_FloatCastOverflow),
- SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
+ CGF.EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
+ OrigSrc);
}
// Should be called within CodeGenFunction::SanitizerScope RAII scope.
@@ -1134,18 +1136,31 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
(!SrcSigned && DstSigned))
return;
- CodeGenFunction::SanitizerScope SanScope(&CGF);
-
std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
- Check =
- EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
- // If the comparison result is 'i1 false', then the truncation was lossy.
+ Check;
+
+ auto CheckHandler = SanitizerHandler::ImplicitConversion;
+ {
+ // We don't know the check kind until we call
+ // EmitIntegerTruncationCheckHelper, but we want to annotate
+ // EmitIntegerTruncationCheckHelper's instructions too.
+ SanitizerDebugLocation SanScope(
+ &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.
+ }
// Do we care about this type of truncation?
if (!CGF.SanOpts.has(Check.second.second))
return;
+ SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
+
// Does some SSCL ignore this type?
if (CGF.getContext().isTypeIgnoredBySanitizer(
SanitizerMask::bitPosToMask(Check.second.second), DstType))
@@ -1157,8 +1172,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,
@@ -1272,7 +1286,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.
- CodeGenFunction::SanitizerScope SanScope(&CGF);
+ auto CheckHandler = SanitizerHandler::ImplicitConversion;
+ SanitizerDebugLocation SanScope(
+ &CGF,
+ {SanitizerKind::SO_ImplicitIntegerSignChange,
+ SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
+ SanitizerKind::SO_ImplicitSignedIntegerTruncation},
+ CheckHandler);
std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
@@ -1308,8 +1328,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.
@@ -1393,7 +1412,9 @@ void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType,
bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
- CodeGenFunction::SanitizerScope SanScope(this);
+ auto CheckHandler = SanitizerHandler::ImplicitConversion;
+ SanitizerDebugLocation SanScope(
+ this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
@@ -1439,8 +1460,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,
@@ -3975,7 +3995,11 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
{
- CodeGenFunction::SanitizerScope SanScope(&CGF);
+ SanitizerDebugLocation SanScope(&CGF,
+ {SanitizerKind::SO_IntegerDivideByZero,
+ SanitizerKind::SO_SignedIntegerOverflow,
+ SanitizerKind::SO_FloatDivideByZero},
+ SanitizerHandler::DivremOverflow);
if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
Ops.Ty->isIntegerType() &&
@@ -4029,7 +4053,10 @@ Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
Ops.Ty->isIntegerType() &&
(Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
- CodeGenFunction::SanitizerScope SanScope(&CGF);
+ SanitizerDebugLocation SanScope(&CGF,
+ {SanitizerKind::SO_IntegerDivideByZero,
+ SanitizerKind::SO_SignedIntegerOverflow},
+ SanitizerHandler::DivremOverflow);
llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
}
@@ -4078,7 +4105,10 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
if (isSigned)
OpID |= 1;
- CodeGenFunction::SanitizerScope SanScope(&CGF);
+ 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);
@@ -4204,7 +4234,9 @@ 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);
+ auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
+ auto CheckHandler = SanitizerHandler::PointerOverflow;
+ SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
Value *IsZeroIndex = CGF.Builder.CreateIsNull(index);
llvm::Constant *StaticArgs[] = {
CGF.EmitCheckSourceLocation(op.E->getExprLoc())};
@@ -4212,8 +4244,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}},
- SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
+ CGF.EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
+ DynamicArgs);
return Ptr;
}
@@ -4734,7 +4766,16 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
RHS = ConstrainShiftValue(Ops.LHS, RHS, "shl.mask");
else if ((SanitizeBase || SanitizeExponent) &&
isa<llvm::IntegerType>(Ops.LHS->getType())) {
- CodeGenFunction::SanitizerScope SanScope(&CGF);
+ SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
+ if (SanitizeSignedBase)
+ Ordinals.push_back(SanitizerKind::SO_ShiftBase);
+ if (SanitizeUnsignedBase)
+ Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
+ if (SanitizeExponent)
+ Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
+
+ SanitizerDebugLocation SanScope(&CGF, Ordinals,
+ SanitizerHandler::ShiftOutOfBounds);
SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
llvm::Value *WidthMinusOne =
@@ -4805,7 +4846,8 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
RHS = ConstrainShiftValue(Ops.LHS, RHS, "shr.mask");
else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) &&
isa<llvm::IntegerType>(Ops.LHS->getType())) {
- CodeGenFunction::SanitizerScope SanScope(&CGF);
+ 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));
@@ -6037,7 +6079,9 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
const auto &DL = CGM.getDataLayout();
- SanitizerScope SanScope(this);
+ auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
+ auto CheckHandler = SanitizerHandler::PointerOverflow;
+ SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
GEPOffsetAndOverflow EvaluatedGEP =
@@ -6074,7 +6118,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) {
@@ -6110,7 +6154,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.");
@@ -6118,7 +6162,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 ff1dae7..8a1b44a 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1968,7 +1968,9 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
const ObjCInterfaceType *InterfaceTy =
ObjPtrTy ? ObjPtrTy->getInterfaceType() : nullptr;
if (InterfaceTy) {
- SanitizerScope SanScope(this);
+ auto CheckOrdinal = SanitizerKind::SO_ObjCCast;
+ auto CheckHandler = SanitizerHandler::InvalidObjCCast;
+ SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
auto &C = CGM.getContext();
assert(InterfaceTy->getDecl() && "No decl for ObjC interface type");
Selector IsKindOfClassSel = GetUnarySelector("isKindOfClass", C);
@@ -1985,8 +1987,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}}, CheckHandler,
ArrayRef<llvm::Constant *>(StaticData), CurrentItem);
}
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 3302abad..5656200 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1636,10 +1636,11 @@ 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);
+ auto CheckOrdinal = SanitizerKind::SO_Return;
+ auto CheckHandler = SanitizerHandler::MissingReturn;
+ SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
llvm::Value *IsFalse = Builder.getFalse();
- EmitCheck(std::make_pair(IsFalse, SanitizerKind::SO_Return),
- SanitizerHandler::MissingReturn,
+ EmitCheck(std::make_pair(IsFalse, CheckOrdinal), CheckHandler,
EmitCheckSourceLocation(FD->getLocation()), {});
} else if (ShouldEmitUnreachable) {
if (CGM.getCodeGenOpts().OptimizationLevel == 0)
@@ -2541,7 +2542,9 @@ 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);
+ auto CheckOrdinal = SanitizerKind::SO_VLABound;
+ auto CheckHandler = SanitizerHandler::VLABoundNotPositive;
+ SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
llvm::Value *Zero = llvm::Constant::getNullValue(size->getType());
clang::QualType SEType = sizeExpr->getType();
llvm::Value *CheckCondition =
@@ -2551,9 +2554,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),
+ CheckHandler, StaticArgs, size);
}
// Always zexting here would be wrong if it weren't
@@ -3196,7 +3198,9 @@ void CodeGenFunction::emitAlignmentAssumptionCheck(
Assumption->removeFromParent();
{
- SanitizerScope SanScope(this);
+ auto CheckOrdinal = SanitizerKind::SO_Alignment;
+ auto CheckHandler = SanitizerHandler::AlignmentAssumption;
+ SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
if (!OffsetValue)
OffsetValue = Builder.getInt1(false); // no offset.
@@ -3205,8 +3209,8 @@ void CodeGenFunction::emitAlignmentAssumptionCheck(
EmitCheckSourceLocation(SecondaryLoc),
EmitCheckTypeDescriptor(Ty)};
llvm::Value *DynamicData[] = {Ptr, Alignment, OffsetValue};
- EmitCheck({std::make_pair(TheCheck, SanitizerKind::SO_Alignment)},
- 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 cecc8c0..a5ab9df 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3332,10 +3332,12 @@ public:
llvm::Value *Index, QualType IndexType,
QualType IndexedType, bool Accessed);
- /// Returns debug info, with additional annotation if enabled by
- /// CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[CheckKindOrdinal].
+ /// Returns debug info, with additional annotation if
+ /// CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[Ordinal] is enabled for
+ /// any of the ordinals.
llvm::DILocation *
- SanitizerAnnotateDebugInfo(SanitizerKind::SanitizerOrdinal CheckKindOrdinal);
+ SanitizerAnnotateDebugInfo(ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+ SanitizerHandler Handler);
llvm::Value *GetCountedByFieldExprGEP(const Expr *Base, const FieldDecl *FD,
const FieldDecl *CountDecl);
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index aac7bb7..f4a9946 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -713,9 +713,9 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
llvm::Value *VirtualFn = nullptr;
{
- CodeGenFunction::SanitizerScope SanScope(&CGF);
- ApplyDebugLocation ApplyTrapDI(
- CGF, CGF.SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIMFCall));
+ auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
+ auto CheckHandler = SanitizerHandler::CFICheckFail;
+ SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
llvm::Value *TypeId = nullptr;
llvm::Value *CheckResult = nullptr;
@@ -785,16 +785,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, SanitizerKind::SO_CFIMFCall),
- SanitizerHandler::CFICheckFail, StaticData,
- {VTable, ValidVtable});
+ CGF.EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler,
+ StaticData, {VTable, ValidVtable});
}
FnVirtual = Builder.GetInsertBlock();
@@ -813,9 +812,9 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
if (ShouldEmitCFICheck) {
CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
if (RD->hasDefinition()) {
- CodeGenFunction::SanitizerScope SanScope(&CGF);
- ApplyDebugLocation ApplyTrapDI(
- CGF, CGF.SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIMFCall));
+ auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
+ auto CheckHandler = SanitizerHandler::CFICheckFail;
+ SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
llvm::Constant *StaticData[] = {
llvm::ConstantInt::get(CGF.Int8Ty, CodeGenFunction::CFITCK_NVMFCall),
@@ -838,8 +837,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
Bit = Builder.CreateOr(Bit, TypeTest);
}
- CGF.EmitCheck(std::make_pair(Bit, SanitizerKind::SO_CFIMFCall),
- SanitizerHandler::CFICheckFail, StaticData,
+ CGF.EmitCheck(std::make_pair(Bit, CheckOrdinal), CheckHandler, StaticData,
{NonVirtualFn, llvm::UndefValue::get(CGF.IntPtrTy)});
FnNonVirtual = Builder.GetInsertBlock();