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.

Reply via email to