Open liam-clink opened 1 year ago
@llvm/issue-subscribers-libc
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.
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.
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.
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.
Suggested re-title: "Standard library re-aliasing issues in overlay mode builds only in the release configuration"
Looks like gcc will error for aliases created with the alias attributes, but not asm aliases.
Simpler reproducer:
$ cd <new build dir>
$ cmake ../llvm -DLLVM_ENABLE_PROJECTS="libc" -DCMAKE_BUILD_TYPE=Release -G Ninja
$ ninja libc.src.stdlib.bsearch
Looks like gcc will error for aliases created with the alias attributes, but not asm aliases.
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).
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:
#ifdef _FORTIFY_SOURCE
#define LIBC_OLD_FORTIFY_SOURCE _FORTIFY_SOURCE
#undef _FORTIFY_SOURCE
#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
CMake invocation: (C/C++ compilers set to GCC/G++)