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 (..)

Reply via email to