Skip to content

Commit f1b859c

Browse files
committed
Concurrency: centralise the definition for std::bit_cast
Remove the multiple definitions of `std::bit_cast` into a header. While this is still not great, it does reduce the duplication. This also silently works towards reducing a bit of the UB introduced here by adding an inline namespace for `std` which you are not technically allowed to use. However, by doing this, we have a clear migration path away from this once we adopt C++20.
1 parent 21841fc commit f1b859c

File tree

4 files changed

+48
-66
lines changed

4 files changed

+48
-66
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//===---- STLCompatibility.h - Runtime C++ Compatibiltiy Stubs --*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_RUNTIME_STL_COMPATIBILITY_H
14+
#define SWIFT_RUNTIME_STL_COMPATIBILITY_H
15+
16+
#if __cplusplus >= 202002l || defined(__cpp_lib_bit_cast)
17+
#include <bit>
18+
#else
19+
#include <cstdint>
20+
#include <cstring>
21+
#include <memory>
22+
#include <type_traits>
23+
24+
namespace std {
25+
inline namespace __swift {
26+
template <typename Destination, typename Source>
27+
std::enable_if_t<sizeof(Destination) == sizeof(Source) &&
28+
std::is_trivially_copyable_v<Source> &&
29+
std::is_trivially_copyable_v<Destination>, Destination>
30+
bit_cast(const Source &src) noexcept {
31+
static_assert(std::is_trivially_constructible_v<Destination>,
32+
"The destination type must be trivially constructible");
33+
Destination dst;
34+
if constexpr (std::is_pointer_v<Source> || std::is_pointer_v<Destination>)
35+
std::memcpy(reinterpret_cast<uintptr_t *>(&dst),
36+
reinterpret_cast<const uintptr_t *>(&src), sizeof(Destination));
37+
else
38+
std::memcpy(&dst, &src, sizeof(Destination));
39+
return dst;
40+
}
41+
}
42+
}
43+
#endif
44+
45+
#endif

stdlib/public/Concurrency/AsyncLet.cpp

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/ABI/TaskOptions.h"
2727
#include "swift/Runtime/Heap.h"
2828
#include "swift/Runtime/HeapObject.h"
29+
#include "swift/Runtime/STLCompatibility.h"
2930
#include "swift/Threading/Mutex.h"
3031
#include "llvm/ADT/PointerIntPair.h"
3132

@@ -35,28 +36,6 @@
3536

3637
#include <new>
3738

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-
6039
using namespace swift;
6140

6241
namespace {

stdlib/public/Concurrency/DispatchGlobalExecutor.cpp

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include "swift/Runtime/Concurrency.h"
3434
#include "swift/Runtime/EnvironmentVariables.h"
35+
#include "swift/Runtime/STLCompatibility.h"
3536

3637
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
3738
#include "swift/Runtime/HeapObject.h"
@@ -54,28 +55,6 @@
5455
#include "ExecutorImpl.h"
5556
#include "TaskPrivate.h"
5657

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-
7958
using namespace swift;
8059

8160
// Ensure that Job's layout is compatible with what Dispatch expects.

stdlib/public/Concurrency/TaskGroup.cpp

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "swift/Runtime/Config.h"
3434
#include "swift/Runtime/Heap.h"
3535
#include "swift/Runtime/HeapObject.h"
36+
#include "swift/Runtime/STLCompatibility.h"
3637
#include "swift/Threading/Mutex.h"
3738
#include <atomic>
3839
#include <deque>
@@ -61,28 +62,6 @@
6162
#include <dlfcn.h>
6263
#endif
6364

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-
8665
using namespace swift;
8766

8867
#if 0

0 commit comments

Comments
 (0)