Skip to content

Commit eee1dc5

Browse files
authored
Merge pull request #60058 from hyp/eng/noexcept-vwt-funcs
[interop][SwiftToCxx] mark value witness table functions as noexcept
2 parents ff2111e + f49e26e commit eee1dc5

File tree

3 files changed

+56
-16
lines changed

3 files changed

+56
-16
lines changed

lib/PrintAsClang/PrintSwiftToClangCoreScaffold.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ printValueWitnessTableFunctionType(raw_ostream &os, StringRef prefix,
6969
uint16_t ptrauthDisc) {
7070
os << "using " << prefix << name << "Ty = " << returnType
7171
<< "(* __ptrauth_swift_value_witness_function_pointer(" << ptrauthDisc
72-
<< "))(" << paramTypes << ");\n";
72+
<< "))(" << paramTypes << ") SWIFT_NOEXCEPT_FUNCTION_PTR;\n";
7373
}
7474

7575
static std::string makeParams(const char *arg) { return arg; }
@@ -83,6 +83,13 @@ static void printValueWitnessTable(raw_ostream &os) {
8383
std::string members;
8484
llvm::raw_string_ostream membersOS(members);
8585

86+
// C++ only supports noexcept on `using` function types in C++17.
87+
os << "#if __cplusplus > 201402L\n";
88+
os << "# define SWIFT_NOEXCEPT_FUNCTION_PTR noexcept\n";
89+
os << "#else\n";
90+
os << "# define SWIFT_NOEXCEPT_FUNCTION_PTR\n";
91+
os << "#endif\n\n";
92+
8693
#define WANT_ONLY_REQUIRED_VALUE_WITNESSES
8794
#define DATA_VALUE_WITNESS(lowerId, upperId, type) \
8895
membersOS << " " << type << " " << #lowerId << ";\n";
@@ -129,6 +136,8 @@ static void printValueWitnessTable(raw_ostream &os) {
129136
os << "\nstruct EnumValueWitnessTable {\n"
130137
<< " ValueWitnessTable vwTable;\n"
131138
<< membersOS.str() << "};\n\n";
139+
140+
os << "#undef SWIFT_NOEXCEPT_FUNCTION_PTR\n\n";
132141
}
133142

134143
static void printTypeMetadataResponseType(SwiftToClangInteropContext &ctx,
@@ -145,7 +154,7 @@ static void printTypeMetadataResponseType(SwiftToClangInteropContext &ctx,
145154
}
146155

147156
static void printOpaqueAllocFee(raw_ostream &os) {
148-
os << R"text(inline void * _Nonnull opaqueAlloc(size_t size, size_t align) {
157+
os << R"text(inline void * _Nonnull opaqueAlloc(size_t size, size_t align) noexcept {
149158
#if defined(_WIN32)
150159
void *r = _aligned_malloc(size, align);
151160
#else
@@ -156,7 +165,7 @@ static void printOpaqueAllocFee(raw_ostream &os) {
156165
#endif
157166
return r;
158167
}
159-
inline void opaqueFree(void * _Nonnull p) {
168+
inline void opaqueFree(void * _Nonnull p) noexcept {
160169
#if defined(_WIN32)
161170
_aligned_free(p);
162171
#else

test/Interop/SwiftToCxx/core/swift-impl-defs-in-cxx.swift

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,20 @@
2323
// CHECK-NEXT: // Swift type metadata request type.
2424
// CHECK-NEXT: typedef uint{{.*}}_t MetadataRequestTy;
2525
// CHECK-EMPTY:
26-
// CHECK-NEXT: using ValueWitnessInitializeBufferWithCopyOfBufferTy = void * _Nonnull(* __ptrauth_swift_value_witness_function_pointer(55882))(void * _Nonnull, void * _Nonnull, void * _Nonnull);
27-
// CHECK-NEXT: using ValueWitnessDestroyTy = void(* __ptrauth_swift_value_witness_function_pointer(1272))(void * _Nonnull, void * _Nonnull);
28-
// CHECK-NEXT: using ValueWitnessInitializeWithCopyTy = void * _Nonnull(* __ptrauth_swift_value_witness_function_pointer(58298))(void * _Nonnull, void * _Nonnull, void * _Nonnull);
29-
// CHECK-NEXT: using ValueWitnessAssignWithCopyTy = void * _Nonnull(* __ptrauth_swift_value_witness_function_pointer(34641))(void * _Nonnull, void * _Nonnull, void * _Nonnull);
30-
// CHECK-NEXT: using ValueWitnessInitializeWithTakeTy = void * _Nonnull(* __ptrauth_swift_value_witness_function_pointer(18648))(void * _Nonnull, void * _Nonnull, void * _Nonnull);
31-
// CHECK-NEXT: using ValueWitnessAssignWithTakeTy = void * _Nonnull(* __ptrauth_swift_value_witness_function_pointer(61402))(void * _Nonnull, void * _Nonnull, void * _Nonnull);
32-
// CHECK-NEXT: using ValueWitnessGetEnumTagSinglePayloadTy = unsigned(* __ptrauth_swift_value_witness_function_pointer(24816))(const void * _Nonnull, unsigned, void * _Nonnull);
33-
// CHECK-NEXT: using ValueWitnessStoreEnumTagSinglePayloadTy = void(* __ptrauth_swift_value_witness_function_pointer(41169))(void * _Nonnull, unsigned, unsigned, void * _Nonnull);
26+
// CHECK-NEXT: #if __cplusplus > 201402L
27+
// CHECK-NEXT: # define SWIFT_NOEXCEPT_FUNCTION_PTR noexcept
28+
// CHECK-NEXT: #else
29+
// CHECK-NEXT: # define SWIFT_NOEXCEPT_FUNCTION_PTR
30+
// CHECK-NEXT: #endif
31+
// CHECK-EMPTY:
32+
// CHECK-NEXT: using ValueWitnessInitializeBufferWithCopyOfBufferTy = void * _Nonnull(* __ptrauth_swift_value_witness_function_pointer(55882))(void * _Nonnull, void * _Nonnull, void * _Nonnull) SWIFT_NOEXCEPT_FUNCTION_PTR;
33+
// CHECK-NEXT: using ValueWitnessDestroyTy = void(* __ptrauth_swift_value_witness_function_pointer(1272))(void * _Nonnull, void * _Nonnull) SWIFT_NOEXCEPT_FUNCTION_PTR;
34+
// CHECK-NEXT: using ValueWitnessInitializeWithCopyTy = void * _Nonnull(* __ptrauth_swift_value_witness_function_pointer(58298))(void * _Nonnull, void * _Nonnull, void * _Nonnull) SWIFT_NOEXCEPT_FUNCTION_PTR;
35+
// CHECK-NEXT: using ValueWitnessAssignWithCopyTy = void * _Nonnull(* __ptrauth_swift_value_witness_function_pointer(34641))(void * _Nonnull, void * _Nonnull, void * _Nonnull) SWIFT_NOEXCEPT_FUNCTION_PTR;
36+
// CHECK-NEXT: using ValueWitnessInitializeWithTakeTy = void * _Nonnull(* __ptrauth_swift_value_witness_function_pointer(18648))(void * _Nonnull, void * _Nonnull, void * _Nonnull) SWIFT_NOEXCEPT_FUNCTION_PTR;
37+
// CHECK-NEXT: using ValueWitnessAssignWithTakeTy = void * _Nonnull(* __ptrauth_swift_value_witness_function_pointer(61402))(void * _Nonnull, void * _Nonnull, void * _Nonnull) SWIFT_NOEXCEPT_FUNCTION_PTR;
38+
// CHECK-NEXT: using ValueWitnessGetEnumTagSinglePayloadTy = unsigned(* __ptrauth_swift_value_witness_function_pointer(24816))(const void * _Nonnull, unsigned, void * _Nonnull) SWIFT_NOEXCEPT_FUNCTION_PTR;
39+
// CHECK-NEXT: using ValueWitnessStoreEnumTagSinglePayloadTy = void(* __ptrauth_swift_value_witness_function_pointer(41169))(void * _Nonnull, unsigned, unsigned, void * _Nonnull) SWIFT_NOEXCEPT_FUNCTION_PTR;
3440
// CHECK-EMPTY:
3541
// CHECK-NEXT: struct ValueWitnessTable {
3642
// CHECK-NEXT: ValueWitnessInitializeBufferWithCopyOfBufferTy _Nonnull initializeBufferWithCopyOfBuffer;
@@ -47,9 +53,9 @@
4753
// CHECK-NEXT: unsigned extraInhabitantCount;
4854
// CHECK-NEXT: };
4955
// CHECK-EMPTY:
50-
// CHECK-NEXT: using EnumValueWitnessGetEnumTagTy = int(* __ptrauth_swift_value_witness_function_pointer(41909))(const void * _Nonnull, void * _Nonnull);
51-
// CHECK-NEXT: using EnumValueWitnessDestructiveProjectEnumDataTy = void(* __ptrauth_swift_value_witness_function_pointer(1053))(void * _Nonnull, void * _Nonnull);
52-
// CHECK-NEXT: using EnumValueWitnessDestructiveInjectEnumTagTy = void(* __ptrauth_swift_value_witness_function_pointer(45796))(void * _Nonnull, unsigned, void * _Nonnull);
56+
// CHECK-NEXT: using EnumValueWitnessGetEnumTagTy = int(* __ptrauth_swift_value_witness_function_pointer(41909))(const void * _Nonnull, void * _Nonnull) SWIFT_NOEXCEPT_FUNCTION_PTR;
57+
// CHECK-NEXT: using EnumValueWitnessDestructiveProjectEnumDataTy = void(* __ptrauth_swift_value_witness_function_pointer(1053))(void * _Nonnull, void * _Nonnull) SWIFT_NOEXCEPT_FUNCTION_PTR;
58+
// CHECK-NEXT: using EnumValueWitnessDestructiveInjectEnumTagTy = void(* __ptrauth_swift_value_witness_function_pointer(45796))(void * _Nonnull, unsigned, void * _Nonnull) SWIFT_NOEXCEPT_FUNCTION_PTR;
5359
// CHECK-EMPTY:
5460
// CHECK-NEXT: struct EnumValueWitnessTable {
5561
// CHECK-NEXT: ValueWitnessTable vwTable;
@@ -58,12 +64,14 @@
5864
// CHECK-NEXT: EnumValueWitnessDestructiveInjectEnumTagTy _Nonnull destructiveInjectEnumTag;
5965
// CHECK-NEXT: };
6066
// CHECK-EMPTY:
67+
// CHECK-NEXT: #undef SWIFT_NOEXCEPT_FUNCTION_PTR
68+
// CHECK-EMPTY:
6169
// CHECK-EMPTY:
6270
// CHECK-NEXT: #ifdef __cplusplus
6371
// CHECK-NEXT: }
6472
// CHECK-NEXT: #endif
6573
// CHECK-EMPTY:
66-
// CHECK-NEXT: inline void * _Nonnull opaqueAlloc(size_t size, size_t align) {
74+
// CHECK-NEXT: inline void * _Nonnull opaqueAlloc(size_t size, size_t align) noexcept {
6775
// CHECK-NEXT: #if defined(_WIN32)
6876
// CHECK-NEXT: void *r = _aligned_malloc(size, align);
6977
// CHECK-NEXT: #else
@@ -74,7 +82,7 @@
7482
// CHECK-NEXT: #endif
7583
// CHECK-NEXT: return r;
7684
// CHECK-NEXT: }
77-
// CHECK-NEXT: inline void opaqueFree(void * _Nonnull p) {
85+
// CHECK-NEXT: inline void opaqueFree(void * _Nonnull p) noexcept {
7886
// CHECK-NEXT: #if defined(_WIN32)
7987
// CHECK-NEXT: _aligned_free(p);
8088
// CHECK-NEXT: #else
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend %S/swift-impl-defs-in-cxx.swift -typecheck -module-name Core -clang-header-expose-public-decls -emit-clang-header-path %t/core.h
4+
5+
// RUN: %target-interop-build-clangxx -std=c++17 -c %s -I %t -o %t/swift-core-validation.o
6+
// RUN: %target-interop-build-clangxx -std=c++20 -c %s -I %t -o %t/swift-core-validation.o
7+
// RUN: %target-interop-build-clangxx -std=c++14 -c %s -I %t -o %t/swift-core-validation.o -D SHOULD_FAIL
8+
9+
#include <assert.h>
10+
#include "core.h"
11+
12+
#define CHECK(x) (x)
13+
14+
#ifdef SHOULD_FAIL
15+
# undef CHECK
16+
# define CHECK(x) !(x)
17+
#endif
18+
19+
int main() {
20+
swift::_impl::ValueWitnessDestroyTy destroyFn;
21+
static_assert(CHECK(noexcept(destroyFn(nullptr, nullptr))), "value witness table fns are noexcept");
22+
return 0;
23+
}

0 commit comments

Comments
 (0)