aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--compiler-tricks/not-constant.c2
-rw-r--r--git-compat-util.h9
-rw-r--r--meson.build1
-rw-r--r--run-command.c12
5 files changed, 18 insertions, 7 deletions
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 <git-compat-util.h>
+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))