https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78042
Bug ID: 78042 Summary: g++ does not select the corresponding overloads of abs() for long and long long Product: gcc Version: 6.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: dominik.muth at gmx dot de Target Milestone: --- // begin example file abs.cxx #include <cstdlib> #include <climits> #include <cstdio> int main() { int myint = INT_MAX; long mylong = LONG_MAX; long long myllong = LLONG_MAX; printf("%lu\n", sizeof(myint)); printf("%lu\n", sizeof(mylong)); printf("%lu\n", sizeof(myllong)); printf("%d\n", myint); printf("%ld\n", mylong); printf("%lld\n", myllong); printf("%d\n", -abs(myint)); printf("%ld\n", -abs(mylong)); printf("%lld\n", -abs(myllong)); printf("%d\n", -abs(myint)); printf("%ld\n", -labs(mylong)); printf("%lld\n", -llabs(myllong)); } // end example file abs.cxx $ g++6 -Wall -Wextra -Wconversion -std=c++11 -o abs abs.cxx abs.cxx: In function 'int main()': abs.cxx:16:29: warning: conversion to 'int' from 'long int' may alter its value [-Wconversion] printf("%ld\n", -abs(mylong)); ^ abs.cxx:16:30: warning: format '%ld' expects argument of type 'long int', but argument 2 has type 'int' [-Wformat=] printf("%ld\n", -abs(mylong)); ^ abs.cxx:17:31: warning: conversion to 'int' from 'long long int' may alter its value [-Wconversion] printf("%lld\n", -abs(myllong)); ^ abs.cxx:17:32: warning: format '%lld' expects argument of type 'long long int', but argument 2 has type 'int' [-Wformat=] printf("%lld\n", -abs(myllong)); ^ $ ./abs 4 8 8 2147483647 9223372036854775807 9223372036854775807 -2147483647 4294967295 4294967295 -2147483647 -9223372036854775807 -9223372036854775807 Obviously int abs(int) is called here all the time. However I expect the corresponding overloads to be selected according to http://en.cppreference.com/w/cpp/numeric/math/abs. $ g++6 -v Using built-in specs. COLLECT_GCC=g++6 COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc6/gcc/x86_64-portbld-freebsd11.0/6.2.0/lto-wrapper Target: x86_64-portbld-freebsd11.0 Configured with: /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.2.0/configure --with-build-config=bootstrap-debug --disable-nls --enable-gnu-indirect-function --libdir=/usr/local/lib/gcc6 --libexecdir=/usr/local/libexec/gcc6 --program-suffix=6 --with-as=/usr/local/bin/as --with-gmp=/usr/local --with-gxx-include-dir=/usr/local/lib/gcc6/include/c++/ --with-ld=/usr/local/bin/ld --with-pkgversion='FreeBSD Ports Collection' --with-system-zlib --with-ecj-jar=/usr/local/share/java/ecj-4.5.jar --enable-languages=c,c++,objc,fortran,java --prefix=/usr/local --localstatedir=/var --mandir=/usr/local/man --infodir=/usr/local/info/gcc6 --build=x86_64-portbld-freebsd11.0 Thread model: posix gcc version 6.2.0 (FreeBSD Ports Collection) Note 1: The FreeBSD 11.0 system compiler behaves as expected: $ clang++ -Wall -Wextra -Wconversion -std=c++11 -o abs abs.cxx $ ./abs 4 8 8 2147483647 9223372036854775807 9223372036854775807 -2147483647 -9223372036854775807 -9223372036854775807 -2147483647 -9223372036854775807 -9223372036854775807 Note 2: arm-linux-gnueabihf-g++ version 4.8.4 (Ubuntu/Linaro 4.8.4-2ubuntu1~14.04.3) also FAILS to select the long long abs(long long) overload. Note 3: armv7l-unknown-linux-gnueabihf-g++ version 6.2.1 20160830 (GCC) also FAILS to select the long long abs(long long) overload. Note 4: aarch64--linux-android clang++ version 3.9.0 (tags/RELEASE_390/final) also FAILS to select the long abs(long) and long long abs(long long) overloads.