public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/112882] New: [14 Regression] std::clamp no longer usable in header only mode
@ 2023-12-06 15:20 tnfchris at gcc dot gnu.org
2023-12-06 16:47 ` [Bug libstdc++/112882] " redi at gcc dot gnu.org
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: tnfchris at gcc dot gnu.org @ 2023-12-06 15:20 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112882
Bug ID: 112882
Summary: [14 Regression] std::clamp no longer usable in header
only mode
Product: gcc
Version: 14.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: tnfchris at gcc dot gnu.org
CC: redi at gcc dot gnu.org
Target Milestone: ---
I know this is not a supported scenario, but I'm wondering if it's still easy
to support.
We have some libraries that use C++ mostly as an abstraction layer and try to
ensure that it needs no runtime support from libstdc++.
A recent commit: g:5e8a30d8b8f4d7ea0a8340b46c1e0c865dbde781 changed how
`__glibcxx_assert` is defined and now always calls
`std::__glibcxx_assert_fail`.
This means that now you always need libstdc++ even in contex where things would
have been folded away before. Similarly we're getting the same thing through
usage of `std::unique_ptr`.
It seems that undefining `_GLIBCXX_VERBOSE_ASSERT` gets it to go to
`__builtin_abort()` which makes it work again.
If this change was intentional, would it be possible to make
`_GLIBCXX_VERBOSE_ASSERT` user configurable?
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug libstdc++/112882] [14 Regression] std::clamp no longer usable in header only mode
2023-12-06 15:20 [Bug libstdc++/112882] New: [14 Regression] std::clamp no longer usable in header only mode tnfchris at gcc dot gnu.org
@ 2023-12-06 16:47 ` redi at gcc dot gnu.org
2023-12-06 16:55 ` redi at gcc dot gnu.org
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2023-12-06 16:47 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112882
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Ever confirmed|0 |1
Last reconfirmed| |2023-12-06
Status|UNCONFIRMED |NEW
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Tamar Christina from comment #0)
> I know this is not a supported scenario, but I'm wondering if it's still
> easy to support.
>
> We have some libraries that use C++ mostly as an abstraction layer and try
> to ensure that it needs no runtime support from libstdc++.
>
> A recent commit: g:5e8a30d8b8f4d7ea0a8340b46c1e0c865dbde781 changed how
> `__glibcxx_assert` is defined and now always calls
> `std::__glibcxx_assert_fail`.
>
> This means that now you always need libstdc++ even in contex where things
> would have been folded away before. Similarly we're getting the same thing
> through usage of `std::unique_ptr`.
Ugh, that's undesirable. It should only depend on that symbol when
_GLIBCXX_ASSERTIONS is defined, but the change means we also use that symbol
for constexpr checks.
I'm surprised it doesn't get folded away though, since the code looks like:
if (std::__is_constant_evaluated())
if (__builtin_expect(COND, false))
__glibcxx_assert_fail(...);
Since __is_constant_evaluated is always false at runtime, that function can
never be called. Either it's needed during compile-time and makes the program
ill-formed, or it's not needed at all.
Ah, __is_constant_evaluated() is not marked always_inline, so at -O0 it just
looks like a normal function call.
> It seems that undefining `_GLIBCXX_VERBOSE_ASSERT` gets it to go to
> `__builtin_abort()` which makes it work again.
>
> If this change was intentional, would it be possible to make
> `_GLIBCXX_VERBOSE_ASSERT` user configurable?
You can use --disable-libstdcxx-verbose for that, or do you need to control it
during preprocessing?
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug libstdc++/112882] [14 Regression] std::clamp no longer usable in header only mode
2023-12-06 15:20 [Bug libstdc++/112882] New: [14 Regression] std::clamp no longer usable in header only mode tnfchris at gcc dot gnu.org
2023-12-06 16:47 ` [Bug libstdc++/112882] " redi at gcc dot gnu.org
@ 2023-12-06 16:55 ` redi at gcc dot gnu.org
2023-12-06 17:07 ` redi at gcc dot gnu.org
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2023-12-06 16:55 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112882
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |ASSIGNED
Assignee|unassigned at gcc dot gnu.org |redi at gcc dot gnu.org
Target Milestone|--- |14.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug libstdc++/112882] [14 Regression] std::clamp no longer usable in header only mode
2023-12-06 15:20 [Bug libstdc++/112882] New: [14 Regression] std::clamp no longer usable in header only mode tnfchris at gcc dot gnu.org
2023-12-06 16:47 ` [Bug libstdc++/112882] " redi at gcc dot gnu.org
2023-12-06 16:55 ` redi at gcc dot gnu.org
@ 2023-12-06 17:07 ` redi at gcc dot gnu.org
2023-12-06 17:09 ` redi at gcc dot gnu.org
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2023-12-06 17:07 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112882
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
That change was broken anyway: when _GLIBCXX_ASSERTIONS was not defined, the
condition in the assertion is if constexpr (is_constant_evaluated()) which is
always true, even when not actually doing constant eval.
I'll test this:
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -538,6 +538,7 @@ namespace std
// This can be used without checking if the compiler supports the feature.
// The macro _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED can be used to check if
// the compiler support is present to make this function work as expected.
+ __attribute__((__always_inline__))
_GLIBCXX_CONSTEXPR inline bool
__is_constant_evaluated() _GLIBCXX_NOEXCEPT
{
@@ -589,19 +590,28 @@ namespace std
#endif
#if defined(_GLIBCXX_ASSERTIONS)
-# define _GLIBCXX_DO_ASSERT true
-#elif _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
-# define _GLIBCXX_DO_ASSERT std::__is_constant_evaluated()
-#else
-# define _GLIBCXX_DO_ASSERT false
-#endif
-
# define __glibcxx_assert(cond)
\
do { \
- if _GLIBCXX17_CONSTEXPR (_GLIBCXX_DO_ASSERT) \
- if (__builtin_expect(!bool(cond), false))
\
- _GLIBCXX_ASSERT_FAIL(cond); \
+ if (__builtin_expect(!bool(cond), false)) \
+ _GLIBCXX_ASSERT_FAIL(cond); \
} while (false)
+#elif _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
+namespace std
+{
+ __attribute__((__always_inline__,visibility("default")))
+ inline void
+ __glibcxx_compile_time_assert_fail()
+ { }
+}
+# define __glibcxx_assert(cond)
\
+ do { \
+ if (std::__is_constant_evaluated())
\
+ if (__builtin_expect(!bool(cond), false))
\
+ __glibcxx_compile_time_assert_fail(); \
+ } while (false)
+#else
+# define __glibcxx_assert(cond)
+#endif
// Macro indicating that TSAN is in use.
#if __SANITIZE_THREAD__
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug libstdc++/112882] [14 Regression] std::clamp no longer usable in header only mode
2023-12-06 15:20 [Bug libstdc++/112882] New: [14 Regression] std::clamp no longer usable in header only mode tnfchris at gcc dot gnu.org
` (2 preceding siblings ...)
2023-12-06 17:07 ` redi at gcc dot gnu.org
@ 2023-12-06 17:09 ` redi at gcc dot gnu.org
2023-12-06 17:20 ` redi at gcc dot gnu.org
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2023-12-06 17:09 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112882
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Priority|P3 |P1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug libstdc++/112882] [14 Regression] std::clamp no longer usable in header only mode
2023-12-06 15:20 [Bug libstdc++/112882] New: [14 Regression] std::clamp no longer usable in header only mode tnfchris at gcc dot gnu.org
` (3 preceding siblings ...)
2023-12-06 17:09 ` redi at gcc dot gnu.org
@ 2023-12-06 17:20 ` redi at gcc dot gnu.org
2023-12-07 8:23 ` tnfchris at gcc dot gnu.org
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2023-12-06 17:20 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112882
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This minimal fix is enough to remove the reference to __glibcxx_assert_fail
when optimization is enabled (at any level):
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -598,7 +598,7 @@ namespace std
# define __glibcxx_assert(cond)
\
do { \
- if _GLIBCXX17_CONSTEXPR (_GLIBCXX_DO_ASSERT) \
+ if (_GLIBCXX_DO_ASSERT) \
if (__builtin_expect(!bool(cond), false))
\
_GLIBCXX_ASSERT_FAIL(cond); \
} while (false)
But we still need the more complete fix for -O0.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug libstdc++/112882] [14 Regression] std::clamp no longer usable in header only mode
2023-12-06 15:20 [Bug libstdc++/112882] New: [14 Regression] std::clamp no longer usable in header only mode tnfchris at gcc dot gnu.org
` (4 preceding siblings ...)
2023-12-06 17:20 ` redi at gcc dot gnu.org
@ 2023-12-07 8:23 ` tnfchris at gcc dot gnu.org
2023-12-07 9:49 ` redi at gcc dot gnu.org
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: tnfchris at gcc dot gnu.org @ 2023-12-07 8:23 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112882
--- Comment #4 from Tamar Christina <tnfchris at gcc dot gnu.org> ---
Awesome! Thanks for taking a look!
> > It seems that undefining `_GLIBCXX_VERBOSE_ASSERT` gets it to go to
> > `__builtin_abort()` which makes it work again.
> >
> > If this change was intentional, would it be possible to make
> > `_GLIBCXX_VERBOSE_ASSERT` user configurable?
>
> You can use --disable-libstdcxx-verbose for that, or do you need to control
> it during preprocessing?
Yeah I meant during preprocessing, we distribute the library as source to
client too, so would be harder if they'd also need to recompile the toolchain
:)
Thanks for the fixes!
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug libstdc++/112882] [14 Regression] std::clamp no longer usable in header only mode
2023-12-06 15:20 [Bug libstdc++/112882] New: [14 Regression] std::clamp no longer usable in header only mode tnfchris at gcc dot gnu.org
` (5 preceding siblings ...)
2023-12-07 8:23 ` tnfchris at gcc dot gnu.org
@ 2023-12-07 9:49 ` redi at gcc dot gnu.org
2023-12-07 20:55 ` cvs-commit at gcc dot gnu.org
2023-12-07 21:03 ` redi at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2023-12-07 9:49 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112882
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The original effect of --disable-libstdcxx-verbose was to change the default
std::terminate handler, which is a configure-time property.
But it's now also used to decide whether to use the verbose assertion or just
abort. That latter property could be flipped at compile-time. Even with this
bug fixed, that might be useful (probably for stage 1 though).
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug libstdc++/112882] [14 Regression] std::clamp no longer usable in header only mode
2023-12-06 15:20 [Bug libstdc++/112882] New: [14 Regression] std::clamp no longer usable in header only mode tnfchris at gcc dot gnu.org
` (6 preceding siblings ...)
2023-12-07 9:49 ` redi at gcc dot gnu.org
@ 2023-12-07 20:55 ` cvs-commit at gcc dot gnu.org
2023-12-07 21:03 ` redi at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-12-07 20:55 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112882
--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:
https://gcc.gnu.org/g:1395c573c523762957bde8c2a08832c5f4350815
commit r14-6291-g1395c573c523762957bde8c2a08832c5f4350815
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Wed Dec 6 17:21:29 2023 +0000
libstdc++: Fix recent changes to __glibcxx_assert [PR112882]
The changes in r14-6198-g5e8a30d8b8f4d7 were broken, as I used
_GLIBCXX17_CONSTEXPR for the 'if _GLIBCXX17_CONSTEXPR (true)' condition,
forgetting that it would also be used for the is_constant_evaluated()
check. Using 'if constexpr (std::is_constant_evaluated())' is a bug.
Additionally, relying on __glibcxx_assert_fail to give a "not a constant
expression" error is a problem because at -O0 an undefined reference to
__glibcxx_assert_fail is present in the compiled code. This means you
can't use libstdc++ headers without also linking to libstdc++ for the
symbol definition.
This fix rewrites the __glibcxx_assert macro again. This still avoids
doing the duplicate checks, once for constexpr and once at runtime (if
_GLIBCXX_ASSERTIONS is defined). When _GLIBCXX_ASSERTIONS is defined we
still rely on __glibcxx_assert_fail to give a "not a constant
expression" error during constant evaluation (because when assertions
are defined it's not a problem to emit a reference to the symbol). But
when that macro is not defined, we use a new inline (but not constexpr)
overload of __glibcxx_assert_fail to cause compilation to fail. That
inline function doesn't cause an undefined reference to a symbol in the
library (and will be optimized away anyway).
We can also add always_inline to the __is_constant_evaluated function,
although this doesn't actually matter for -O0 and it's always inlined
with any optimization enabled.
libstdc++-v3/ChangeLog:
PR libstdc++/112882
* include/bits/c++config (__is_constant_evaluated): Add
always_inline attribute.
(_GLIBCXX_DO_ASSERT): Remove macro.
(__glibcxx_assert): Define separately for assertions-enabled and
constexpr-only cases.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug libstdc++/112882] [14 Regression] std::clamp no longer usable in header only mode
2023-12-06 15:20 [Bug libstdc++/112882] New: [14 Regression] std::clamp no longer usable in header only mode tnfchris at gcc dot gnu.org
` (7 preceding siblings ...)
2023-12-07 20:55 ` cvs-commit at gcc dot gnu.org
@ 2023-12-07 21:03 ` redi at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2023-12-07 21:03 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112882
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|ASSIGNED |RESOLVED
Resolution|--- |FIXED
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Fixed now - thanks for spotting the problem!
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2023-12-07 21:03 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-06 15:20 [Bug libstdc++/112882] New: [14 Regression] std::clamp no longer usable in header only mode tnfchris at gcc dot gnu.org
2023-12-06 16:47 ` [Bug libstdc++/112882] " redi at gcc dot gnu.org
2023-12-06 16:55 ` redi at gcc dot gnu.org
2023-12-06 17:07 ` redi at gcc dot gnu.org
2023-12-06 17:09 ` redi at gcc dot gnu.org
2023-12-06 17:20 ` redi at gcc dot gnu.org
2023-12-07 8:23 ` tnfchris at gcc dot gnu.org
2023-12-07 9:49 ` redi at gcc dot gnu.org
2023-12-07 20:55 ` cvs-commit at gcc dot gnu.org
2023-12-07 21:03 ` redi at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).