git: 3d3eeda198a9 - stable/15 - libc: Fix assert() sanitiser for C++ contextual bool conversion
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 02 Jul 2026 07:47:03 UTC
The branch stable/15 has been updated by fuz:
URL: https://cgit.FreeBSD.org/src/commit/?id=3d3eeda198a924189b47eb0ba7f6f0dd3defbd89
commit 3d3eeda198a924189b47eb0ba7f6f0dd3defbd89
Author: Faraz Vahedi <kfv@kfv.io>
AuthorDate: 2026-06-06 11:38:47 +0000
Commit: Robert Clausecker <fuz@FreeBSD.org>
CommitDate: 2026-07-02 07:44:26 +0000
libc: Fix assert() sanitiser for C++ contextual bool conversion
Replace the `(bool(*)(bool))` probe in `__assert_sanitize()` with an unevaluated
conditional expression, so types with `explicit operator bool()` that require a
contextually converted constant expression of type `bool` are handled correctly.
Ergo, arity check is now performed separately via `__assert_sanitize_arity()`, a
unary template whose parameter pack must bind to exactly on argument after
`__VA_ARGS__` is substituted into the call.
Also align NDEBUG with C23 requirements.
Reported by: dim, aokblast
Signed-off-by: Faraz Vahedi <kfv@kfv.io>
Reviewed by: aokblast, fuz
MFC after: 1 week
Fixes: 867b51452ea78ece0b312a387e63fdbc2a11056a
Pull Request: https://github.com/freebsd/freebsd-src/pull/2265
(cherry picked from commit 48d20fd1cf90179e778c6155900cbed2be140273)
---
include/assert.h | 34 +++++++---------------------------
1 file changed, 7 insertions(+), 27 deletions(-)
diff --git a/include/assert.h b/include/assert.h
index 75d3e62e8932..afbf2c1092e0 100644
--- a/include/assert.h
+++ b/include/assert.h
@@ -53,35 +53,15 @@
#endif /* __BSD_VISIBLE */
#else
#ifdef __cplusplus
-#if __cplusplus < 202002L
-/*
- * C++ modes prior to C++20 cannot simultaneously satisfy all three
- * desirable properties of the sanitiser:
- *
- * Approach No double-eval Lambda support Arity check
- * ----------------------------- -------------- -------------- -----------
- * sizeof(cast(expression)) yes no yes
- * static_cast<bool>(expression) no yes no
- * (void)bool(expression) no yes no
- *
- * NOTE: C++20 introduced lambdas in unevaluated contexts; see P0315R4.
- *
- * Since no approach satisfies all three below C++20, the least harmful
- * choice is to forgo the check entirely rather than silently break one
- * of the remaining guarantees.
- *
- */
-#define __assert_sanitize(...) ((void)0)
-#else
-#define __assert_sanitize(...) (void)sizeof(((bool(*)(bool))0)(__VA_ARGS__))
-#endif /* __cplusplus < 202002L */
+#define assert(...) ((void)(bool(__VA_ARGS__) ? ((void)0) : \
+ __assert(__func__, __FILE__, __LINE__, \
+ #__VA_ARGS__)))
#else
-#define __assert_sanitize(...) (void)sizeof(((_Bool(*)(_Bool))0)(__VA_ARGS__))
-#endif /* __cplusplus */
-#define assert(...) (__assert_sanitize(__VA_ARGS__), \
- (__VA_ARGS__) ? (void)0 : \
- __assert(__func__, __FILE__, \
+#define assert(...) ((void)sizeof(((_Bool(*)(_Bool))0)(__VA_ARGS__)), \
+ (__VA_ARGS__) ? (void)0 : \
+ __assert(__func__, __FILE__, \
__LINE__, #__VA_ARGS__))
+#endif /* __cplusplus */
#define _assert(...) assert(__VA_ARGS__)
#if __BSD_VISIBLE
#define __assert_unreachable() assert(0 && "unreachable segment reached")