From: Willy Tarreau Date: Tue, 11 Aug 2026 13:14:31 +0000 (+0200) Subject: MINOR: compiler: add a function attribute to disable tail calls X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9752f802b3869c96446f7e84e43d89360695c0f8;p=thirdparty%2Fhaproxy.git MINOR: compiler: add a function attribute to disable tail calls In some cases we want a tail call to be turned into a jump, which is sometimes referred to as "tail call elimination". Gcc and clang have options for this, so let's add an attribute "eliminate_tail_calls" that works with both. --- diff --git a/include/haproxy/compiler.h b/include/haproxy/compiler.h index b74e636bb..72792476c 100644 --- a/include/haproxy/compiler.h +++ b/include/haproxy/compiler.h @@ -123,6 +123,20 @@ # define __fallthrough do { } while (0) #endif +/* tail-call elimination (turn the final call of a function into a jump). This + * applies to the calling function. Clang doesn't support -f type optimizations + * but has a dedicated attribute that we can use. Modern versions have a + * "musttail" attribute at the statement level (per-return), but that's harder + * to turn into something portable. + */ +#if defined(__clang__) && __has_attribute(disable_tail_calls) +# define eliminate_tail_calls __attribute__((disable_tail_calls)) +#elif !defined(__clang__) && __has_attribute(optimize) +# define eliminate_tail_calls __attribute__((optimize("optimize-sibling-calls"))) +#else +# define eliminate_tail_calls +#endif + #if !defined(__GNUC__) /* Some versions of glibc irresponsibly redefine __attribute__() to empty for * non-gcc compilers, and as such, silently break all constructors with other