https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86590
--- Comment #12 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #11)
> (In reply to Richard Biener from comment #8)
> > So I've analyzed it more and it is because
> >
> > static _GLIBCXX17_CONSTEXPR size_t
> > length(const char_type* __s)
> > {
> > #if __cplusplus >= 201703L
> > if (__constant_string_p(__s))
> > return __gnu_cxx::char_traits<char_type>::length(__s);
> > #endif
> > return __builtin_strlen(__s);
> > }
> >
> > confuses us because of the stupid structure of __constant_string_p.
> >
> > Is this some odd requirement of O(1) length for constant strings? Why not
> > make it constexpr evaluated instead? Didn't we invent some special
> > __builtin_constant_p for this? __constexpr_p ()? Quoting
> > __constant_string_p:
> >
> > template<typename _CharT>
> > static _GLIBCXX_ALWAYS_INLINE constexpr bool
> > __constant_string_p(const _CharT* __s)
> > {
> > while (__builtin_constant_p(*__s) && *__s)
> > __s++;
> > return __builtin_constant_p(*__s);
> > }
>
> I think it is a poor man's workaround for the constexpr evaluation, until
> the FE can handle the memory/string builtins in constexpr evaluation.
> We need some helper routines for constexpr reading and storing a character
> to a certain pointer, and then basically open-code the needed builtins using
> those two helpers.
>
> Is the problem __constant_string_p implementation or the
> __gnu_cxx::char_traits<char_type>::length(__s); part? If only
> __constant_string_p, then it might be enough to handle constexpr evaluation
> of __builtin_strlen.
The __constant_string_p implementation (__builtin_constant_p in a loop).
> Is the problem that when optimizing we defer the __builtin_constant_p
> evaluation until fab? Perhaps my
> https://gcc.gnu.org/ml/gcc-patches/2018-03/msg00355.html patch would help
> here instead?
The first DOM pass evaluates it already but that's too late.
So C++ is basically lacking a feature to give two implementations, one
suitable for constexpr evaluation and one for non-constexpr contexts.
If we could overload on 'constexpr' then we could do
static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
{
#if __cplusplus >= 201703L
if (__constant_string_p(__s))
return __gnu_cxx::char_traits<char_type>::length(__s);
#endif
return __builtin_strlen(__s);
}
staic size_t
length(const char_type* __s)
{
return __builtin_strlen(__s);
}
I can very well imagine that people want to dispatch to fancy library
routines in non-constexpr context while provide the compiler with a
straight-forward constexpr implementation.
Maybe it's easier to retro-fit sth like that into the compiler?
if (__constexpr_evaluation_p)
{
fancy
}
else
return __builtin_strlen (..)