PR libstdc++/125228
This patch replaces the uses of `assert` in ryu and debug.cc with
`__glibcxx_assert`, and removed their direct dependency on `<cassert>`.
To avoid modifying the third-party ryu headers, this patch use
`#pragma push_macro` / `#pragma pop_macro` to locally
redefine `assert` to `__glibcxx_assert` when including the ryu headers.
libstdc++-v3/ChangeLog:
PR libstdc++/125228
* src/c++11/debug.cc: Replace assert with __glibcxx_assert,
and remove the include of <cassert>.
* src/c++17/floating_to_chars.cc: Likewise, but redefine
assert as __glibcxx_assert using pragma push/pop_macro.
--
From 76f866652f9a7e2fc4faf012f6b356e9a85ecb8d Mon Sep 17 00:00:00 2001
From: dragon-archer <[email protected]>
Date: Fri, 8 May 2026 19:14:49 +0800
Subject: [PATCH] libstdc++: Use __glibcxx_assert instead of assert
Unlike `__glibcxx_assert` which is guarded
by `_GLIBCXX_ASSERTIONS` and enabled only in Debug
build of libstdc++, `assert` is either always enabled, or
always disabled if manually defining `NDEBUG` before
`#include <cassert>` or `#include <assert.h>`. This not
only makes `assert` inflexible, but also introduces extra
runtime overhead and/or increased binary size in Release
builds.
Uses of `assert` without `NDEBUG` introduces `__FILE__`
into the final library, and can be easily found using
`string`
This is a long standing issue, dating from at least GCC
8.5.0 to latest GCC 16.1.0
---
libstdc++-v3/src/c++11/debug.cc | 33 ++++++++++-----------
libstdc++-v3/src/c++17/floating_to_chars.cc | 5 +++-
2 files changed, 20 insertions(+), 18 deletions(-)
diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc
index 7049d5f1238..9a36bdfabb9 100644
--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -33,7 +33,6 @@
#include <debug/safe_local_iterator.h>
#include <debug/vector>
-#include <cassert>
#include <cstdio> // for std::fprintf, stderr
#include <cstdlib> // for std::abort
#include <cctype> // for std::isspace.
@@ -888,7 +887,7 @@ namespace
void
print_named_name(PrintContext& ctx, const _Parameter::_Named& named)
{
- assert(named._M_name);
+ __glibcxx_assert(named._M_name);
pretty_print(ctx, named._M_name, print_word);
}
@@ -985,7 +984,7 @@ namespace
print_iterator_state(ctx, iterator);
else if (__builtin_strcmp(fname, "sequence") == 0)
{
- assert(iterator._M_sequence);
+ __glibcxx_assert(iterator._M_sequence);
print_address(ctx, iterator._M_sequence);
}
else if (__builtin_strcmp(fname, "seq_type") == 0)
@@ -999,43 +998,43 @@ namespace
void
print_field(PrintContext& ctx, const _Parameter& param, const char* fname)
{
- assert(param._M_kind != _Parameter::__unused_param);
+ __glibcxx_assert(param._M_kind != _Parameter::__unused_param);
const auto& variant = param._M_variant;
switch (param._M_kind)
{
case _Parameter::__iterator:
if (!print_iterator_field(ctx, fname, variant._M_iterator))
- assert(false);
+ __glibcxx_assert(false);
break;
case _Parameter::__sequence:
if (!print_instance_field(ctx, fname, variant._M_sequence))
- assert(false);
+ __glibcxx_assert(false);
break;
case _Parameter::__integer:
if (!print_named_field(ctx, fname, variant._M_integer))
- assert(false);
+ __glibcxx_assert(false);
break;
case _Parameter::__string:
if (!print_named_field(ctx, fname, variant._M_string))
- assert(false);
+ __glibcxx_assert(false);
break;
case _Parameter::__instance:
if (!print_instance_field(ctx, fname, variant._M_instance))
- assert(false);
+ __glibcxx_assert(false);
break;
case _Parameter::__iterator_value_type:
if (!print_type_field(ctx, fname, variant._M_iterator_value_type))
- assert(false);
+ __glibcxx_assert(false);
break;
default:
- assert(false);
+ __glibcxx_assert(false);
break;
}
}
@@ -1198,9 +1197,9 @@ namespace
}
// Get the parameter number
- assert(*str >= '1' && *str <= '9');
+ __glibcxx_assert(*str >= '1' && *str <= '9');
size_t param_index = *str - '0' - 1;
- assert(param_index < num_parameters);
+ __glibcxx_assert(param_index < num_parameters);
const auto& param = parameters[param_index];
// '.' separates the parameter number from the field
@@ -1208,7 +1207,7 @@ namespace
++str;
if (*str != '.')
{
- assert(*str == ';');
+ __glibcxx_assert(*str == ';');
++str;
if (param._M_kind == _Parameter::__integer)
print_integer(ctx, param._M_variant._M_integer._M_value);
@@ -1226,8 +1225,8 @@ namespace
++str;
while (*str != ';')
{
- assert(*str);
- assert(field_idx < max_field_len - 1);
+ __glibcxx_assert(*str);
+ __glibcxx_assert(field_idx < max_field_len - 1);
field[field_idx++] = *str++;
}
++str;
@@ -1382,7 +1381,7 @@ namespace __gnu_debug
print_literal(ctx, "Error: ");
// Print the error message
- assert(_M_text);
+ __glibcxx_assert(_M_text);
print_string(ctx, _M_text, -1, _M_parameters, _M_num_parameters);
print_literal(ctx, ".\n");
diff --git a/libstdc++-v3/src/c++17/floating_to_chars.cc
b/libstdc++-v3/src/c++17/floating_to_chars.cc
index 9bddffd70ff..264e520e187 100644
--- a/libstdc++-v3/src/c++17/floating_to_chars.cc
+++ b/libstdc++-v3/src/c++17/floating_to_chars.cc
@@ -26,7 +26,6 @@
#include <bit>
#include <cfenv>
-#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
@@ -106,6 +105,9 @@ namespace
namespace ryu
{
+#pragma push_macro("assert")
+#undef assert
+#define assert __glibcxx_assert
#include "ryu/common.h"
#include "ryu/digit_table.h"
#include "ryu/d2s_intrinsics.h"
@@ -123,6 +125,7 @@ namespace
# include "ryu/ryu_generic_128.h"
# include "ryu/generic_128.c"
} // namespace generic128
+#pragma pop_macro("assert")
using generic128::floating_decimal_128;
using generic128::generic_binary_to_decimal;
--
2.54.0.windows.1