Skip to content

Commit 9306352

Browse files
committed
[Clang] Emit KCFI type hashes for member functions
With `-fsanitize=kcfi`, Clang currently won't emit type hashes for C++ member functions, which leads to check failures if they are indirectly called. As there's no reason to exclude member functions in CodeGenModule::setKCFIType, emit type hashes also for them to fix member function pointer calls with KCFI, and add a test to confirm that types are emitted correctly.
1 parent c012eb7 commit 9306352

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -2610,9 +2610,6 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
26102610
}
26112611

26122612
void CodeGenModule::setKCFIType(const FunctionDecl *FD, llvm::Function *F) {
2613-
if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic())
2614-
return;
2615-
26162613
llvm::LLVMContext &Ctx = F->getContext();
26172614
llvm::MDBuilder MDB(Ctx);
26182615
F->setMetadata(llvm::LLVMContext::MD_kcfi_type,

clang/test/CodeGen/kcfi.c

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -o - %s | FileCheck %s
2-
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -x c++ -o - %s | FileCheck %s
2+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -x c++ -o - %s | FileCheck %s --check-prefixes=CHECK,MEMBER
33
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fpatchable-function-entry-offset=3 -o - %s | FileCheck %s --check-prefixes=CHECK,OFFSET
44
#if !__has_feature(kcfi)
55
#error Missing kcfi?
@@ -54,7 +54,21 @@ int test(void) {
5454
f6();
5555
}
5656

57+
#ifdef __cplusplus
58+
struct A {
59+
// MEMBER-DAG: define{{.*}} void @_ZN1A1fEv(ptr{{.*}} %this){{.*}} !kcfi_type ![[#TYPE3:]]
60+
void f() {}
61+
};
62+
63+
void test_member_call(void) {
64+
void (A::* p)() = &A::f;
65+
// MEMBER-DAG: call void %[[#]](ptr{{.*}} [ "kcfi"(i32 [[#%d,HASH3:]]) ]
66+
(A().*p)();
67+
}
68+
#endif
69+
5770
// CHECK-DAG: ![[#]] = !{i32 4, !"kcfi", i32 1}
5871
// OFFSET-DAG: ![[#]] = !{i32 4, !"kcfi-offset", i32 3}
5972
// CHECK-DAG: ![[#TYPE]] = !{i32 [[#HASH]]}
6073
// CHECK-DAG: ![[#TYPE2]] = !{i32 [[#%d,HASH2:]]}
74+
// MEMBER-DAG: ![[#TYPE3]] = !{i32 [[#HASH3]]}

0 commit comments

Comments
 (0)