llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.29k stars 11.68k forks source link

Clang has missing/different macros than gcc - causing compatibility issues #24103

Open 56d0a558-f6b8-4eef-a80e-c55ffae20971 opened 9 years ago

56d0a558-f6b8-4eef-a80e-c55ffae20971 commented 9 years ago
Bugzilla Link 23729
Version 3.6
OS Windows NT
Attachments gcc defines, Clang defines
CC @asl,@DougGregor

Extended Description

Hello,

I tried compiling out project at work, which is a realtime firmware for arm. Ideally clang would be just able to generate correct code, but it misbehaves on a few accounts. I consider some of these macros pretty much defacto-standard, as eg. newlib is using and depending on these.

__SOFTFP__ is not set, implicating hardware floating point support __USES_INITFINI__ is not set, resulting in initialisation functions not being called

And several macros are quite different: __ARM_SIZEOF_WCHAR_T 32 vs. 4 __FLT_* sizes are different, probably just nonrelevant extra precision __INTPTR_TYPE__,__UINT32_TYPE__,__WINT_TYPE__ etc. int vs. long int (kills binary compatibility)

I used these 2 commands (clang needed the system directories defined, din`t pick them up correctly)

LC_ALL=C /opt/toolchain/bin/arm-none-eabi-g++ -fmessage-length=0 -DNVALGRIND -Wignored-qualifiers -mcpu=arm926ej-s -fstrict-aliasing -ftls-model=local-exec -fno-threadsafe-statics -ffunction-sections -fdata-sections -mpoke-function-name -DPOKE_FUNCTION_NAME -Wpointer-arith -Wno-psabi -Wsign-compare -fstrict-overflow -Wnoexcept -std=gnu++11 -Wall -O2 -g2  \
           \
            -E -P -dD -x c++ -v - < /dev/null 2>&1

LC_ALL=C /opt/toolchain/bin/arm-none-eabi-clang++ -fmessage-length=0 -DNVALGRIND -Wignored-qualifiers -mcpu=arm926ej-s -fstrict-aliasing -ftls-model=local-exec -fno-threadsafe-statics -ffunction-sections -fdata-sections -fshort-enums -fshort-enums -Wpointer-arith -Wsign-compare -Wimplicit-fallthrough -std=gnu++11 -Wall -O2 -g3  \
           \
        -nostdinc -I/opt/toolchain-4.8/lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/include/c++/4.8.4 -I/opt/toolchain-4.8/lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/include/c++/4.8.4/arm-none-eabi/armv5te -I/opt/toolchain-4.8/lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/include/c++/4.8.4/backward -I/opt/toolchain-4.8/lib/gcc/arm-none-eabi/4.8.4/include -I/opt/toolchain-4.8/lib/gcc/arm-none-eabi/4.8.4/include-fixed -I/opt/toolchain-4.8/lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/include 
        \ 
        -E -P -dD -x c++ -v - < /dev/null 2>&1
56d0a558-f6b8-4eef-a80e-c55ffae20971 commented 9 years ago

I dont see why this would help, particularly as __SOFTFP__ and __USES_INITFINI__ is missing from clang. These are rather common for embedded toolchains, eg. newlib and ARM`s CMSIS depend on these being set correctly.

If there are some flags missing for running clang as arm cross-compiler let me know, I am using a symlink in the gcc-toolchain so clang can pick up the correct tools. Other methods never worked for me

Using built-in specs.

COLLECT_GCC=/opt/toolchain/bin/arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/opt/toolchain-4.8/libexec/gcc/arm-none-eabi/4.8.4/lto-wrapper
Target: arm-none-eabi
Configured with: /home/build/toolchain-arm-none-eabi-4.8-4.8.4/gcc-4.8.4/configure --prefix=/opt/toolchain-4.8 --target=arm-none-eabi --enable-languages=c,c++ --disable-nls --enable-tls --enable-lto --disable-shared --disable-libstdcxx-verbose --disable-libstdcxx-pch --disable-install-libiberty --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp --with-newlib --enable-multilib --with-multilib-list=armv5te,armv7e-m --with-host-libstdcxx=-Wl,-Bstatic,/opt/toolchain-4.8/lib/gcc/i486-linux-gnu/4.8.4/../../../libstdc++.a,/opt/toolchain-4.8/lib/gcc/i486-linux-gnu/4.8.4/../../../libsupc++.a,-Bdynamic --with-cloog --with-isl --without-zlib --with-system-zlib --with-pkgversion='H 4.8.4-4' --with-build-time-tools=/tmp/build/tmp/opt/toolchain-4.8/bin
Thread model: single
gcc version 4.8.4 (H 4.8.4-4)
asl commented 9 years ago

How the gcc was compiled? Please post gcc -v here.

Ferdi265 commented 1 year ago

I can reproduce this with modern compiler versions:

OS: Linux (Arch Linux) GCC: arm-none-eabi-gcc 12.2.0 (from Arch repos) Clang: clang 14.0.6 (from Arch repos)

$ touch empty.c
$ arm-none-eabi-gcc -E -dM empty.c | grep __INT32_TYPE__
#define __INT32_TYPE__ long int
$ clang --target=arm-none-eabi -E -dM empty.c | grep __INT32_TYPE__
#define __INT32_TYPE__ int

I have traced this back to clang/lib/Frontend/InitPreprocessor.cpp:1094-1104. In GCC this is selected by the machinery in gcc/config/newlib-stdint.h:38 since newlib seems to prefer uint32_t to be long int.

Clang always defines the exact width integer types to the first fundamental type it finds that has a specific size. i.e, if both int and long int are 32 bits, __INT32_TYPE__ will be defined as int. This seems a sensible and logical approach to me.

GCC seems to use platform specific or historic conventions when deciding what type to use for exact width integer types such as __INT32_TYPE__ .

It seems to me that the only way for Clang to become compatible with GCC in this case is to add a way to change the way Clang decides to select its exact width integer definitions, maybe with some kind of "GCC compatibility" switch or any other way to override this decision.

GCC -v output:

Configured with: /build/arm-none-eabi-gcc/src/gcc-12.2.0/configure --target=arm-none-eabi --prefix=/usr --with-sysroot=/usr/arm-none-eabi --with-native-system-header-dir=/include --libexecdir=/usr/lib --enable-languages=c,c++ --enable-plugins --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-system-zlib --with-newlib --with-headers=/usr/arm-none-eabi/include --with-python-dir=share/gcc-arm-none-eabi --with-gmp --with-mpfr --with-mpc --with-isl --with-libelf --enable-gnu-indirect-function --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='Arch Repository' --with-bugurl=https://bugs.archlinux.org/ --with-multilib-list=rmprofile