[PATCH] Enhance _GLIBCXX_DEBUG constexpr support
François Dumont
frs.dumont@gmail.com
Mon Dec 2 19:31:00 GMT 2019
Hi
   Here is a patch to enhance constexpr support in _GLIBCXX_DEBUG. I
work on std::lower_bound/upper_bound to find out if Debug mode is well
prepared. I'll continue on other algos later.
   I initially hope that I could count on the compiler for the
valid_range check. But for lower_bound/upper_bound there is no constexpr
dedicated implementation like for copy/copy_backward so it implies
changing the existing implementation. So I tried to change the
while(__len > 0) into a while(__len != 0) and it gave:
constexpr_valid_range_neg.cc:35:20: error: non-constant condition for
static assertion
  35 | static_assert(test1()); // { dg-error "" }
     |              ~~~~~^~
In file included from
/home/fdt/dev/gcc/install/include/c++/10.0.0/algorithm:61,
                from constexpr_valid_range_neg.cc:22:
constexpr_valid_range_neg.cc:35:20:Â Â in âconstexprâ expansion of âtest1()â
constexpr_valid_range_neg.cc:30:38:Â Â in âconstexprâ expansion of
âstd::lower_bound<const int*, int>(ca0.std::array<int, 12>::end(),
ca0.std::array<int, 12>::begin(), 6)â
/home/fdt/dev/gcc/install/include/c++/10.0.0/bits/stl_algobase.h:1484:32:
in âconstexprâ expansion of âstd::__lower_bound<const int*, int,
__gnu_cxx::__ops::_Iter_less_val>(__first, __last, (* & __val),
__gnu_cxx::__ops::__iter_less_val())â
/home/fdt/dev/gcc/install/include/c++/10.0.0/bits/stl_algobase.h:1444:7:
error: âconstexprâ loop iteration count exceeds limit of 262144 (use
â-fconstexpr-loop-limit=â to increase the limit)
 1444 |      while (__len != 0)
     |      ^~~~~
   It seems ok but it isn't. The compiler had to loop 262144 times to
eventually give this status which is not even clear about the fact that
begin/end has been inverted. It is a quite heavy operation for a limited
result.
   So this patch rather enable _GLIBCXX_DEBUG valid_range check which
gives:
constexpr_valid_range_neg.cc:35:20: error: non-constant condition for
static assertion
  35 | static_assert(test1()); // { dg-error "" }
     |              ~~~~~^~
In file included from
/home/fdt/dev/gcc/install/include/c++/10.0.0/debug/debug.h:90,
                from
/home/fdt/dev/gcc/install/include/c++/10.0.0/bits/stl_algobase.h:69,
                from
/home/fdt/dev/gcc/install/include/c++/10.0.0/algorithm:61,
                from constexpr_valid_range_neg.cc:22:
constexpr_valid_range_neg.cc:35:20:Â Â in âconstexprâ expansion of âtest1()â
constexpr_valid_range_neg.cc:30:38:Â Â in âconstexprâ expansion of
âstd::lower_bound<const int*, int>(ca0.std::__debug::array<int,
12>::end(), ca0.std::__debug::array<int, 12>::begin(), 6)â
/home/fdt/dev/gcc/install/include/c++/10.0.0/bits/stl_algobase.h:1482:7:
error: inline assembly is not a constant expression
 1482 |      __glibcxx_requires_partitioned_lower(__first, __last, __val);
     |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/fdt/dev/gcc/install/include/c++/10.0.0/bits/stl_algobase.h:1482:7:
note: only unevaluated inline assembly is allowed in a âconstexprâ
function in C++2a
This time it is done in no time. Of course you can see that the asm
trick to generate a non-constant condition is not so nice.
We just don't see the asm call parameter but showing
__glibcxx_requires_partitioned_lower is not so bad. For this reason the
tests in this patch are not checking for any failure message. We'll see
how to adapt when we have the necessary front end help to generate this
compilation error.
Of course I could have a nicer compilation error by directly calling
__glibcxx_requires_valid_range in the algo and stop doing it within
__glibcxx_requires_partitioned_lower. Do you want to expose all macros
this way ?
   * include/debug/formatter.h (__check_singular): Add C++11 constexpr
   qualification.
   * include/debug/helper_functions.h (__check_singular): Likewise. Skip
   check if constant evaluated.
   (__valid_range): Remove check skip if constant evaluated.
   * include/debug/macros.h [_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED]
   (_GLIBCXX_DEBUG_VERIFY_COND_AT): Define.
   * testsuite/25_algorithms/lower_bound/constexpr.cc (test): Add
checks on
   lower_bound results.
   * testsuite/25_algorithms/upper_bound/constexpr.cc (test): Likewise.
   * testsuite/25_algorithms/lower_bound/debug/
   constexpr_partitioned_neg.cc: New.
   * testsuite/25_algorithms/lower_bound/debug/
   constexpr_partitioned_pred_neg.cc: New.
   * testsuite/25_algorithms/lower_bound/debug/
   constexpr_valid_range_neg.cc: New.
   * testsuite/25_algorithms/lower_bound/debug/partitioned_neg.cc: New.
   * testsuite/25_algorithms/lower_bound/debug/partitioned_pred_neg.cc:
   New.
   * testsuite/25_algorithms/upper_bound/debug/
   constexpr_partitioned_neg.cc: New.
   * testsuite/25_algorithms/upper_bound/debug/
   constexpr_partitioned_pred_neg.cc: New.
   * testsuite/25_algorithms/upper_bound/debug/
   constexpr_valid_range_neg.cc: New.
   * testsuite/25_algorithms/upper_bound/debug/partitioned_neg.cc: New.
   * testsuite/25_algorithms/upper_bound/debug/partitioned_pred_neg.cc:
   New.
Tested under Linux x86_64 normal and debug modes.
Ok to commit ?
Is there any request done to get the necessary front end help ? Ideally
a builtin to generate the error at a given source/file line for a given
function would be perfect cause we have all those info.
François
-------------- next part --------------
A non-text attachment was scrubbed...
Name: debug_constexpr.patch
Type: text/x-patch
Size: 21235 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20191202/67c6fe42/attachment.bin>
More information about the Libstdc++
mailing list