Skip to content

Commit 21841fc

Browse files
authored
Merge pull request #78911 from compnerd/bitcasting
Concurrency: silence some `-Wcast-function-type-mismatch` warnings
2 parents eb1ea4e + c9df7c5 commit 21841fc

File tree

3 files changed

+79
-13
lines changed

3 files changed

+79
-13
lines changed

stdlib/public/Concurrency/AsyncLet.cpp

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,28 @@
3535

3636
#include <new>
3737

38+
#if __cplusplus < 202002l || !defined(__cpp_lib_bit_cast)
39+
namespace std {
40+
template <typename Destination, typename Source>
41+
std::enable_if_t<sizeof(Destination) == sizeof(Source) &&
42+
std::is_trivially_copyable_v<Source> &&
43+
std::is_trivially_copyable_v<Destination>, Destination>
44+
bit_cast(const Source &src) noexcept {
45+
static_assert(std::is_trivially_constructible_v<Destination>,
46+
"The destination type must be trivially constructible");
47+
Destination dst;
48+
if constexpr (std::is_pointer_v<Source> || std::is_pointer_v<Destination>)
49+
std::memcpy(reinterpret_cast<uintptr_t *>(&dst),
50+
reinterpret_cast<const uintptr_t *>(&src), sizeof(Destination));
51+
else
52+
std::memcpy(&dst, &src, sizeof(Destination));
53+
return dst;
54+
}
55+
}
56+
#else
57+
#include <bit>
58+
#endif
59+
3860
using namespace swift;
3961

4062
namespace {
@@ -287,8 +309,8 @@ static void _asyncLet_get_throwing_continuation(
287309
}
288310

289311
// Continue the caller's execution.
290-
auto throwingResume
291-
= reinterpret_cast<ThrowingTaskFutureWaitContinuationFunction*>(callContext->ResumeParent);
312+
auto throwingResume =
313+
std::bit_cast<ThrowingTaskFutureWaitContinuationFunction*>(callContext->ResumeParent);
292314
return throwingResume(callContext->Parent, error);
293315
}
294316

@@ -305,8 +327,8 @@ static void swift_asyncLet_get_throwingImpl(
305327
}
306328

307329
auto aletContext = static_cast<AsyncLetContinuationContext*>(callContext);
308-
aletContext->ResumeParent
309-
= reinterpret_cast<TaskContinuationFunction*>(resumeFunction);
330+
aletContext->ResumeParent =
331+
std::bit_cast<TaskContinuationFunction*>(resumeFunction);
310332
aletContext->Parent = callerContext;
311333
aletContext->alet = alet;
312334
auto futureContext = asImpl(alet)->getFutureContext();
@@ -376,7 +398,7 @@ static void asyncLet_finish_after_task_completion(SWIFT_ASYNC_CONTEXT AsyncConte
376398
swift_task_dealloc(task);
377399
}
378400

379-
return reinterpret_cast<ThrowingTaskFutureWaitContinuationFunction*>(resumeFunction)
401+
return std::bit_cast<ThrowingTaskFutureWaitContinuationFunction*>(resumeFunction)
380402
(callerContext, error);
381403
}
382404

@@ -528,14 +550,14 @@ static void swift_asyncLet_consume_throwingImpl(
528550
if (asImpl(alet)->hasResultInBuffer()) {
529551
return asyncLet_finish_after_task_completion(callerContext,
530552
alet,
531-
reinterpret_cast<TaskContinuationFunction*>(resumeFunction),
553+
std::bit_cast<TaskContinuationFunction*>(resumeFunction),
532554
callContext,
533555
nullptr);
534556
}
535557

536558
auto aletContext = static_cast<AsyncLetContinuationContext*>(callContext);
537-
aletContext->ResumeParent
538-
= reinterpret_cast<TaskContinuationFunction*>(resumeFunction);
559+
aletContext->ResumeParent =
560+
std::bit_cast<TaskContinuationFunction*>(resumeFunction);
539561
aletContext->Parent = callerContext;
540562
aletContext->alet = alet;
541563
auto futureContext = asImpl(alet)->getFutureContext();

stdlib/public/Concurrency/DispatchGlobalExecutor.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,28 @@
5454
#include "ExecutorImpl.h"
5555
#include "TaskPrivate.h"
5656

57+
#if __cplusplus < 202002l || !defined(__cpp_lib_bit_cast)
58+
namespace std {
59+
template <typename Destination, typename Source>
60+
std::enable_if_t<sizeof(Destination) == sizeof(Source) &&
61+
std::is_trivially_copyable_v<Source> &&
62+
std::is_trivially_copyable_v<Destination>, Destination>
63+
bit_cast(const Source &src) noexcept {
64+
static_assert(std::is_trivially_constructible_v<Destination>,
65+
"The destination type must be trivially constructible");
66+
Destination dst;
67+
if constexpr (std::is_pointer_v<Source> || std::is_pointer_v<Destination>)
68+
std::memcpy(reinterpret_cast<uintptr_t *>(&dst),
69+
reinterpret_cast<const uintptr_t *>(&src), sizeof(Destination));
70+
else
71+
std::memcpy(&dst, &src, sizeof(Destination));
72+
return dst;
73+
}
74+
}
75+
#else
76+
#include <bit>
77+
#endif
78+
5779
using namespace swift;
5880

5981
// Ensure that Job's layout is compatible with what Dispatch expects.
@@ -119,11 +141,11 @@ static void initializeDispatchEnqueueFunc(dispatch_queue_t queue, void *obj,
119141
if (SWIFT_RUNTIME_WEAK_CHECK(dispatch_async_swift_job))
120142
func = SWIFT_RUNTIME_WEAK_USE(dispatch_async_swift_job);
121143
#elif defined(_WIN32)
122-
func = reinterpret_cast<dispatchEnqueueFuncType>(
144+
func = std::bit_cast<dispatchEnqueueFuncType>(
123145
GetProcAddress(LoadLibraryW(L"dispatch.dll"),
124146
"dispatch_async_swift_job"));
125147
#else
126-
func = reinterpret_cast<dispatchEnqueueFuncType>(
148+
func = std::bit_cast<dispatchEnqueueFuncType>(
127149
dlsym(RTLD_NEXT, "dispatch_async_swift_job"));
128150
#endif
129151
#endif

stdlib/public/Concurrency/TaskGroup.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,28 @@
6161
#include <dlfcn.h>
6262
#endif
6363

64+
#if __cplusplus < 202002l || !defined(__cpp_lib_bit_cast)
65+
namespace std {
66+
template <typename Destination, typename Source>
67+
std::enable_if_t<sizeof(Destination) == sizeof(Source) &&
68+
std::is_trivially_copyable_v<Source> &&
69+
std::is_trivially_copyable_v<Destination>, Destination>
70+
bit_cast(const Source &src) noexcept {
71+
static_assert(std::is_trivially_constructible_v<Destination>,
72+
"The destination type must be trivially constructible");
73+
Destination dst;
74+
if constexpr (std::is_pointer_v<Source> || std::is_pointer_v<Destination>)
75+
std::memcpy(reinterpret_cast<uintptr_t *>(&dst),
76+
reinterpret_cast<const uintptr_t *>(&src), sizeof(Destination));
77+
else
78+
std::memcpy(&dst, &src, sizeof(Destination));
79+
return dst;
80+
}
81+
}
82+
#else
83+
#include <bit>
84+
#endif
85+
6486
using namespace swift;
6587

6688
#if 0
@@ -1653,7 +1675,7 @@ task_group_wait_resume_adapter(SWIFT_ASYNC_CONTEXT AsyncContext *_context) {
16531675

16541676
auto context = static_cast<TaskFutureWaitAsyncContext *>(_context);
16551677
auto resumeWithError =
1656-
reinterpret_cast<AsyncVoidClosureResumeEntryPoint *>(context->ResumeParent);
1678+
std::bit_cast<AsyncVoidClosureResumeEntryPoint *>(context->ResumeParent);
16571679
return resumeWithError(context->Parent, context->errorResult);
16581680
}
16591681

@@ -1705,7 +1727,7 @@ static void swift_taskGroup_wait_next_throwingImpl(
17051727

17061728
auto context = static_cast<TaskFutureWaitAsyncContext *>(rawContext);
17071729
context->ResumeParent =
1708-
reinterpret_cast<TaskContinuationFunction *>(resumeFunction);
1730+
std::bit_cast<TaskContinuationFunction *>(resumeFunction);
17091731
context->Parent = callerContext;
17101732
context->errorResult = nullptr;
17111733
context->successResultPointer = resultPointer;
@@ -1937,7 +1959,7 @@ void TaskGroupBase::waitAll(SwiftError* bodyError, AsyncTask *waitingTask,
19371959

19381960
auto context = static_cast<TaskFutureWaitAsyncContext *>(rawContext);
19391961
context->ResumeParent =
1940-
reinterpret_cast<TaskContinuationFunction *>(resumeFunction);
1962+
std::bit_cast<TaskContinuationFunction *>(resumeFunction);
19411963
context->Parent = callerContext;
19421964
context->errorResult = nullptr;
19431965
context->successResultPointer = resultPointer;

0 commit comments

Comments
 (0)