Clang considers trivially recursive a function that may call itself, not a function that always call itself.
This leads to some inline definition of fortified libc builtins no being emitted, and thus ignored.
Work around the situation by detecting the pattern and generate a combination of builtin / nobuiltin attributes to have it work as expected.
The basic problem to solve is the compilation of the following code, which exhibits the behavior used in the glibc. Note that currently clang generates a call to wmemcpy ad not __wmemcpy_chk as it should, leading to a less secure code.
typedef long unsigned int size_t; typedef int wchar_t; extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, size_t __n, size_t __ns1) __attribute__ ((__nothrow__ )); extern wchar_t *__wmemcpy_alias (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, size_t __n) __asm__("wmemcpy") __attribute__ ((__nothrow__ )); extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__nothrow__ )) wchar_t * wmemcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, size_t __n) { if (__builtin_object_size (__s1, 0) != (size_t) -1 && (!__builtin_constant_p (__n) || __n > __builtin_object_size (__s1, 0) / sizeof (wchar_t))) { return __wmemcpy_chk (__s1, __s2, __n, (__builtin_object_size (__s1, 0) / sizeof (wchar_t))); } return __wmemcpy_alias (__s1, __s2, __n); } wchar_t wbuf[10]; int main (int argc, char **argv) { wmemcpy (wbuf + 1, L"abcdefghij", 10); return 0; }
I see a dep from clangCodeGen to clangAnalysis in the CMakeLists, but this is the first include of clang/Analysis/* from CodeGen. I think we should consider this new dependency more carefully.
@rjmccall, can you please advise about the new dependency?