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

--- Comment #9 from Pedro Alves <palves at redhat dot com> ---
FWIW, I've tried to poke a bit more at this, to try to make it _not_ work, but
couldn't.  It seems to always do what we need.  These all work/compile too:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
constexpr int constexpr_strcmp(const char *s1, const char *s2)
{
  while (*s1 != '\0' && *s1 == *s2)
    {
      s1++;
      s2++;
    }

  if (*s1 < *s2)
    return -1;
  else if (*s1 > *s2)
    return 1;
  return 0;
}

constexpr int my_strcmp(const char *s1, const char *s2)
{
  if (__builtin_constant_p (s1[0])
      && __builtin_constant_p (s2[0]))
    return constexpr_strcmp (s1, s2);

  return strcmp (s1, s2);
}

constexpr bool str4()
{
  char s[4]= {};
  int i = 0;
  for (; i < 3; i++)
    s[i] = i + 1;
  return ce_char_traits<char>::length(s) == 3;
}

static_assert( str4() );

constexpr int foo (char x, char y)
{
  char a[10] = "abcde";
  a[2] = x;
  a[4] = y;
  return ce_char_traits<char>::length(a);
}

static_assert (foo ('1', '2') == 5);
static_assert (foo ('1', '\0') == 4);

bool runtime()
{
  char s[] = "str";
  s[0] = 'l';
  s[1] = '\0';
  return ce_char_traits<char>::length(s) == 1;
}

bool runtime2()
{
  char s[4]= {};
  int i = 0;
  for (; i < 3; i++)
    s[i] = i + 1;
  return ce_char_traits<char>::length(s) == 3;
}

bool runtime3()
{
  constexpr char s[] = "str";
  return ce_char_traits<char>::length(s) == 1;
}

int main ()
{
  assert (runtime ());
  assert (runtime2 ());
  assert (runtime3 ());
}

static_assert (my_strcmp("hello", "hello") == 0);
static_assert (my_strcmp("hello", "hell2") > 0);
static_assert (my_strcmp("hell2", "hello") < 0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

And I confirmed that "constexpr_strlen" / "constexpr_strcmp" are NOT emitted /
called as runtime functions, both at -O0 and -O2.

Reply via email to