https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Missed optimization for     |[10/11/12/13 Regression]
                   |static const                |Missed optimization for
                   |std::string_view(const      |static const
                   |char*)                      |std::string_view(const
                   |                            |char*)

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
And if the variable is like this it does optimize it:

  static constexpr string_view foo("bar");

Because then we take the constant evaluation path and calculate the length by
hand.

The problem seems to be that GCC considers the
__builtin_is_constant_evaluated() branch to be reachable for non-constexpr and
so doesn't inline as aggressively. If we have:

struct traits
{
  static constexpr unsigned long length(const char* s)
  {
#ifndef FIX
    if (__builtin_is_constant_evaluated())
    {
      unsigned long n = 0;
      while (*s++)
        ++n;
      return n;
    }
#endif
    return __builtin_strlen(s);
  }
};

struct string_view
{
  constexpr
  string_view(const char* s) : str(s), len(traits::length(s)) { }

  unsigned long size() const { return len; }

  const char* str;
  unsigned long len;
};

int main()
{
  static const string_view foo("bar");
  return foo.size();
}

Then with -DFIX we optimize correctly, but without -DFIX we don't. That block
of code should make no difference to inlining decisions, because at runtime it
is always dead code.

Reply via email to