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

            Bug ID: 103858
           Summary: [12 Regression] strlen() implementation is optimized
                    into a call to strlen() at -O2, causing infinite
                    recursion
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dani at danielbertalan dot dev
  Target Milestone: ---

Compiler Explorer link: https://godbolt.org/z/h419G55P4

The following function is folded into a call to strlen() by gcc 12 (commit
61e53698a08dc1d9a54d785218af687a6751c1b3) at -O2, unless -fno-builtin-strlen is
specified. This function is taken from a (naive) libc implementation, where
this is the only definition of strlen(), so it ends up calling itself
recursively, overflowing the stack.

#include <stddef.h>

size_t strlen(const char* str)
{
    size_t len = 0;
    while (*(str++))
        ++len;
    return len;
}

x86_64 assembly output:
strlen:
        cmp     BYTE PTR [rdi], 0
        je      .L3
        lea     rax, [rdi+1]
        sub     rsp, 8
        mov     rdi, rax
        call    strlen
        add     rsp, 8
        add     rax, 1
        ret
.L3:
        xor     eax, eax
        ret

My workaround is to compile our libc with -ffreestanding/-fno-builtin, but I'd
like to avoid that, as it might prevent other (valid) optimizations from being
performed on our code.

Reply via email to