llvm / llvm-project

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

Release overlay GCC build fails with "aliased to external symbol" #60481

Open liam-clink opened 1 year ago

liam-clink commented 1 year ago

CMake invocation: (C/C++ compilers set to GCC/G++)

cmake -S ../llvm -B . -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$HOME/llvm-15_temp -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_ENABLE_PROJECTS="all"
[1/7688] Building CXX object projects/libc/src/stdlib/CMakeFiles/libc.src.stdlib.bsearch.dir/bsearch.cpp.o
FAILED: projects/libc/src/stdlib/CMakeFiles/libc.src.stdlib.bsearch.dir/bsearch.cpp.o 
/home/liam/gcc-12.2.0/bin/g++ -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/liam/Documents/GitHub/llvm-project/build/projects/libc/src/stdlib -I/home/liam/Documents/GitHub/llvm-project/libc/src/stdlib -I/home/liam/Documents/GitHub/llvm-project/build/include -I/home/liam/Documents/GitHub/llvm-project/llvm/include -I/home/liam/Documents/GitHub/llvm-project/build/projects/libc/include -I/home/liam/Documents/GitHub/llvm-project/libc -I/home/liam/Documents/GitHub/llvm-project/build/projects/libc -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wmisleading-indentation -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -fpie -ffreestanding -fno-builtin -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti -DLLVM_LIBC_PUBLIC_PACKAGING -std=c++17 -MD -MT projects/libc/src/stdlib/CMakeFiles/libc.src.stdlib.bsearch.dir/bsearch.cpp.o -MF projects/libc/src/stdlib/CMakeFiles/libc.src.stdlib.bsearch.dir/bsearch.cpp.o.d -o projects/libc/src/stdlib/CMakeFiles/libc.src.stdlib.bsearch.dir/bsearch.cpp.o -c /home/liam/Documents/GitHub/llvm-project/libc/src/stdlib/bsearch.cpp
In file included from /home/liam/Documents/GitHub/llvm-project/libc/src/stdlib/bsearch.cpp:10:
/home/liam/Documents/GitHub/llvm-project/libc/src/stdlib/bsearch.cpp:16:28: error: 'void* __llvm_libc::bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*))' aliased to external symbol 'bsearch'
   16 | LLVM_LIBC_FUNCTION(void *, bsearch,
      |                            ^~~~~~~
/home/liam/Documents/GitHub/llvm-project/libc/src/__support/common.h:33:31: note: in definition of macro 'LLVM_LIBC_FUNCTION'
   33 |   decltype(__llvm_libc::name) name [[gnu::alias(#name)]];                      \
      |                               ^~~~
/home/liam/Documents/GitHub/llvm-project/libc/src/stdlib/bsearch.cpp:16:28: warning: 'void* __llvm_libc::bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*))' specifies less restrictive attribute than its target 'void* bsearch(const void*, const void*, size_t, size_t, __compar_fn_t)': 'nonnull' [-Wmissing-attributes]
   16 | LLVM_LIBC_FUNCTION(void *, bsearch,
      |                            ^~~~~~~
/home/liam/Documents/GitHub/llvm-project/libc/src/__support/common.h:33:31: note: in definition of macro 'LLVM_LIBC_FUNCTION'
   33 |   decltype(__llvm_libc::name) name [[gnu::alias(#name)]];                      \
      |                               ^~~~
In file included from /usr/include/stdlib.h:833,
                 from /home/liam/gcc-12.2.0/include/c++/12.2.0/cstdlib:75,
                 from /home/liam/gcc-12.2.0/include/c++/12.2.0/stdlib.h:36,
                 from /home/liam/Documents/GitHub/llvm-project/libc/src/stdlib/bsearch.h:9,
                 from /home/liam/Documents/GitHub/llvm-project/libc/src/stdlib/bsearch.cpp:9:
/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h:20:1: note: 'void* __llvm_libc::bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*))' target declared here
   20 | bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size,
      | ^~~~~~~
llvmbot commented 1 year ago

@llvm/issue-subscribers-libc

DavidSpickett commented 1 year ago

Just been looking at this myself, this only happens for overlay mode. It's the overlaying mechanism that leads to this error I think.

Reading the gcc docs: https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html

"It is an error if `__f' is not defined in the same translation unit."

clang does not document it so I don't know if clang allows this on purpose or not.

I also found https://stackoverflow.com/questions/7649979/gcc-alias-to-function-outside-of-translation-unit-aka-is-this-even-the-right-t asking about this with another project. No obvious solution from C, but some ideas with linker scripts and such.

I should note that the libc project only officially supports clang at this time. The gcc buildbots they have build the full mode so they won't have hit this.

sivachandra commented 1 year ago

Interestingly, this seems to happen only for release mode builds with -DCMAKE_BUILD_TYPE=Release. I am not able to reproduce this for debug builds.

sivachandra commented 1 year ago

Ah, looks like bsearch gets defined as an extern inline function in glibc's stdlib.h under release build and so the alias here is conflicting with that extern inline function.

mikhailramalho commented 1 year ago

I also started to get the same error for readlinkat in RelWithDebInfo mode:

In file included from /home/mgadelha/tools/llvm-project/libc/src/__support/OSUtil/linux/syscall.h:12,
                 from /home/mgadelha/tools/llvm-project/libc/src/__support/OSUtil/syscall.h:13,
                 from /home/mgadelha/tools/llvm-project/libc/src/unistd/linux/readlinkat.cpp:11:
/home/mgadelha/tools/llvm-project/libc/src/unistd/linux/readlinkat.cpp:20:29: error: ‘ssize_t __llvm_libc::readlinkat(int, const char*, char*, size_t)’ aliased to external symbol ‘readlinkat’
   20 | LLVM_LIBC_FUNCTION(ssize_t, readlinkat,
      |                             ^~~~~~~~~~
/home/mgadelha/tools/llvm-project/libc/src/__support/common.h:30:31: note: in definition of macro ‘LLVM_LIBC_FUNCTION’
   30 |   decltype(__llvm_libc::name) name [[gnu::alias(#name)]];                      \
      |                               ^~~~
/home/mgadelha/tools/llvm-project/libc/src/unistd/linux/readlinkat.cpp:20:29: warning: ‘ssize_t __llvm_libc::readlinkat(int, const char*, char*, size_t)’ specifies less restrictive attributes than its target ‘ssize_t readlinkat(int, const char*, char*, size_t)’: ‘leaf’, ‘nonnull’, ‘nothrow’ [-Wmissing-attributes]
   20 | LLVM_LIBC_FUNCTION(ssize_t, readlinkat,
      |                             ^~~~~~~~~~
/home/mgadelha/tools/llvm-project/libc/src/__support/common.h:30:31: note: in definition of macro ‘LLVM_LIBC_FUNCTION’
   30 |   decltype(__llvm_libc::name) name [[gnu::alias(#name)]];                      \
      |                               ^~~~
In file included from /usr/include/features.h:486,
                 from /usr/include/unistd.h:25,
                 from /home/mgadelha/tools/llvm-project/libc/src/unistd/readlinkat.h:12,
                 from /home/mgadelha/tools/llvm-project/libc/src/unistd/linux/readlinkat.cpp:9:
/usr/include/x86_64-linux-gnu/bits/unistd.h:144:1: note: ‘ssize_t __llvm_libc::readlinkat(int, const char*, char*, size_t)’ target declared here
  144 | __NTH (readlinkat (int __fd, const char *__restrict __path,
      | ^~~~~

It builds fine in Debug mode.

erkinalp commented 1 year ago

Suggested re-title: "Standard library re-aliasing issues in overlay mode builds only in the release configuration"

nickdesaulniers commented 6 months ago

Looks like gcc will error for aliases created with the alias attributes, but not asm aliases.

https://godbolt.org/z/xsxrTavnx

nickdesaulniers commented 6 months ago

Simpler reproducer:

$ cd <new build dir>
$ cmake ../llvm -DLLVM_ENABLE_PROJECTS="libc" -DCMAKE_BUILD_TYPE=Release -G Ninja
$ ninja libc.src.stdlib.bsearch
nickdesaulniers commented 6 months ago

Looks like gcc will error for aliases created with the alias attributes, but not asm aliases.

https://godbolt.org/z/xsxrTavnx

So clang can diagnose this, but seemingly only at -O0. I hit asserts in LLVM when I try to build that test case with optimizations enabled though.

I have a fix for the immediate issue of bsearch, but it won't close out this issue because we hit similar but slightly trickier to fix cases for 3 other functions (wctob, vprintf, and atof).

lntue commented 1 month ago

Turns out the problems are from extra extern inline definitions of libc functions in the system headers when building with gcc. Those inclusions are guarded by __USE_FORTIFY_LEVEL and __USE_EXTERN_INLINES, which are in turn guarded by: _FORTIFY_SOURCE and __NO_INLINE__ / __OPTIMIZE__.

A solution for this issue is:

ifndef __NO_INLINE__

define __NO_INLINE__ 1

define LIBC_SET_NO_INLINE

endif

include

ifdef LIBC_OLD_FORTIFY_SOURCE

define _FORTIFY_SOURCE LIBC_OLD_FORTIFY_SOURCE

undef LIBC_OLD_FORTIFY_SOURCE

endif

ifdef LIBC_SET_NO_INLINE

undef __NO_INLINE__

undef LIBC_SET_NO_INLINE

endif


- List of headers having `__USE_FORTIFY_LEVEL`:

/usr/include/fcntl.h /usr/include/mqueue.h /usr/include/setjmp.h /usr/include/stdio.h /usr/include/stdlib.h /usr/include/string.h /usr/include/strings.h /usr/include/unistd.h /usr/include/wchar.h

- List of headers having `__USE_EXTERN_INLINES`:

/usr/include/argp.h /usr/include/argz.h /usr/include/ctype.h /usr/include/pthread.h /usr/include/stdio.h /usr/include/stdlib.h /usr/include/threads.h /usr/include/wchar.h