Skip to content

Commit c71fae1

Browse files
committed
Ensure that bridged types are indirectly returned on Windows ARM64
On Windows ARM64, how a struct value type is returned is sensitive to conditions including whether a user-defined constructor exists, etc. See https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#return-values That caused a calling convention mismatch between the non-USED_IN_CPP_SOURCE (Swift) side and the USE_IN_CPP_SOURCE (C++) side and a crash. Following #76433 add constructors to several bridged C++ struct/class types so that the calling convention matches. This is a partial fix for #74866 Cherrypick #76589
1 parent 986ea7f commit c71fae1

File tree

5 files changed

+85
-0
lines changed

5 files changed

+85
-0
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ class BridgedDeclBaseName {
8080
BridgedIdentifier Ident;
8181

8282
public:
83+
// Ensure that this struct value type will be indirectly returned on
84+
// Windows ARM64
85+
BridgedDeclBaseName() : Ident() {}
86+
8387
#ifdef USED_IN_CPP_SOURCE
8488
BridgedDeclBaseName(swift::DeclBaseName baseName) : Ident(baseName.Ident) {}
8589

@@ -106,6 +110,10 @@ class BridgedDeclNameRef {
106110
void *_Nonnull opaque;
107111

108112
public:
113+
// Ensure that this struct value type will be indirectly returned on
114+
// Windows ARM64
115+
BridgedDeclNameRef() : opaque() {}
116+
109117
#ifdef USED_IN_CPP_SOURCE
110118
BridgedDeclNameRef(swift::DeclNameRef name) : opaque(name.getOpaqueValue()) {}
111119

@@ -162,6 +170,10 @@ class BridgedASTContext {
162170
swift::ASTContext * _Nonnull Ctx;
163171

164172
public:
173+
// Ensure that this struct value type will be indirectly returned on
174+
// Windows ARM64
175+
BridgedASTContext() : Ctx() {}
176+
165177
#ifdef USED_IN_CPP_SOURCE
166178
SWIFT_UNAVAILABLE("Use init(raw:) instead")
167179
BridgedASTContext(swift::ASTContext &ctx) : Ctx(&ctx) {}
@@ -317,6 +329,10 @@ class BridgedDiagnosticArgument {
317329
int64_t storage[3];
318330

319331
public:
332+
// Ensure that this struct value type will be indirectly returned on
333+
// Windows ARM64
334+
BridgedDiagnosticArgument() {}
335+
320336
#ifdef USED_IN_CPP_SOURCE
321337
BridgedDiagnosticArgument(const swift::DiagnosticArgument &arg) {
322338
*reinterpret_cast<swift::DiagnosticArgument *>(&storage) = arg;
@@ -334,6 +350,10 @@ class BridgedDiagnosticFixIt {
334350
int64_t storage[7];
335351

336352
public:
353+
// Ensure that this struct value type will be indirectly returned on
354+
// Windows ARM64
355+
BridgedDiagnosticFixIt() {}
356+
337357
#ifdef USED_IN_CPP_SOURCE
338358
BridgedDiagnosticFixIt(const swift::DiagnosticInfo::FixIt &fixit){
339359
*reinterpret_cast<swift::DiagnosticInfo::FixIt *>(&storage) = fixit;
@@ -1333,6 +1353,10 @@ class BridgedStmtConditionElement {
13331353
void *_Nonnull Raw;
13341354

13351355
public:
1356+
// Ensure that this struct value type will be indirectly returned on
1357+
// Windows ARM64
1358+
BridgedStmtConditionElement() {}
1359+
13361360
#ifdef USED_IN_CPP_SOURCE
13371361
BridgedStmtConditionElement(swift::StmtConditionElement elem)
13381362
: Raw(elem.getOpaqueValue()) {}

include/swift/Basic/BasicBridging.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@
2323
// Pure bridging mode does not permit including any C++/llvm/swift headers.
2424
// See also the comments for `BRIDGING_MODE` in the top-level CMakeLists.txt file.
2525
//
26+
//
27+
// Note: On Windows ARM64, how a C++ struct/class value type is
28+
// returned is sensitive to conditions including whether a
29+
// user-defined constructor exists, etc. See
30+
// https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#return-values
31+
// So, if a C++ struct/class type is returned as a value between Swift
32+
// and C++, we need to be careful to match the return convention
33+
// matches between the non-USED_IN_CPP_SOURCE (Swift) side and the
34+
// USE_IN_CPP_SOURCE (C++) side.
2635
#include "swift/Basic/BridgedSwiftObject.h"
2736
#include "swift/Basic/Compiler.h"
2837

@@ -228,6 +237,10 @@ class BridgedOwnedString {
228237
size_t Length;
229238

230239
public:
240+
// Ensure that this struct value type will be indirectly returned on
241+
// Windows ARM64
242+
BridgedOwnedString() {}
243+
231244
#ifdef USED_IN_CPP_SOURCE
232245
BridgedOwnedString(const std::string &stringToCopy);
233246

include/swift/Parse/ParseBridging.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class BridgedLegacyParser {
3030
swift::Parser *_Nonnull const handle;
3131

3232
public:
33+
// Ensure that this struct value type will be indirectly returned on
34+
// Windows ARM64
35+
BridgedLegacyParser() : handle(nullptr) {}
36+
3337
#ifdef USED_IN_CPP_SOURCE
3438
BridgedLegacyParser(swift::Parser &P) : handle(&P) {}
3539

include/swift/SIL/SILBridging.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ struct BridgedResultInfo {
8282
swift::TypeBase * _Nonnull type;
8383
BridgedResultConvention convention;
8484

85+
// Ensure that this struct value type will be indirectly returned on
86+
// Windows ARM64
87+
BridgedResultInfo() {}
88+
8589
#ifdef USED_IN_CPP_SOURCE
8690
inline static BridgedResultConvention
8791
castToResultConvention(swift::ResultConvention convention) {
@@ -99,6 +103,10 @@ struct OptionalBridgedResultInfo {
99103
swift::TypeBase * _Nullable type = nullptr;
100104
BridgedResultConvention convention = BridgedResultConvention::Indirect;
101105

106+
// Ensure that this struct value type will be indirectly returned on
107+
// Windows ARM64
108+
OptionalBridgedResultInfo() {}
109+
102110
#ifdef USED_IN_CPP_SOURCE
103111
OptionalBridgedResultInfo(std::optional<swift::SILResultInfo> resultInfo) {
104112
if (resultInfo) {
@@ -113,6 +121,10 @@ struct OptionalBridgedResultInfo {
113121
struct BridgedResultInfoArray {
114122
BridgedArrayRef resultInfoArray;
115123

124+
// Ensure that this struct value type will be indirectly returned on
125+
// Windows ARM64
126+
BridgedResultInfoArray() {}
127+
116128
#ifdef USED_IN_CPP_SOURCE
117129
BridgedResultInfoArray(llvm::ArrayRef<swift::SILResultInfo> results)
118130
: resultInfoArray(results) {}
@@ -195,6 +207,10 @@ struct BridgedParameterInfo {
195207
struct BridgedParameterInfoArray {
196208
BridgedArrayRef parameterInfoArray;
197209

210+
// Ensure that this struct value type will be indirectly returned on
211+
// Windows ARM64
212+
BridgedParameterInfoArray() {}
213+
198214
#ifdef USED_IN_CPP_SOURCE
199215
BridgedParameterInfoArray(llvm::ArrayRef<swift::SILParameterInfo> parameters)
200216
: parameterInfoArray(parameters) {}
@@ -213,6 +229,10 @@ struct BridgedParameterInfoArray {
213229
struct BridgedYieldInfoArray {
214230
BridgedArrayRef yieldInfoArray;
215231

232+
// Ensure that this struct value type will be indirectly returned on
233+
// Windows ARM64
234+
BridgedYieldInfoArray() {}
235+
216236
#ifdef USED_IN_CPP_SOURCE
217237
BridgedYieldInfoArray(llvm::ArrayRef<swift::SILYieldInfo> yields)
218238
: yieldInfoArray(yields) {}
@@ -303,6 +323,10 @@ struct BridgedType {
303323
struct EnumElementIterator {
304324
uint64_t storage[4];
305325

326+
// Ensure that this struct value type will be indirectly returned on
327+
// Windows ARM64
328+
EnumElementIterator() {}
329+
306330
#ifdef USED_IN_CPP_SOURCE
307331
EnumElementIterator(swift::EnumDecl::ElementRange::iterator i) {
308332
static_assert(sizeof(EnumElementIterator) >= sizeof(swift::EnumDecl::ElementRange::iterator));
@@ -316,6 +340,10 @@ struct BridgedType {
316340
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE EnumElementIterator getNext() const;
317341
};
318342

343+
// Ensure that this struct value type will be indirectly returned on
344+
// Windows ARM64
345+
BridgedType() {}
346+
319347
#ifdef USED_IN_CPP_SOURCE
320348
BridgedType(swift::SILType t) : opaqueValue(t.getOpaqueValue()) {}
321349

@@ -698,6 +726,10 @@ struct BridgedTypeArray {
698726
struct BridgedSILTypeArray {
699727
BridgedArrayRef typeArray;
700728

729+
// Ensure that this struct value type will be indirectly returned on
730+
// Windows ARM64
731+
BridgedSILTypeArray() {}
732+
701733
#ifdef USED_IN_CPP_SOURCE
702734
BridgedSILTypeArray(llvm::ArrayRef<swift::SILType> silTypes)
703735
: typeArray(silTypes) {}
@@ -716,6 +748,10 @@ struct BridgedSILTypeArray {
716748
struct BridgedLocation {
717749
uint64_t storage[3];
718750

751+
// Ensure that this struct value type will be indirectly returned on
752+
// Windows ARM64
753+
BridgedLocation() {}
754+
719755
#ifdef USED_IN_CPP_SOURCE
720756
BridgedLocation(const swift::SILDebugLocation &loc) {
721757
*reinterpret_cast<swift::SILDebugLocation *>(&storage) = loc;
@@ -742,6 +778,10 @@ struct BridgedGenericSpecializationInformation {
742778
struct OptionalBridgedSILDebugVariable {
743779
uint64_t storage[16];
744780

781+
// Ensure that this struct value type will be indirectly returned on
782+
// Windows ARM64
783+
OptionalBridgedSILDebugVariable() {}
784+
745785
#ifdef USED_IN_CPP_SOURCE
746786
using OptionalSILDebugVariable = std::optional<swift::SILDebugVariable>;
747787

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ struct BridgedCalleeAnalysis {
8585
struct CalleeList {
8686
uint64_t storage[3];
8787

88+
// Ensure that this struct value type will be indirectly returned on
89+
// Windows ARM64
90+
CalleeList() {}
91+
8892
#ifdef USED_IN_CPP_SOURCE
8993
CalleeList(swift::CalleeList list) {
9094
*reinterpret_cast<swift::CalleeList *>(&storage) = list;

0 commit comments

Comments
 (0)