diff --git a/Makefile b/Makefile index 97e8385b66..79121c5a92 100644 --- a/Makefile +++ b/Makefile @@ -985,6 +985,7 @@ LIB_OBJS += compat/nonblock.o LIB_OBJS += compat/obstack.o LIB_OBJS += compat/terminal.o LIB_OBJS += compat/zlib-uncompress2.o +LIB_OBJS += compiler-tricks/not-constant.o LIB_OBJS += config.o LIB_OBJS += connect.o LIB_OBJS += connected.o diff --git a/compiler-tricks/not-constant.c b/compiler-tricks/not-constant.c new file mode 100644 index 0000000000..1da3ffc2f5 --- /dev/null +++ b/compiler-tricks/not-constant.c @@ -0,0 +1,2 @@ +#include +int false_but_the_compiler_does_not_know_it_; diff --git a/git-compat-util.h b/git-compat-util.h index e283c46c6f..c4f96dcc7b 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -1593,4 +1593,13 @@ static inline void *container_of_or_null_offset(void *ptr, size_t offset) ((uintptr_t)&(ptr)->member - (uintptr_t)(ptr)) #endif /* !__GNUC__ */ +/* + * Prevent an overly clever compiler from optimizing an expression + * out, triggering a false positive when building with the + * -Wunreachable-code option. false_but_the_compiler_does_not_know_it_ + * is defined in a compilation unit separate from where the macro is + * used, initialized to 0, and never modified. + */ +#define NOT_CONSTANT(expr) ((expr) || false_but_the_compiler_does_not_know_it_) +extern int false_but_the_compiler_does_not_know_it_; #endif diff --git a/meson.build b/meson.build index 0064eb64f5..f5c9dfa95b 100644 --- a/meson.build +++ b/meson.build @@ -249,6 +249,7 @@ libgit_sources = [ 'compat/obstack.c', 'compat/terminal.c', 'compat/zlib-uncompress2.c', + 'compiler-tricks/not-constant.c', 'config.c', 'connect.c', 'connected.c', diff --git a/run-command.c b/run-command.c index d527c46175..8833b23367 100644 --- a/run-command.c +++ b/run-command.c @@ -516,14 +516,12 @@ static void atfork_prepare(struct atfork_state *as) sigset_t all; /* - * Do not use the return value of sigfillset(). It is transparently 0 - * on some platforms, meaning a clever compiler may complain that - * the conditional body is dead code. Instead, check for error via - * errno, which outsmarts the compiler. + * POSIX says sigfillset() can fail, but an overly clever + * compiler can see through the header files and decide + * it cannot fail on a particular platform it is compiling for, + * triggering -Wunreachable-code false positive. */ - errno = 0; - sigfillset(&all); - if (errno) + if (NOT_CONSTANT(sigfillset(&all))) die_errno("sigfillset"); #ifdef NO_PTHREADS if (sigprocmask(SIG_SETMASK, &all, &as->old))