https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89604
Bug ID: 89604 Summary: Type conversion from signed char to a wider integer generates wrong assembly for ARM, Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: driver Assignee: unassigned at gcc dot gnu.org Reporter: christalization at gmail dot com Target Milestone: --- Created attachment 45902 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45902&action=edit Preprocessed file So I've stumbled upon this bug when compiling a project on the Raspberry pi. I created a barebone test project to verify that nothing else was causing it, and indeed, I got the same result. What happens is that when you're converting a signed char type to a signed integer, the conversion fails to move the sign bit, instead it just extends the bits like it would with an unsigned conversion. I've verified that this does not happen on x86/64 builds so it appears to be specific for ARM builds. Compiling exactly the same piece of code on Windows yields the correct result: int main() { char c = -40; double s = c; printf("%f", s); return 0; } Windows: -40 Raspbian: 226 226 is what you get when interpreting the bits of the char as unsigned. I got around the problem for now by explicitly moving the sign bit as such: ((int)c & ~0x80) | ~0x7FFFFFFF Here is the compiler output along with the commandline arguments: g++ -v -save-temps test.cpp -o test Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/6/lto-wrapper Target: arm-linux-gnueabihf Configured with: ../src/configure -v --with-pkgversion='Raspbian 6.3.0-18+rpi1+deb9u1' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --program-prefix=arm-linux-gnueabihf- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf Thread model: posix gcc version 6.3.0 20170516 (Raspbian 6.3.0-18+rpi1+deb9u1) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-shared-libgcc' '-march=armv6' '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu' /usr/lib/gcc/arm-linux-gnueabihf/6/cc1plus -E -quiet -v -imultilib . -imultiarch arm-linux-gnueabihf -D_GNU_SOURCE test.cpp -march=armv6 -mfloat-abi=hard -mfpu=vfp -mtls-dialect=gnu -fpch-preprocess -o test.ii ignoring duplicate directory "/usr/include/arm-linux-gnueabihf/c++/6" ignoring nonexistent directory "/usr/local/include/arm-linux-gnueabihf" ignoring nonexistent directory "/usr/lib/gcc/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/include" #include "..." search starts here: #include <...> search starts here: /usr/include/c++/6 /usr/include/arm-linux-gnueabihf/c++/6 /usr/include/c++/6/backward /usr/lib/gcc/arm-linux-gnueabihf/6/include /usr/local/include /usr/lib/gcc/arm-linux-gnueabihf/6/include-fixed /usr/include/arm-linux-gnueabihf /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-shared-libgcc' '-march=armv6' '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu' /usr/lib/gcc/arm-linux-gnueabihf/6/cc1plus -fpreprocessed test.ii -quiet -dumpbase test.cpp -march=armv6 -mfloat-abi=hard -mfpu=vfp -mtls-dialect=gnu -auxbase test -version -o test.s GNU C++14 (Raspbian 6.3.0-18+rpi1+deb9u1) version 6.3.0 20170516 (arm-linux-gnueabihf) compiled by GNU C version 6.3.0 20170516, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version 0.15 GGC heuristics: --param ggc-min-expand=93 --param ggc-min-heapsize=118680 GNU C++14 (Raspbian 6.3.0-18+rpi1+deb9u1) version 6.3.0 20170516 (arm-linux-gnueabihf) compiled by GNU C version 6.3.0 20170516, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version 0.15 GGC heuristics: --param ggc-min-expand=93 --param ggc-min-heapsize=118680 Compiler executable checksum: 79dca666fccaa96025c9107a8b3f60f3 COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-shared-libgcc' '-march=armv6' '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu' as -v -march=armv6 -mfloat-abi=hard -mfpu=vfp -meabi=5 -o test.o test.s GNU assembler version 2.28 (arm-linux-gnueabihf) using BFD version (GNU Binutils for Raspbian) 2.28 COMPILER_PATH=/usr/lib/gcc/arm-linux-gnueabihf/6/:/usr/lib/gcc/arm-linux-gnueabihf/6/:/usr/lib/gcc/arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/6/:/usr/lib/gcc/arm-linux-gnueabihf/ LIBRARY_PATH=/usr/lib/gcc/arm-linux-gnueabihf/6/:/usr/lib/gcc/arm-linux-gnueabihf/6/../../../arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/6/../../../:/lib/arm-linux-gnueabihf/:/lib/:/usr/lib/arm-linux-gnueabihf/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-shared-libgcc' '-march=armv6' '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu' /usr/lib/gcc/arm-linux-gnueabihf/6/collect2 -plugin /usr/lib/gcc/arm-linux-gnueabihf/6/liblto_plugin.so -plugin-opt=/usr/lib/gcc/arm-linux-gnueabihf/6/lto-wrapper -plugin-opt=-fresolution=test.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=/ --build-id --eh-frame-hdr -dynamic-linker /lib/ld-linux-armhf.so.3 -X --hash-style=gnu -m armelf_linux_eabi -o test /usr/lib/gcc/arm-linux-gnueabihf/6/../../../arm-linux-gnueabihf/crt1.o /usr/lib/gcc/arm-linux-gnueabihf/6/../../../arm-linux-gnueabihf/crti.o /usr/lib/gcc/arm-linux-gnueabihf/6/crtbegin.o -L/usr/lib/gcc/arm-linux-gnueabihf/6 -L/usr/lib/gcc/arm-linux-gnueabihf/6/../../../arm-linux-gnueabihf -L/usr/lib/gcc/arm-linux-gnueabihf/6/../../.. -L/lib/arm-linux-gnueabihf -L/usr/lib/arm-linux-gnueabihf test.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/arm-linux-gnueabihf/6/crtend.o /usr/lib/gcc/arm-linux-gnueabihf/6/../../../arm-linux-gnueabihf/crtn.o COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-shared-libgcc' '-march=armv6' '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu'