Skip to content

Commit 877d03f

Browse files
authored
Merge pull request #61692 from etcwilde/ewilde/fix-noreturn-warning
Fix asyncMainDrainQueue noreturn warning
2 parents 8dac45e + 932be61 commit 877d03f

File tree

5 files changed

+131
-3
lines changed

5 files changed

+131
-3
lines changed

include/swift/Runtime/Concurrency.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,19 @@ SWIFT_EXPORT_FROM(swift_Concurrency)
770770
SWIFT_CC(swift) void (*swift_task_enqueueMainExecutor_hook)(
771771
Job *job, swift_task_enqueueMainExecutor_original original);
772772

773+
/// A hook to override the entrypoint to the main runloop used to drive the
774+
/// concurrency runtime and drain the main queue. This function must not return.
775+
/// Note: If the hook is wrapping the original function and the `compatOverride`
776+
/// is passed in, the `original` function pointer must be passed into the
777+
/// compatibility override function as the original function.
778+
typedef SWIFT_CC(swift) void (*swift_task_asyncMainDrainQueue_original)();
779+
typedef SWIFT_CC(swift) void (*swift_task_asyncMainDrainQueue_override)(
780+
swift_task_asyncMainDrainQueue_original original);
781+
SWIFT_EXPORT_FROM(swift_Concurrency)
782+
SWIFT_CC(swift) void (*swift_task_asyncMainDrainQueue_hook)(
783+
swift_task_asyncMainDrainQueue_original original,
784+
swift_task_asyncMainDrainQueue_override compatOverride);
785+
773786
/// Initialize the runtime storage for a default actor.
774787
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
775788
void swift_defaultActor_initialize(DefaultActor *actor);

stdlib/public/CompatibilityOverride/CompatibilityOverride.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ static OverrideSection *getOverrideSectionPtr() {
8989
return nullptr; \
9090
return Section->name; \
9191
}
92+
93+
#define OVERRIDE_NORETURN(name, attrs, ccAttrs, namespace, typedArgs, namedArgs) \
94+
Override_ ## name swift::getOverride_ ## name() { \
95+
auto *Section = getOverrideSectionPtr(); \
96+
if (Section == nullptr) \
97+
nullptr; \
98+
Section->name; \
99+
}
100+
92101
#include COMPATIBILITY_OVERRIDE_INCLUDE_PATH
93102

94103
#endif // #ifdef SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT

stdlib/public/CompatibilityOverride/CompatibilityOverrideConcurrency.def

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@
7777
# define OVERRIDE_TASK_GROUP OVERRIDE
7878
# define OVERRIDE_TASK_LOCAL OVERRIDE
7979
# define OVERRIDE_TASK_STATUS OVERRIDE
80+
#ifndef HOOKED_OVERRIDE_TASK_NORETURN
81+
# define HOOKED_OVERRIDE_TASK_NORETURN(name, attrs, ccAttrs, namespace, \
82+
typedArgs, namedArgs) \
83+
OVERRIDE(name, void, attrs, ccAttrs, namespace, typedArgs, namedArgs)
84+
#endif
8085
#else
8186
# ifndef OVERRIDE_ACTOR
8287
# define OVERRIDE_ACTOR(...)
@@ -96,6 +101,9 @@
96101
# ifndef OVERRIDE_TASK_STATUS
97102
# define OVERRIDE_TASK_STATUS(...)
98103
# endif
104+
# ifndef HOOKED_OVERRIDE_TASK_NORETURN
105+
# define HOOKED_OVERRIDE_TASK_NORETURN(...)
106+
# endif
99107
#endif
100108

101109
OVERRIDE_ACTOR(task_enqueue, void,
@@ -181,9 +189,10 @@ OVERRIDE_TASK(task_createNullaryContinuationJob, NullaryContinuationJob *,
181189
(size_t priority,
182190
AsyncTask *continuation), (priority, continuation))
183191

184-
OVERRIDE_TASK(task_asyncMainDrainQueue, void,
185-
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift), swift::,
186-
, )
192+
HOOKED_OVERRIDE_TASK_NORETURN(task_asyncMainDrainQueue,
193+
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
194+
swift::, ,)
195+
187196

188197
OVERRIDE_TASK(task_suspend, AsyncTask *,
189198
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
@@ -380,3 +389,4 @@ OVERRIDE_TASK_STATUS(task_escalate, JobPriority,
380389
#undef OVERRIDE_TASK_GROUP
381390
#undef OVERRIDE_TASK_LOCAL
382391
#undef OVERRIDE_TASK_STATUS
392+
#undef HOOKED_OVERRIDE_TASK_NORETURN

stdlib/public/Concurrency/Task.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,5 +1589,49 @@ static void swift_task_asyncMainDrainQueueImpl() {
15891589
#endif
15901590
}
15911591

1592+
SWIFT_CC(swift)
1593+
void (*swift::swift_task_asyncMainDrainQueue_hook)(
1594+
swift_task_asyncMainDrainQueue_original original,
1595+
swift_task_asyncMainDrainQueue_override compatOverride) = nullptr;
1596+
15921597
#define OVERRIDE_TASK COMPATIBILITY_OVERRIDE
1598+
1599+
#ifdef SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT
1600+
/// The original COMPATIBILITY_OVERRIDE defined in CompatibilityOverride.h
1601+
/// returns the result of the impl function and override function. This results
1602+
/// in a warning emitted for noreturn functions. Overriding the override macro
1603+
/// to not return.
1604+
#define HOOKED_OVERRIDE_TASK_NORETURN(name, attrs, ccAttrs, namespace, \
1605+
typedArgs, namedArgs) \
1606+
attrs ccAttrs void namespace swift_##name COMPATIBILITY_PAREN(typedArgs) { \
1607+
static Override_##name Override; \
1608+
static swift_once_t Predicate; \
1609+
swift_once( \
1610+
&Predicate, [](void *) { Override = getOverride_##name(); }, nullptr); \
1611+
if (swift_##name##_hook) { \
1612+
swift_##name##_hook(COMPATIBILITY_UNPAREN_WITH_COMMA(namedArgs) \
1613+
swift_##name##Impl, \
1614+
Override); \
1615+
abort(); \
1616+
} \
1617+
if (Override != nullptr) \
1618+
Override(COMPATIBILITY_UNPAREN_WITH_COMMA(namedArgs) \
1619+
swift_##name##Impl); \
1620+
swift_##name##Impl COMPATIBILITY_PAREN(namedArgs); \
1621+
}
1622+
1623+
#else // ifndef SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT
1624+
// Call directly through to the original implementation when we don't support
1625+
// overrides.
1626+
#define HOOKED_OVERRIDE_TASK_NORETURN(name, attrs, ccAttrs, namespace, \
1627+
typedArgs, namedArgs) \
1628+
attrs ccAttrs void namespace swift_##name COMPATIBILITY_PAREN(typedArgs) { \
1629+
if (swift_##name##_hook) { \
1630+
swift_##name##_hook(swift_##name##Impl, nullptr); \
1631+
abort(); \
1632+
} \
1633+
swift_##name##Impl COMPATIBILITY_PAREN(namedArgs); \
1634+
}
1635+
#endif // #else SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT
1636+
15931637
#include COMPATIBILITY_OVERRIDE_INCLUDE_PATH

unittests/runtime/CompatibilityOverrideConcurrency.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
#include "swift/Runtime/Concurrency.h"
1919
#include "gtest/gtest.h"
2020

21+
#if __has_include("pthread.h")
22+
23+
#define RUN_ASYNC_MAIN_DRAIN_QUEUE_TEST 1
24+
#include <pthread.h>
25+
#endif // HAVE_PTHREAD_H
26+
2127
#include <stdio.h>
2228

2329
using namespace swift;
@@ -44,6 +50,15 @@ ExecutorRef getEmptyValue() {
4450
Ran = true; \
4551
return getEmptyValue<ret>(); \
4652
}
53+
#define OVERRIDE_TASK_NORETURN(name, attrs, ccAttrs, namespace, typedArgs, \
54+
namedArgs) \
55+
static ccAttrs void name##Override(COMPATIBILITY_UNPAREN_WITH_COMMA( \
56+
typedArgs) Original_##name originalImpl) { \
57+
if (!EnableOverride) \
58+
originalImpl COMPATIBILITY_PAREN(namedArgs); \
59+
Ran = true; \
60+
}
61+
4762
#include "../../stdlib/public/CompatibilityOverride/CompatibilityOverrideConcurrency.def"
4863

4964
struct OverrideSection {
@@ -82,6 +97,16 @@ static void swift_task_enqueueMainExecutor_override(
8297
Ran = true;
8398
}
8499

100+
#ifdef RUN_ASYNC_MAIN_DRAIN_QUEUE_TEST
101+
[[noreturn]] SWIFT_CC(swift)
102+
static void swift_task_asyncMainDrainQueue_override_fn(
103+
swift_task_asyncMainDrainQueue_original original,
104+
swift_task_asyncMainDrainQueue_override compatOverride) {
105+
Ran = true;
106+
pthread_exit(nullptr); // noreturn function
107+
}
108+
#endif
109+
85110
class CompatibilityOverrideConcurrencyTest : public ::testing::Test {
86111
protected:
87112
virtual void SetUp() {
@@ -100,6 +125,10 @@ class CompatibilityOverrideConcurrencyTest : public ::testing::Test {
100125
swift_task_enqueueGlobalWithDelay_override;
101126
swift_task_enqueueMainExecutor_hook =
102127
swift_task_enqueueMainExecutor_override;
128+
#ifdef RUN_ASYNC_MAIN_DRAIN_QUEUE_TEST
129+
swift_task_asyncMainDrainQueue_hook =
130+
swift_task_asyncMainDrainQueue_override_fn;
131+
#endif
103132
}
104133

105134
virtual void TearDown() {
@@ -255,4 +284,27 @@ TEST_F(CompatibilityOverrideConcurrencyTest, test_swift_task_escalate) {
255284
swift_task_escalate(nullptr, {});
256285
}
257286

287+
#if RUN_ASYNC_MAIN_DRAIN_QUEUE_TEST
288+
TEST_F(CompatibilityOverrideConcurrencyTest, test_swift_task_asyncMainDrainQueue) {
289+
290+
auto runner = [](void *) -> void * {
291+
swift_task_asyncMainDrainQueue();
292+
return nullptr;
293+
};
294+
295+
int ret = 0;
296+
pthread_t thread;
297+
pthread_attr_t attrs;
298+
ret = pthread_attr_init(&attrs);
299+
ASSERT_EQ(ret, 0);
300+
ret = pthread_create(&thread, &attrs, runner, nullptr);
301+
ASSERT_EQ(ret, 0);
302+
void * result = nullptr;
303+
ret = pthread_join(thread, &result);
304+
ASSERT_EQ(ret, 0);
305+
pthread_attr_destroy(&attrs);
306+
ASSERT_EQ(ret, 0);
307+
}
308+
#endif
309+
258310
#endif

0 commit comments

Comments
 (0)