mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-04 20:46:11 +02:00
MINOR: compiler: add ASSUME_NONNULL() to tell the compiler a pointer is valid
At plenty of places we have ALREADY_CHECKED() or DISGUISE() on a pointer just to avoid "possibly null-deref" warnings. These ones have the side effect of weakening optimizations by passing through an assembly step. Using ASSUME_NONNULL() we can avoid that extra step. And when the __builtin_unreachable() builtin is not present, we fall back to the old method using assembly. The macro returns the input value so that it may be used both as a declarative way to claim non-nullity or directly inside an expression like DISGUISE().
This commit is contained in:
parent
2ce63b7b17
commit
63798088b3
@ -220,13 +220,19 @@
|
||||
* with compilers that support it, and we do not want to emit any static code
|
||||
* for other ones, so we use a construct that the compiler should easily be
|
||||
* able to optimize away. Clang also has __builtin_assume() since at least 3.x.
|
||||
* In addition, ASSUME_NONNULL() tells the compiler that the pointer argument
|
||||
* will never be null. If not supported, it will be disguised via an assembly
|
||||
* step.
|
||||
*/
|
||||
#if __has_builtin(__builtin_assume)
|
||||
# define ASSUME(expr) __builtin_assume(expr)
|
||||
# define ASSUME_NONNULL(p) ({ typeof(p) __p = (p); __builtin_assume(__p != NULL); (__p); })
|
||||
#elif __has_builtin(__builtin_unreachable)
|
||||
# define ASSUME(expr) do { if (!(expr)) __builtin_unreachable(); } while (0)
|
||||
# define ASSUME_NONNULL(p) ({ typeof(p) __p = (p); if (__p == NULL) __builtin_unreachable(); (__p); })
|
||||
#else
|
||||
# define ASSUME(expr) do { if (!(expr)) break; } while (0)
|
||||
# define ASSUME_NONNULL(p) ({ typeof(p) __p = (p); asm("" : "=rm"(__p) : "0"(__p)); __p; })
|
||||
#endif
|
||||
|
||||
/* This prevents the compiler from folding multiple identical code paths into a
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user