https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104633
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Richard Biener from comment #2) > The following is a valid use of extern inline I think > > extern int memcmp (const void * p, const void *q, unsigned long size); > > extern inline __attribute__((always_inline,gnu_inline)) > int memcmp (const void * p, const void *q, unsigned long size) > { > return memcmp (p, q, size); > } I think the above isn't actually valid, the compiler should still inline it infinitely. This is an infinite recursion. extern inline __attribute__((always_inline,gnu_inline)) int memcmp (const void * p, const void *q, unsigned long size) { return __builtin_memcmp (p, q, size); } is ok, __builtin_memcmp there doesn't mean it should use the user memcmp inline, it should handle it as the builtin and if it decides it wants to call, will call memcmp (but the out of line one). What glibc uses are either the call __builtin_whatever forms, or call an alias, say: extern int __memcmp_alias (const void *, const void *, unsigned long) __asm ("memcmp"); extern inline __attribute__((always_inline,gnu_inline)) int memcmp (const void * p, const void *q, unsigned long size) { return __memcmp_alias (p, q, size); } This one is also fine, it should call the external function, not the inline recursively. So, -Winfinite-recursion shouldn't warn about these 2 forms and should warn about the #c2 case.