llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang <details> <summary>Changes</summary> Summary: We previously had to disable these string functions because they were not compatible with the definitions coming from the GNU / host environment. The GPU, when exporting its declarations, has a very difficult requirement that it be compatible with the host environment as both sides of the compilation need to agree on definitions and what's present. For `string.h`, some functions have different defintions for C and C++. GNU would optionally provide the C++ definitions directly in the `string.h` file. This patch attempts to hack around this by tricking the GNU headers into thinking that the `clang` used it too old to support their special definition handling. The blast radius from this hack should be somewhat minimal, only changing C++ behaviour for a few functions. The only noticable change is that we lose const error checking for a small handful of functions if the user includes `string.h` directly in C++ mode instead of <cstring>. --- Full diff: https://github.com/llvm/llvm-project/pull/67869.diff 3 Files Affected: - (modified) clang/lib/Headers/llvm_libc_wrappers/string.h (+24-3) - (modified) libc/config/gpu/entrypoints.txt (+16) - (modified) libc/docs/gpu/support.rst (+19-8) ``````````diff diff --git a/clang/lib/Headers/llvm_libc_wrappers/string.h b/clang/lib/Headers/llvm_libc_wrappers/string.h index 027c415c1d0f8f3..0fa6d81fda36b61 100644 --- a/clang/lib/Headers/llvm_libc_wrappers/string.h +++ b/clang/lib/Headers/llvm_libc_wrappers/string.h @@ -13,11 +13,32 @@ #error "This file is for GPU offloading compilation only" #endif -// FIXME: The GNU headers provide C++ standard compliant headers when in C++ -// mode and the LLVM libc does not. We cannot enable memchr, strchr, strchrnul, -// strpbrk, strrchr, strstr, or strcasestr until this is addressed. +// The GNU headers provide C++ standard compliant headers when in C++ mode and +// the LLVM libc does not. We need to perform a pretty nasty hack to trick the +// GNU headers into emitting the C compatible definitions so we can use them. +#if defined(__cplusplus) && defined(__GLIBC__) + +// We need to make sure that the GNU C library has done its setup before we mess +// with the expected macro values. +#if !defined(__GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION) && \ + __has_include(<bits/libc-header-start.h>) +#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION +#include <bits/libc-header-start.h> +#endif + +// Trick the GNU headers into thinking that this clang is too old for the C++ +// definitions. +#pragma push_macro("__clang_major__") +#define __clang_major__ 3 +#endif + #include_next <string.h> +// Resore the original macros if they were changed. +#if defined(__cplusplus) && defined(__GLIBC__) +#pragma pop_macro("__clang_major__") +#endif + #if __has_include(<llvm-libc-decls/string.h>) #if defined(__HIP__) || defined(__CUDA__) diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt index ad68216a76b9429..dcaca15b500cbe9 100644 --- a/libc/config/gpu/entrypoints.txt +++ b/libc/config/gpu/entrypoints.txt @@ -22,21 +22,31 @@ set(TARGET_LIBC_ENTRYPOINTS # string.h entrypoints libc.src.string.bcmp + libc.src.string.bcopy libc.src.string.bzero + libc.src.string.index libc.src.string.memccpy + libc.src.string.memchr libc.src.string.memcmp libc.src.string.memcpy libc.src.string.memmem libc.src.string.memmove libc.src.string.mempcpy + libc.src.string.memrchr libc.src.string.memset + libc.src.string.rindex libc.src.string.stpcpy libc.src.string.stpncpy libc.src.string.strcasecmp + libc.src.string.strcasestr libc.src.string.strcat + libc.src.string.strchr + libc.src.string.strchrnul libc.src.string.strcmp + libc.src.string.strcoll libc.src.string.strcpy libc.src.string.strcspn + libc.src.string.strdup libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen @@ -44,10 +54,16 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strncat libc.src.string.strncmp libc.src.string.strncpy + libc.src.string.strndup libc.src.string.strnlen + libc.src.string.strpbrk + libc.src.string.strrchr + libc.src.string.strsep libc.src.string.strspn + libc.src.string.strstr libc.src.string.strtok libc.src.string.strtok_r + libc.src.string.strxfrm # stdlib.h entrypoints libc.src.stdlib.abs diff --git a/libc/docs/gpu/support.rst b/libc/docs/gpu/support.rst index fd27273ed562e49..beca7b587a05215 100644 --- a/libc/docs/gpu/support.rst +++ b/libc/docs/gpu/support.rst @@ -45,37 +45,48 @@ string.h Function Name Available RPC Required ============= ========= ============ bcmp |check| +bcopy |check| bzero |check| +index |check| memccpy |check| -memchr +memchr |check| memcmp |check| memcpy |check| +memmem |check| memmove |check| mempcpy |check| -memrchr +memrchr |check| memset |check| +rindex |check| stpcpy |check| stpncpy |check| +strcasecmp |check| +strcasestr |check| strcat |check| -strchr +strchr |check| +strchrnul |check| strcmp |check| +strcoll |check| strcpy |check| strcspn |check| +strdup |check| strlcat |check| strlcpy |check| strlen |check| +strncasecmp |check| strncat |check| strncmp |check| strncpy |check| +strndup |check| strnlen |check| -strpbrk -strrchr +strpbrk |check| +strrchr |check| +strsep |check| strspn |check| -strstr +strstr |check| strtok |check| strtok_r |check| -strdup -strndup +strxfrm |check| ============= ========= ============ stdlib.h `````````` </details> https://github.com/llvm/llvm-project/pull/67869 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits