From 18770ece5391e0c6dedf2ee698bd19e44c0748c8 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sun, 15 Nov 2015 11:13:29 +0100 Subject: [PATCH] macros: avoid signed overflow in nm_utils_is_power_of_two() If __x is signed and its value is the minimum allowed for the type, (__x - 1) causes a signed overflow, which has an undefined behavior. Compiling with -fsanitize=undefined produces the warnings: test-general.c:4499:619: runtime error: signed integer overflow: -2147483648 - 1 cannot be represented in type 'int' test-general.c:4506:681: runtime error: signed integer overflow: -2147483648 - 1 cannot be represented in type 'TEST_IS_POWER_OF_TWP_ENUM_SIGNED' test-general.c:4501:619: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int' test-general.c:4509:691: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'TEST_IS_POWER_OF_TWP_ENUM_UNSIGNED_64' Change the order of expressions to avoid this. Fixes: 0a3c1f57741677e21ec9efb9c67bfac81c31d208 (cherry picked from commit bc9d034775442127a0cfbb2d5c8cc707e699239d) --- include/nm-macros-internal.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/nm-macros-internal.h b/include/nm-macros-internal.h index 31e583bd81..ee94196488 100644 --- a/include/nm-macros-internal.h +++ b/include/nm-macros-internal.h @@ -277,12 +277,12 @@ nm_clear_g_signal_handler (gpointer self, guint *id) #define nm_utils_is_power_of_two(x) ({ \ const typeof(x) __x = (x); \ \ - ((__x & (__x - 1)) == 0) && \ - /* Check if the value is negative. In that case, return FALSE. - * The first expression is a compile time constant, depending on whether - * the type is signed. The second expression is a clumsy way for (__x >= 0), - * which causes a compiler warning for unsigned types. */ \ - ( ( ((typeof(__x)) -1) > ((typeof(__x)) 0) ) || (__x > 0) || (__x == 0) ); \ + /* Check if the value is negative. In that case, return FALSE. + * The first expression is a compile time constant, depending on whether + * the type is signed. The second expression is a clumsy way for (__x >= 0), + * which causes a compiler warning for unsigned types. */ \ + ( ( ((typeof(__x)) -1) > ((typeof(__x)) 0) ) || (__x > 0) || (__x == 0) ) \ + && ((__x & (__x - 1)) == 0); \ }) /*****************************************************************************/