]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commit
include/linux/kernel.h: change abs() macro so it uses consistent return type
authorMichal Nazarewicz <mina86@mina86.com>
Sat, 16 Jan 2016 00:57:58 +0000 (16:57 -0800)
committerSeth Forshee <seth.forshee@canonical.com>
Thu, 20 Oct 2016 13:05:50 +0000 (08:05 -0500)
commit3e4b3c3a4f2f849c705add69375970e5621f27b7
tree0598b9b95ff4b3b461cdce4f9770260148025534
parente60506b27f7b2f994c9163555e6cd97e2e46a3c9
include/linux/kernel.h: change abs() macro so it uses consistent return type

BugLink: http://bugs.launchpad.net/bugs/1629386
commit 8f57e4d930d48217268315898212518d4d3e0773 upstream.

Rewrite abs() so that its return type does not depend on the
architecture and no unexpected type conversion happen inside of it.  The
only conversion is from unsigned to signed type.  char is left as a
return type but treated as a signed type regradless of it's actual
signedness.

With the old version, int arguments were promoted to long and depending
on architecture a long argument might result in s64 or long return type
(which may or may not be the same).

This came after some back and forth with Nicolas.  The current macro has
different return type (for the same input type) depending on
architecture which might be midly iritating.

An alternative version would promote to int like so:

#define abs(x) __abs_choose_expr(x, long long, \
__abs_choose_expr(x, long, \
__builtin_choose_expr( \
sizeof(x) <= sizeof(int), \
({ int __x = (x); __x<0?-__x:__x; }), \
((void)0))))

I have no preference but imagine Linus might.  :] Nicolas argument against
is that promoting to int causes iconsistent behaviour:

int main(void) {
unsigned short a = 0, b = 1, c = a - b;
unsigned short d = abs(a - b);
unsigned short e = abs(c);
printf("%u %u\n", d, e);  // prints: 1 65535
}

Then again, no sane person expects consistent behaviour from C integer
arithmetic.  ;)

Note:

  __builtin_types_compatible_p(unsigned char, char) is always false, and
  __builtin_types_compatible_p(signed char, char) is also always false.

Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Reviewed-by: Nicolas Pitre <nico@linaro.org>
Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Cc: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
drivers/iio/industrialio-core.c
drivers/net/wireless/iwlwifi/dvm/calib.c
include/linux/kernel.h