Interestingly, pthread_cleanup_push/pop are allowed by POSIX to be
implemented as macros opening and closing an lexical scope. By using
the well-known trick of do { ... } while (0) [1], we prevent potential
scoping issues in surrounding code when the macro is expanded.

Removing the comma operator in pthread_cleanup_pop prevents compiler
warnings against not using the return value of the expression, and a
against an empty statement.

[1]: https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html

Signed-off-by: Antonin Décimo <[email protected]>
---
 .../winpthreads/include/pthread.h             | 22 ++++++++++++-------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/mingw-w64-libraries/winpthreads/include/pthread.h 
b/mingw-w64-libraries/winpthreads/include/pthread.h
index 6ea4f0184..e8df91e91 100644
--- a/mingw-w64-libraries/winpthreads/include/pthread.h
+++ b/mingw-w64-libraries/winpthreads/include/pthread.h
@@ -208,16 +208,22 @@ struct _pthread_cleanup
     _pthread_cleanup *next;
 };
 
-#define pthread_cleanup_push(F, A)\
-{\
-    const _pthread_cleanup _pthread_cup = {(F), (A), *pthread_getclean()};\
-    __sync_synchronize();\
-    *pthread_getclean() = (_pthread_cleanup *) &_pthread_cup;\
-    __sync_synchronize()
+#define pthread_cleanup_push(F, A)                                      \
+    do {                                                                \
+        const _pthread_cleanup _pthread_cup =                           \
+            { (F), (A), *pthread_getclean() };                          \
+        __sync_synchronize();                                           \
+        *pthread_getclean() = (_pthread_cleanup *) &_pthread_cup;       \
+        __sync_synchronize();                                           \
+        do {                                                            \
+            do {} while (0)
 
 /* Note that if async cancelling is used, then there is a race here */
-#define pthread_cleanup_pop(E)\
-    (*pthread_getclean() = _pthread_cup.next, ((E) ? 
(_pthread_cup.func((pthread_once_t *)_pthread_cup.arg)) : (void)0));}
+#define pthread_cleanup_pop(E)                                          \
+        } while (0);                                                    \
+        *pthread_getclean() = _pthread_cup.next;                        \
+        if ((E)) _pthread_cup.func((pthread_once_t *)_pthread_cup.arg); \
+    } while (0)
 
 #ifndef SCHED_OTHER
 /* Some POSIX realtime extensions, mostly stubbed */
-- 
2.43.0



_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to