-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[cfi] Enable -fsanitize-annotate-debug-info functionality for CFI checks #139809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Thurston Dang (thurstond) ChangesThis connects the -fsanitize-annotate-debug-info plumbing (#138577) to CFI check codegen. Updates the tests from #139149. A side effect is that "__ubsan_check_array_bounds" is renamed to "__ubsan_check_array-bounds". This affects clang/test/CodeGen/bounds-checking-debuginfo.c from #128977 Patch is 35.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/139809.diff 8 Files Affected:
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index befbfc64a680c..232965f8f0a84 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2779,6 +2779,36 @@ void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD,
}
}
+void CodeGenFunction::ParseCFITypeCheckKind(CFITypeCheckKind TCK,
+ SanitizerKind::SanitizerOrdinal &M,
+ llvm::SanitizerStatKind &SSK) {
+ switch (TCK) {
+ case CFITCK_VCall:
+ M = SanitizerKind::SO_CFIVCall;
+ SSK = llvm::SanStat_CFI_VCall;
+ break;
+ case CFITCK_NVCall:
+ M = SanitizerKind::SO_CFINVCall;
+ SSK = llvm::SanStat_CFI_NVCall;
+ break;
+ case CFITCK_DerivedCast:
+ M = SanitizerKind::SO_CFIDerivedCast;
+ SSK = llvm::SanStat_CFI_DerivedCast;
+ break;
+ case CFITCK_UnrelatedCast:
+ M = SanitizerKind::SO_CFIUnrelatedCast;
+ SSK = llvm::SanStat_CFI_UnrelatedCast;
+ break;
+ case CFITCK_ICall:
+ M = SanitizerKind::SO_CFIICall;
+ SSK = llvm::SanStat_CFI_ICall;
+ break;
+ case CFITCK_NVMFCall:
+ case CFITCK_VMFCall:
+ llvm_unreachable("unexpected sanitizer kind");
+ }
+}
+
void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
llvm::Value *VTable,
CFITypeCheckKind TCK,
@@ -2786,6 +2816,10 @@ void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
if (!SanOpts.has(SanitizerKind::CFICastStrict))
RD = LeastDerivedClassWithSameLayout(RD);
+ SanitizerKind::SanitizerOrdinal Ordinal;
+ llvm::SanitizerStatKind SSK;
+ ParseCFITypeCheckKind(TCK, Ordinal, SSK);
+ ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(Ordinal));
EmitVTablePtrCheck(RD, VTable, TCK, Loc);
}
@@ -2808,6 +2842,11 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived,
if (!SanOpts.has(SanitizerKind::CFICastStrict))
ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl);
+ SanitizerKind::SanitizerOrdinal Ordinal;
+ llvm::SanitizerStatKind SSK;
+ ParseCFITypeCheckKind(TCK, Ordinal, SSK);
+ ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(Ordinal));
+
llvm::BasicBlock *ContBlock = nullptr;
if (MayBeNull) {
@@ -2844,22 +2883,12 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
SanitizerKind::SanitizerOrdinal M;
llvm::SanitizerStatKind SSK;
+ ParseCFITypeCheckKind(TCK, M, SSK);
switch (TCK) {
case CFITCK_VCall:
- M = SanitizerKind::SO_CFIVCall;
- SSK = llvm::SanStat_CFI_VCall;
- break;
case CFITCK_NVCall:
- M = SanitizerKind::SO_CFINVCall;
- SSK = llvm::SanStat_CFI_NVCall;
- break;
case CFITCK_DerivedCast:
- M = SanitizerKind::SO_CFIDerivedCast;
- SSK = llvm::SanStat_CFI_DerivedCast;
- break;
case CFITCK_UnrelatedCast:
- M = SanitizerKind::SO_CFIUnrelatedCast;
- SSK = llvm::SanStat_CFI_UnrelatedCast;
break;
case CFITCK_ICall:
case CFITCK_NVMFCall:
@@ -2932,6 +2961,8 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
SanitizerScope SanScope(this);
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/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 0d03923951a16..8519584c1f081 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1217,6 +1217,30 @@ void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,
EmitBoundsCheckImpl(E, Bound, Index, IndexType, IndexedType, Accessed);
}
+llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
+ SanitizerKind::SanitizerOrdinal CheckKindOrdinal) {
+ StringRef 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");
+ }
+
+ 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;
+}
+
void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
llvm::Value *Index,
QualType IndexType,
@@ -1225,17 +1249,8 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
return;
SanitizerScope SanScope(this);
-
- llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
auto CheckKind = SanitizerKind::SO_ArrayBounds;
- // TODO: deprecate ClArrayBoundsPseudoFn
- if ((ClArrayBoundsPseudoFn ||
- CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo.has(CheckKind)) &&
- CheckDI) {
- CheckDI = getDebugInfo()->CreateSyntheticInlineAt(
- Builder.getCurrentDebugLocation(), "__ubsan_check_array_bounds");
- }
- ApplyDebugLocation ApplyTrapDI(*this, CheckDI);
+ ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(CheckKind));
bool IndexSigned = IndexType->isSignedIntegerOrEnumerationType();
llvm::Value *IndexVal = Builder.CreateIntCast(Index, SizeTy, IndexSigned);
@@ -3950,6 +3965,8 @@ void CodeGenFunction::EmitCfiCheckFail() {
{Addr, AllVtables}),
IntPtrTy);
+ // TODO: the instructions above are not annotated with debug info. It is
+ // inconvenient to do so because we hadn't determined the SanitizerKind yet.
const std::pair<int, SanitizerKind::SanitizerOrdinal> CheckKinds[] = {
{CFITCK_VCall, SanitizerKind::SO_CFIVCall},
{CFITCK_NVCall, SanitizerKind::SO_CFINVCall},
@@ -3960,6 +3977,9 @@ void CodeGenFunction::EmitCfiCheckFail() {
for (auto CheckKindOrdinalPair : CheckKinds) {
int Kind = CheckKindOrdinalPair.first;
SanitizerKind::SanitizerOrdinal Ordinal = CheckKindOrdinalPair.second;
+
+ ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(Ordinal));
+
llvm::Value *Cond =
Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(Int8Ty, Kind));
if (CGM.getLangOpts().Sanitize.has(Ordinal))
@@ -6245,6 +6265,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
(!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
SanitizerScope SanScope(this);
EmitSanitizerStatReport(llvm::SanStat_CFI_ICall);
+ ApplyDebugLocation ApplyTrapDI(
+ *this, SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIICall));
llvm::Metadata *MD;
if (CGM.getCodeGenOpts().SanitizeCfiICallGeneralizePointers)
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index c0bc3825f0188..ab36e0965d6fe 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3353,6 +3353,17 @@ class CodeGenFunction : public CodeGenTypeCache {
SanitizerSet SkippedChecks = SanitizerSet(),
llvm::Value *ArraySize = nullptr);
+ /// Returns debug info, with additional annotation if enabled by
+ /// CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[CheckKindOrdinal].
+ llvm::DILocation *
+ SanitizerAnnotateDebugInfo(SanitizerKind::SanitizerOrdinal CheckKindOrdinal);
+
+ /// Converts the CFITypeCheckKind into SanitizerKind::SanitizerOrdinal and
+ /// llvm::SanitizerStatKind.
+ void ParseCFITypeCheckKind(CFITypeCheckKind TCK,
+ SanitizerKind::SanitizerOrdinal &M,
+ llvm::SanitizerStatKind &SSK);
+
/// Emit a check that \p Base points into an array object, which
/// we can access at index \p Index. \p Accessed should be \c false if we
/// this expression is used as an lvalue, for instance in "&Arr[Idx]".
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 70b53be7e77a3..df12425ee46f9 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -703,6 +703,9 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
{
CodeGenFunction::SanitizerScope SanScope(&CGF);
+ ApplyDebugLocation ApplyTrapDI(
+ CGF, CGF.SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIMFCall));
+
llvm::Value *TypeId = nullptr;
llvm::Value *CheckResult = nullptr;
@@ -792,14 +795,16 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
// In the non-virtual path, the function pointer is actually a
// function pointer.
CGF.EmitBlock(FnNonVirtual);
+
llvm::Value *NonVirtualFn =
Builder.CreateIntToPtr(FnAsInt, CGF.UnqualPtrTy, "memptr.nonvirtualfn");
-
// Check the function pointer if CFI on member function pointers is enabled.
if (ShouldEmitCFICheck) {
CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
if (RD->hasDefinition()) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
+ ApplyDebugLocation ApplyTrapDI(
+ CGF, CGF.SanitizerAnnotateDebugInfo(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..1549b02938697 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_array_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}
@@ -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_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 cd5ec567cb01b..7100a42fef886 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 [[META21:![0-9]+]]
-// CHECK-NEXT: br i1 [[TMP0]], label %[[CFI_CONT:.*]], label %[[CFI_SLOWPATH:.*]], !dbg [[DBG20]], !prof [[PROF22:![0-9]+]], !nosanitize [[META21]]
+// 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 [[META21]]
-// CHECK-NEXT: br label %[[CFI_CONT]], !dbg [[DBG20]], !nosanitize [[META21]]
+// 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 [[DBG20]]
-// CHECK-NEXT: ret void, !dbg [[DBG23:![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();
@@ -38,8 +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: 23, column: 3, scope: [[DBG7]])
-// CHECK: [[META21]] = !{}
-// CHECK: [[PROF22]] = !{!"branch_weights", i32 1048575, i32 1}
-// CHECK: [[DBG23]] = !DILocation(line: 24, column: 1, 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: [[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]])
//.
diff --git a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
index 8b184528889a0..e47f058e2c633 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 [[META35:![0-9]+]]
-// UNGENERALIZED-NEXT: br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF36:![0-9]+]], !nosanitize [[META35]]
+// 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 [[META35]]
-// UNGENERALIZED-NEXT: unreachable, !dbg [[DBG34]], !nosanitize [[META35]]
+// 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 [[DBG34]]
-// UNGENERALIZED-NEXT: ret void, !dbg [[DBG37:![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 [[META35:![0-9]+]]
-// GENERALIZED-NEXT: br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF36:![0-9]+]], !nosanitize [[META35]]
+// 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 [[META35]]
-// GENERALIZED-NEXT: unreachable, !dbg [[DBG34]], !nosanitize [[META35]]
+// 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 [[DBG34]]
-// GENERALIZED-NEXT: ret void, !dbg [[DBG37:![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);
@@ -84,10 +84,13 @@ 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: 53, column: 3, scope: [[DBG25]])
-// UNGENERALIZED: [[META35]] = !{}
-// UNGENERALIZED: [[PROF36]] = !{!"branch_weights", i32 1048575, i32 1}
-// UNGENERALIZED: [[DBG37]] = !DILocation(line: 54, column: 1, 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: [[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]])
//.
// GENERALIZED: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: [[META2:![0-9]+]], splitDebugIn...
[truncated]
|
@llvm/pr-subscribers-clang-codegen Author: Thurston Dang (thurstond) ChangesThis connects the -fsanitize-annotate-debug-info plumbing (#138577) to CFI check codegen. Updates the tests from #139149. A side effect is that "__ubsan_check_array_bounds" is renamed to "__ubsan_check_array-bounds". This affects clang/test/CodeGen/bounds-checking-debuginfo.c from #128977 Patch is 35.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/139809.diff 8 Files Affected:
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index befbfc64a680c..232965f8f0a84 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2779,6 +2779,36 @@ void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD,
}
}
+void CodeGenFunction::ParseCFITypeCheckKind(CFITypeCheckKind TCK,
+ SanitizerKind::SanitizerOrdinal &M,
+ llvm::SanitizerStatKind &SSK) {
+ switch (TCK) {
+ case CFITCK_VCall:
+ M = SanitizerKind::SO_CFIVCall;
+ SSK = llvm::SanStat_CFI_VCall;
+ break;
+ case CFITCK_NVCall:
+ M = SanitizerKind::SO_CFINVCall;
+ SSK = llvm::SanStat_CFI_NVCall;
+ break;
+ case CFITCK_DerivedCast:
+ M = SanitizerKind::SO_CFIDerivedCast;
+ SSK = llvm::SanStat_CFI_DerivedCast;
+ break;
+ case CFITCK_UnrelatedCast:
+ M = SanitizerKind::SO_CFIUnrelatedCast;
+ SSK = llvm::SanStat_CFI_UnrelatedCast;
+ break;
+ case CFITCK_ICall:
+ M = SanitizerKind::SO_CFIICall;
+ SSK = llvm::SanStat_CFI_ICall;
+ break;
+ case CFITCK_NVMFCall:
+ case CFITCK_VMFCall:
+ llvm_unreachable("unexpected sanitizer kind");
+ }
+}
+
void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
llvm::Value *VTable,
CFITypeCheckKind TCK,
@@ -2786,6 +2816,10 @@ void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
if (!SanOpts.has(SanitizerKind::CFICastStrict))
RD = LeastDerivedClassWithSameLayout(RD);
+ SanitizerKind::SanitizerOrdinal Ordinal;
+ llvm::SanitizerStatKind SSK;
+ ParseCFITypeCheckKind(TCK, Ordinal, SSK);
+ ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(Ordinal));
EmitVTablePtrCheck(RD, VTable, TCK, Loc);
}
@@ -2808,6 +2842,11 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived,
if (!SanOpts.has(SanitizerKind::CFICastStrict))
ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl);
+ SanitizerKind::SanitizerOrdinal Ordinal;
+ llvm::SanitizerStatKind SSK;
+ ParseCFITypeCheckKind(TCK, Ordinal, SSK);
+ ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(Ordinal));
+
llvm::BasicBlock *ContBlock = nullptr;
if (MayBeNull) {
@@ -2844,22 +2883,12 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
SanitizerKind::SanitizerOrdinal M;
llvm::SanitizerStatKind SSK;
+ ParseCFITypeCheckKind(TCK, M, SSK);
switch (TCK) {
case CFITCK_VCall:
- M = SanitizerKind::SO_CFIVCall;
- SSK = llvm::SanStat_CFI_VCall;
- break;
case CFITCK_NVCall:
- M = SanitizerKind::SO_CFINVCall;
- SSK = llvm::SanStat_CFI_NVCall;
- break;
case CFITCK_DerivedCast:
- M = SanitizerKind::SO_CFIDerivedCast;
- SSK = llvm::SanStat_CFI_DerivedCast;
- break;
case CFITCK_UnrelatedCast:
- M = SanitizerKind::SO_CFIUnrelatedCast;
- SSK = llvm::SanStat_CFI_UnrelatedCast;
break;
case CFITCK_ICall:
case CFITCK_NVMFCall:
@@ -2932,6 +2961,8 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
SanitizerScope SanScope(this);
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/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 0d03923951a16..8519584c1f081 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1217,6 +1217,30 @@ void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,
EmitBoundsCheckImpl(E, Bound, Index, IndexType, IndexedType, Accessed);
}
+llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
+ SanitizerKind::SanitizerOrdinal CheckKindOrdinal) {
+ StringRef 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");
+ }
+
+ 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;
+}
+
void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
llvm::Value *Index,
QualType IndexType,
@@ -1225,17 +1249,8 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
return;
SanitizerScope SanScope(this);
-
- llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
auto CheckKind = SanitizerKind::SO_ArrayBounds;
- // TODO: deprecate ClArrayBoundsPseudoFn
- if ((ClArrayBoundsPseudoFn ||
- CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo.has(CheckKind)) &&
- CheckDI) {
- CheckDI = getDebugInfo()->CreateSyntheticInlineAt(
- Builder.getCurrentDebugLocation(), "__ubsan_check_array_bounds");
- }
- ApplyDebugLocation ApplyTrapDI(*this, CheckDI);
+ ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(CheckKind));
bool IndexSigned = IndexType->isSignedIntegerOrEnumerationType();
llvm::Value *IndexVal = Builder.CreateIntCast(Index, SizeTy, IndexSigned);
@@ -3950,6 +3965,8 @@ void CodeGenFunction::EmitCfiCheckFail() {
{Addr, AllVtables}),
IntPtrTy);
+ // TODO: the instructions above are not annotated with debug info. It is
+ // inconvenient to do so because we hadn't determined the SanitizerKind yet.
const std::pair<int, SanitizerKind::SanitizerOrdinal> CheckKinds[] = {
{CFITCK_VCall, SanitizerKind::SO_CFIVCall},
{CFITCK_NVCall, SanitizerKind::SO_CFINVCall},
@@ -3960,6 +3977,9 @@ void CodeGenFunction::EmitCfiCheckFail() {
for (auto CheckKindOrdinalPair : CheckKinds) {
int Kind = CheckKindOrdinalPair.first;
SanitizerKind::SanitizerOrdinal Ordinal = CheckKindOrdinalPair.second;
+
+ ApplyDebugLocation ApplyTrapDI(*this, SanitizerAnnotateDebugInfo(Ordinal));
+
llvm::Value *Cond =
Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(Int8Ty, Kind));
if (CGM.getLangOpts().Sanitize.has(Ordinal))
@@ -6245,6 +6265,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
(!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
SanitizerScope SanScope(this);
EmitSanitizerStatReport(llvm::SanStat_CFI_ICall);
+ ApplyDebugLocation ApplyTrapDI(
+ *this, SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIICall));
llvm::Metadata *MD;
if (CGM.getCodeGenOpts().SanitizeCfiICallGeneralizePointers)
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index c0bc3825f0188..ab36e0965d6fe 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3353,6 +3353,17 @@ class CodeGenFunction : public CodeGenTypeCache {
SanitizerSet SkippedChecks = SanitizerSet(),
llvm::Value *ArraySize = nullptr);
+ /// Returns debug info, with additional annotation if enabled by
+ /// CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo[CheckKindOrdinal].
+ llvm::DILocation *
+ SanitizerAnnotateDebugInfo(SanitizerKind::SanitizerOrdinal CheckKindOrdinal);
+
+ /// Converts the CFITypeCheckKind into SanitizerKind::SanitizerOrdinal and
+ /// llvm::SanitizerStatKind.
+ void ParseCFITypeCheckKind(CFITypeCheckKind TCK,
+ SanitizerKind::SanitizerOrdinal &M,
+ llvm::SanitizerStatKind &SSK);
+
/// Emit a check that \p Base points into an array object, which
/// we can access at index \p Index. \p Accessed should be \c false if we
/// this expression is used as an lvalue, for instance in "&Arr[Idx]".
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 70b53be7e77a3..df12425ee46f9 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -703,6 +703,9 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
{
CodeGenFunction::SanitizerScope SanScope(&CGF);
+ ApplyDebugLocation ApplyTrapDI(
+ CGF, CGF.SanitizerAnnotateDebugInfo(SanitizerKind::SO_CFIMFCall));
+
llvm::Value *TypeId = nullptr;
llvm::Value *CheckResult = nullptr;
@@ -792,14 +795,16 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
// In the non-virtual path, the function pointer is actually a
// function pointer.
CGF.EmitBlock(FnNonVirtual);
+
llvm::Value *NonVirtualFn =
Builder.CreateIntToPtr(FnAsInt, CGF.UnqualPtrTy, "memptr.nonvirtualfn");
-
// Check the function pointer if CFI on member function pointers is enabled.
if (ShouldEmitCFICheck) {
CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
if (RD->hasDefinition()) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
+ ApplyDebugLocation ApplyTrapDI(
+ CGF, CGF.SanitizerAnnotateDebugInfo(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..1549b02938697 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_array_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}
@@ -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_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 cd5ec567cb01b..7100a42fef886 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 [[META21:![0-9]+]]
-// CHECK-NEXT: br i1 [[TMP0]], label %[[CFI_CONT:.*]], label %[[CFI_SLOWPATH:.*]], !dbg [[DBG20]], !prof [[PROF22:![0-9]+]], !nosanitize [[META21]]
+// 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 [[META21]]
-// CHECK-NEXT: br label %[[CFI_CONT]], !dbg [[DBG20]], !nosanitize [[META21]]
+// 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 [[DBG20]]
-// CHECK-NEXT: ret void, !dbg [[DBG23:![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();
@@ -38,8 +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: 23, column: 3, scope: [[DBG7]])
-// CHECK: [[META21]] = !{}
-// CHECK: [[PROF22]] = !{!"branch_weights", i32 1048575, i32 1}
-// CHECK: [[DBG23]] = !DILocation(line: 24, column: 1, 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: [[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]])
//.
diff --git a/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c b/clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
index 8b184528889a0..e47f058e2c633 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 [[META35:![0-9]+]]
-// UNGENERALIZED-NEXT: br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF36:![0-9]+]], !nosanitize [[META35]]
+// 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 [[META35]]
-// UNGENERALIZED-NEXT: unreachable, !dbg [[DBG34]], !nosanitize [[META35]]
+// 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 [[DBG34]]
-// UNGENERALIZED-NEXT: ret void, !dbg [[DBG37:![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 [[META35:![0-9]+]]
-// GENERALIZED-NEXT: br i1 [[TMP0]], label %[[CONT:.*]], label %[[TRAP:.*]], !dbg [[DBG34]], !prof [[PROF36:![0-9]+]], !nosanitize [[META35]]
+// 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 [[META35]]
-// GENERALIZED-NEXT: unreachable, !dbg [[DBG34]], !nosanitize [[META35]]
+// 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 [[DBG34]]
-// GENERALIZED-NEXT: ret void, !dbg [[DBG37:![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);
@@ -84,10 +84,13 @@ 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: 53, column: 3, scope: [[DBG25]])
-// UNGENERALIZED: [[META35]] = !{}
-// UNGENERALIZED: [[PROF36]] = !{!"branch_weights", i32 1048575, i32 1}
-// UNGENERALIZED: [[DBG37]] = !DILocation(line: 54, column: 1, 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: [[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]])
//.
// GENERALIZED: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: [[META2:![0-9]+]], splitDebugIn...
[truncated]
|
I am not a fan of the change to the function used for array-bounds. |
More specific? I like it in general. |
Sorry, I meant the new name. I don't like that it has a |
It was changed for efficiency. Anyway, fixed in dfc3919 |
Marking as draft - I'll pull out ParseCFITypeCheckKind as a separate NFC patch |
This refactors existing code into a 'ParseCFITypeCheckKind' helper function. This will be useful in future work to annotate CFI checks with debug info (llvm#139809).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable to me other than my coding style nits. I don't own this code though so you should wait for approval from one of the code owners.
clang/lib/CodeGen/CGClass.cpp
Outdated
void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, | ||
llvm::Value *VTable, | ||
CFITypeCheckKind TCK, | ||
SourceLocation Loc) { | ||
if (!SanOpts.has(SanitizerKind::CFICastStrict)) | ||
RD = LeastDerivedClassWithSameLayout(RD); | ||
|
||
auto [Ordinal, SSK] = ParseCFITypeCheckKind(TCK); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is SSK
unused?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Renamed SSK to '_'. Thanks!
clang/lib/CodeGen/CGClass.cpp
Outdated
@@ -2808,6 +2842,9 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived, | |||
if (!SanOpts.has(SanitizerKind::CFICastStrict)) | |||
ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl); | |||
|
|||
auto [Ordinal, SSK] = ParseCFITypeCheckKind(TCK); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is SSK
unused?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
clang/lib/CodeGen/CGClass.cpp
Outdated
|
||
switch (TCK) { | ||
case CFITCK_VCall: | ||
M = SanitizerKind::SO_CFIVCall; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just return std::make_pair(SanitizerKind::SO_CFIVCall, llvm::SanStat_CFI_VCall)
? It's a little more concise and also more inline with LLVM's coding style of returning as early as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review! I refactored this function into #140117. I'll make the change there.
This refactors existing code into a 'SanitizerInfoFromCFICheckKind' helper function. This will be useful in future work to annotate CFI checks with debug info (#139809).
…(#140117) This refactors existing code into a 'SanitizerInfoFromCFICheckKind' helper function. This will be useful in future work to annotate CFI checks with debug info (llvm/llvm-project#139809).
This connects the -fsanitize-annotate-debug-info plumbing (llvm#138577) to CFI check codegen. Updates the tests from llvm#139149. A side effect is that __ubsan_check_array_bounds is renamed to __ubsan_check_array-bounds. This affects clang/test/CodeGen/bounds-checking-debuginfo.c from llvm#128977
…Kind> ParseCFITypeCheckKind(CFITypeCheckKind TCK);
These tests will track progress on extending llvm#139809 from CFI to more UBSan checks.
…g-info (#141814) These tests will track progress on extending llvm/llvm-project#139809 from CFI to more UBSan checks.
This extends llvm#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 llvm#128977 and llvm#139809. Updates the tests from llvm#128976, llvm#139149 and llvm#141814.
…m#141814) These tests will track progress on extending llvm#139809 from CFI to more UBSan checks.
…cks (llvm#139809) This connects the -fsanitize-annotate-debug-info plumbing (llvm#138577) to CFI check codegen, using SanitizerAnnotateDebugInfo() (llvm#139965) and SanitizerInfoFromCFIKind (llvm#140117). Note: SanitizerAnnotateDebugInfo() is updated to a public function because it is needed in ItaniumCXXABI. Updates the tests from llvm#139149.
…m#141814) These tests will track progress on extending llvm#139809 from CFI to more UBSan checks.
…cks (llvm#139809) This connects the -fsanitize-annotate-debug-info plumbing (llvm#138577) to CFI check codegen, using SanitizerAnnotateDebugInfo() (llvm#139965) and SanitizerInfoFromCFIKind (llvm#140117). Note: SanitizerAnnotateDebugInfo() is updated to a public function because it is needed in ItaniumCXXABI. Updates the tests from llvm#139149.
This connects the -fsanitize-annotate-debug-info plumbing (#138577) to CFI check codegen, using SanitizerAnnotateDebugInfo() (#139965) and SanitizerInfoFromCFIKind (#140117).
Note: SanitizerAnnotateDebugInfo() is updated to a public function because it is needed in ItaniumCXXABI.
Updates the tests from #139149.