Skip to content

Commit fa1f536

Browse files
authored
Merge pull request #63143 from aschwaighofer/ptr_auth_fn_ptr_store
IRGen: Thin function values may carry a precise pointer to function type rather than i8*
2 parents ccb35fe + db61349 commit fa1f536

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

lib/IRGen/GenFunc.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,21 @@ namespace {
153153
return new ThinFuncTypeInfo(formalType, storageType, size, align,
154154
spareBits);
155155
}
156+
void initialize(IRGenFunction &IGF, Explosion &src, Address addr,
157+
bool isOutlined) const override {
158+
auto *fn = src.claimNext();
159+
160+
// We might be presented with a value of the more precise pointer to
161+
// function type "void(*)*" rather than the generic "i8*". Downcast to the
162+
// more general expected type.
163+
if (fn->getContext().supportsTypedPointers() &&
164+
fn->getType()->getNonOpaquePointerElementType()->isFunctionTy())
165+
fn = IGF.Builder.CreateBitCast(fn, getStorageType());
166+
167+
Explosion tmp;
168+
tmp.add(fn);
169+
PODSingleScalarTypeInfo<ThinFuncTypeInfo,LoadableTypeInfo>::initialize(IGF, tmp, addr, isOutlined);
170+
}
156171

157172
TypeLayoutEntry *buildTypeLayoutEntry(IRGenModule &IGM,
158173
SILType T) const override {

test/IRGen/Inputs/fnptr.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef fnptr_h
2+
#define fnptr_h
3+
4+
#include <stddef.h>
5+
6+
typedef struct {
7+
void (* _Nonnull fnptr)(size_t *);
8+
} Container;
9+
10+
#endif

test/IRGen/fnptr.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-swift-frontend -import-objc-header %S/Inputs/fnptr.h -swift-version 5 -target arm64e-apple-ios13.0 %s -emit-ir -module-name test -use-clang-function-types -Xcc -Xclang -Xcc -fptrauth-function-pointer-type-discrimination | %FileCheck %s
2+
3+
// REQUIRES: CPU=arm64e
4+
// REQUIRES: OS=ios
5+
6+
// This test used to crash in IRGen because of mismatching pointer types.
7+
8+
// CHECK: define{{.*}} swiftcc void @"$s4testAAyyF"()
9+
// CHECK: store i8* bitcast {{.*}} @"$s4testAAyyFySpySiGSgcfU_To.ptrauth" to i8*), i8**
10+
11+
public func test() {
12+
var tmp = Container(
13+
fnptr: { (x) in return }
14+
)
15+
}

0 commit comments

Comments
 (0)