Bug 71960 - __glibcxx_assert and Debug Mode checks can't be used in constexpr functions
Summary: __glibcxx_assert and Debug Mode checks can't be used in constexpr functions
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 7.0
: P3 minor
Target Milestone: 11.0
Assignee: Jonathan Wakely
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2016-07-21 17:24 UTC by Jonathan Wakely
Modified: 2020-09-11 10:59 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-04-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2016-07-21 17:24:03 UTC
This affects clamp, min_element, max_element and minmax_element, at least.

For the simple __glibcxx_assert uses it would be nice to have a constexpr replacement for __replacement_assert which could be used in those places.

In more complex cases we could drop the 'constexpr' specifier but that would mean some valid code wouldn't compile in Debug Mode.
Comment 1 Jonathan Wakely 2016-07-21 17:26:41 UTC
Alternatively, compiler magic which allows the checks to be skipped when used in a constant expression would allow us to support all valid code, at the expense of not diagnosing misuses in constant expressions.
Comment 2 Jonathan Wakely 2016-08-22 09:58:04 UTC
*** Bug 77303 has been marked as a duplicate of this bug. ***
Comment 4 GCC Commits 2020-08-26 13:49:04 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:3eefb302d2bd8502cb3d8fe44e672b11092ccaf6

commit r11-2881-g3eefb302d2bd8502cb3d8fe44e672b11092ccaf6
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Aug 26 14:47:51 2020 +0100

    libstdc++: Enable assertions in constexpr string_view members [PR 71960]
    
    Since GCC 6.1 there is no reason we can't just use __glibcxx_assert in
    constexpr functions in string_view. As long as the condition is true,
    there will be no call to std::__replacement_assert that would make the
    function ineligible for constant evaluation.
    
            PR libstdc++/71960
            * include/experimental/string_view (basic_string_view):
            Enable debug assertions.
            * include/std/string_view (basic_string_view):
            Likewise.
Comment 5 GCC Commits 2020-08-26 13:49:58 UTC
The releases/gcc-10 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:85847fd421d7760f45f0e69c7ae3607f2f898bb8

commit r10-8676-g85847fd421d7760f45f0e69c7ae3607f2f898bb8
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Aug 26 14:47:51 2020 +0100

    libstdc++: Enable assertions in constexpr string_view members [PR 71960]
    
    Since GCC 6.1 there is no reason we can't just use __glibcxx_assert in
    constexpr functions in string_view. As long as the condition is true,
    there will be no call to std::__replacement_assert that would make the
    function ineligible for constant evaluation.
    
            PR libstdc++/71960
            * include/experimental/string_view (basic_string_view):
            Enable debug assertions.
            * include/std/string_view (basic_string_view):
            Likewise.
    
    (cherry picked from commit 3eefb302d2bd8502cb3d8fe44e672b11092ccaf6)
Comment 6 GCC Commits 2020-08-26 13:50:55 UTC
The releases/gcc-9 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:42fb390082b59c0b5af6a9f1e5a2e608ccb8e193

commit r9-8833-g42fb390082b59c0b5af6a9f1e5a2e608ccb8e193
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Aug 26 14:47:51 2020 +0100

    libstdc++: Enable assertions in constexpr string_view members [PR 71960]
    
    Since GCC 6.1 there is no reason we can't just use __glibcxx_assert in
    constexpr functions in string_view. As long as the condition is true,
    there will be no call to std::__replacement_assert that would make the
    function ineligible for constant evaluation.
    
            PR libstdc++/71960
            * include/experimental/string_view (basic_string_view):
            Enable debug assertions.
            * include/std/string_view (basic_string_view):
            Likewise.
    
    (cherry picked from commit 3eefb302d2bd8502cb3d8fe44e672b11092ccaf6)
Comment 7 GCC Commits 2020-09-01 19:55:26 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:10f51543bb81cc953792270b40a9c812049e8b4c

commit r11-2971-g10f51543bb81cc953792270b40a9c812049e8b4c
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Sep 1 20:52:26 2020 +0100

    libstdc++: Add compile-time checks to__glibcxx_assert [PR 71960]
    
    This change evaluates __glibcxx_assert checks unconditionally when a
    function is being constant evaluated (when std::is_constant_evaluated()
    is true). If the check fails, compilation will fail with an error.
    
    If the function isn't being constant evaluated, the normal runtime check
    will be done if enabled by _GLIBCXX_ASSERTIONS or _GLIBCXX_DEBUG, the
    same as before.
    
    Tangentially, the __glibcxx_assert and _GLIBCXX_PARALLEL_ASSERT macros
    are changed to expand to 'do { } while (false)' when assertions are
    disabled, instead of expanding to nothing. This avoids -Wempty-body
    warnings when a disabled assertion is used in an 'if' or 'else'
    statement e.g.
    
      if constexpr (/* precondition is testable */)
        __glibcxx_assert(precondition);
    
    a.C:9:27: warning: suggest braces around empty body in an âifâ statement [-Wempty-body]
        9 |     __glibcxx_assert(precondition);
          |                                  ^
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/71960
            * include/bits/c++config (__glibcxx_assert_impl): Remove
            do-while so that uses of the macro need to add it.
            (__glibcxx_assert): Rename macro for runtime assertions
            to __glibcxx_assert_2.
            (__glibcxx_assert_1): Define macro for constexpr assertions.
            (__glibcxx_assert): Define macro for constexpr and runtime
            assertions.
            * include/bits/range_access.h (ranges::advance): Remove
            redundant precondition checks during constant evaluation.
            * include/parallel/base.h (_GLIBCXX_PARALLEL_ASSERT): Always
            use do-while in macro expansion.
            * include/std/ranges (iota_view::iota_view(W, B)): Remove
            redundant braces.
Comment 8 GCC Commits 2020-09-11 10:52:57 UTC
The releases/gcc-8 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:877cdcc714704e242f477580d81397cc1d0fc90e

commit r8-10444-g877cdcc714704e242f477580d81397cc1d0fc90e
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Sep 10 15:49:26 2020 +0100

    libstdc++: Enable assertions in constexpr string_view members [PR 71960]
    
    There is no longer any reason we can't just use __glibcxx_assert in
    constexpr functions. As long as the condition is true, there will be no
    call to std::__replacement_assert that would make the function
    ineligible for constant evaluation.
    
            PR libstdc++/71960
            * include/experimental/string_view (basic_string_view):
            Enable debug assertions.
            * include/std/string_view (basic_string_view):
            Likewise.
Comment 9 Jonathan Wakely 2020-09-11 10:59:23 UTC
I think these assertions should always have been OK in constexpr functions, but G++ was incorrectly evaluating the untaken branch. That has been fixed for some time, so the checks work. The commented out checks in string_view have been enabled on all branches, and on trunk the assertions are now unconditionally checked during constant evaluation, not only when _GLIBCXX_ASSERTIONS is defined.