Skip to content

Commit b0d4bda

Browse files
ahmedbougachaojhunt
authored andcommitted
[clang] Sign the dtor passed to __cxa_throw as a void(*)(void*) fptr.
__cxa_throw is declared to take its destructor as void (*)(void *). We must match that if function pointers can be authenticated with a discriminator based on their type.
1 parent b00d0b2 commit b0d4bda

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,8 +1321,16 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
13211321
if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) {
13221322
CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
13231323
if (!Record->hasTrivialDestructor()) {
1324+
// __cxa_throw is declared to take its destructor as void (*)(void *). We
1325+
// must match that if function pointers can be authenticated with a
1326+
// discriminator based on their type.
1327+
ASTContext &Ctx = getContext();
1328+
QualType DtorTy = Ctx.getFunctionType(Ctx.VoidTy, {Ctx.VoidPtrTy},
1329+
FunctionProtoType::ExtProtoInfo());
1330+
13241331
CXXDestructorDecl *DtorD = Record->getDestructor();
13251332
Dtor = CGM.getAddrOfCXXStructor(GlobalDecl(DtorD, Dtor_Complete));
1333+
Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
13261334
}
13271335
}
13281336
if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s
2+
3+
class Foo {
4+
public:
5+
~Foo() {
6+
}
7+
};
8+
9+
// CHECK-LABEL: define void @_Z1fv()
10+
// CHECK: call void @__cxa_throw(ptr %{{.*}}, ptr @_ZTI3Foo, ptr ptrauth (ptr @_ZN3FooD1Ev, i32 0))
11+
void f() {
12+
throw Foo();
13+
}
14+
15+
// __cxa_throw is defined to take its destructor as "void (*)(void *)" in the ABI.
16+
// CHECK-LABEL: define void @__cxa_throw({{.*}})
17+
// CHECK: call void {{%.*}}(ptr noundef {{%.*}}) [ "ptrauth"(i32 0, i64 0) ]
18+
extern "C" void __cxa_throw(void *exception, void *, void (*dtor)(void *)) {
19+
dtor(exception);
20+
}

0 commit comments

Comments
 (0)