]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
c.h: really avoid undefined behavior in SINT_MAX
authorThomas Weißschuh <thomas@t-8ch.de>
Sat, 14 Jan 2023 22:16:28 +0000 (22:16 +0000)
committerThomas Weißschuh <thomas@t-8ch.de>
Sat, 14 Jan 2023 22:24:39 +0000 (22:24 +0000)
The previous fix in #2013 still invoked undefined behavior by shifting
into the sign-bit.

Now we have a correct, albeit unwieldy solution that avoids undefined
behavior.
Instead of bit fiddling it uses plain addition and substraction.

We are looking for (in LaTeX notation):
  2^(n - 1) - 1
= 2 * 2^(n - 2) - 1
= 2^(n - 2) + 2^(n - 2) - 1
= 2^(n - 2) - 1 + 2^(n - 2)

include/c.h

index eab6ff5054db4a6b6fa8459d423a4ae0e7d4a426..0f25fb009da875a404e446ed47c4b144d612dc07 100644 (file)
@@ -526,6 +526,6 @@ static inline void print_features(const char **features, const char *prefix)
 # define MAP_ANONYMOUS  (MAP_ANON)
 #endif
 
-#define SINT_MAX(t) ((t)((~(t) 0) ^ (t) 1 << (sizeof(t) * 8 - 1)))
+#define SINT_MAX(t) ((t) (1 << (sizeof(t) * 8 - 2)) - 1 + ((t) 1 << (sizeof(t) * 8 - 2)))
 
 #endif /* UTIL_LINUX_C_H */