https://github.com/al45tair created https://github.com/llvm/llvm-project/pull/85092
Clang was putting its built-in headers at the end of the search path if running on musl; this was a mistake, because it breaks libc++, as the latter tries to include the built-in header and then the `#include_next` in the built-in header fails. The right solution here is to have the built-in headers remain in their usual location in the search path, and then if it's desirable to override them for musl, have them explicitly include the musl header with `#include_next`. This is the solution that is already in use for other platforms. rdar://118881637 >From 527aa4616dc53f8f7ca212472fa40c23f40b6dc1 Mon Sep 17 00:00:00 2001 From: Alastair Houghton <ahough...@apple.com> Date: Thu, 22 Feb 2024 11:33:32 +0000 Subject: [PATCH] [Clang] Prioritise built-in headers, even on musl. Clang was putting its built-in headers at the end of the search path if running on musl; this was a mistake, because it breaks libc++, as the latter tries to include the built-in header and then the `#include_next` in the built-in header fails. The right solution here is to have the built-in headers remain in their usual location in the search path, and then if it's desirable to override them for musl, have them explicitly include the musl header with `#include_next`. This is the solution that is already in use for other platforms. rdar://118881637 --- clang/lib/Basic/Targets/OSTargets.h | 2 ++ clang/lib/Driver/ToolChains/Linux.cpp | 22 +++++++++++++--------- clang/lib/Headers/float.h | 10 +++------- clang/lib/Headers/stddef.h | 10 ++++++++++ 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 4366c1149e4053..7c5ef420757ef3 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -331,6 +331,8 @@ class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> { } else { Builder.defineMacro("__gnu_linux__"); } + if (Triple.isMusl()) + Builder.defineMacro("__musl__", "1"); if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); if (Opts.CPlusPlus) diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 6c2f23e57bce05..857cbb73240cf6 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -629,13 +629,20 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, // Add 'include' in the resource directory, which is similar to // GCC_INCLUDE_DIR (private headers) in GCC. Note: the include directory - // contains some files conflicting with system /usr/include. musl systems - // prefer the /usr/include copies which are more relevant. - SmallString<128> ResourceDirInclude(D.ResourceDir); - llvm::sys::path::append(ResourceDirInclude, "include"); - if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && - (!getTriple().isMusl() || DriverArgs.hasArg(options::OPT_nostdlibinc))) + // contains some files conflicting with system /usr/include. + // + // Note: the include order used to be different on musl systems because + // of the expectation that that users of that C library would use the + // C library's copies of the "built-in" headers. This was a mistake; + // it's better to adapt the built-in headers to fall through in that case + // (using #include_next), since otherwise if they get pulled in through + // some other mechanism, __has_include_next(<header>) will fail and then + // they'll try to redefine things, which causes errors. + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> ResourceDirInclude(D.ResourceDir); + llvm::sys::path::append(ResourceDirInclude, "include"); addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude); + } if (DriverArgs.hasArg(options::OPT_nostdlibinc)) return; @@ -676,9 +683,6 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include")); addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include")); - - if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && getTriple().isMusl()) - addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude); } void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, diff --git a/clang/lib/Headers/float.h b/clang/lib/Headers/float.h index 0e73bca0a2d6e4..715a4eb54b54a4 100644 --- a/clang/lib/Headers/float.h +++ b/clang/lib/Headers/float.h @@ -10,15 +10,11 @@ #ifndef __CLANG_FLOAT_H #define __CLANG_FLOAT_H -/* If we're on MinGW, fall back to the system's float.h, which might have - * additional definitions provided for Windows. - * For more details see http://msdn.microsoft.com/en-us/library/y0ybw9fy.aspx - * - * Also fall back on Darwin and AIX to allow additional definitions and - * implementation-defined values. +/* On various platforms, fall back to the system's float.h, which might have + * additional definitions and/or implementation-defined values. */ #if (defined(__APPLE__) || defined(__MINGW32__) || defined(_MSC_VER) || \ - defined(_AIX)) && \ + defined(_AIX) || defined(__musl__)) && \ __STDC_HOSTED__ && __has_include_next(<float.h>) /* Prior to Apple's 10.7 SDK, float.h SDK header used to apply an extra level diff --git a/clang/lib/Headers/stddef.h b/clang/lib/Headers/stddef.h index e0ad7b8d17aff9..11e7b8a4d645fa 100644 --- a/clang/lib/Headers/stddef.h +++ b/clang/lib/Headers/stddef.h @@ -28,6 +28,14 @@ * When clang modules are not enabled, the header guards can function in the * normal simple fashion. */ + +#if defined(__musl__) + +// On musl systems, use the system header +#include_next <stddef.h> + +#else + #if !defined(__STDDEF_H) || __has_feature(modules) || \ (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1) || \ defined(__need_ptrdiff_t) || defined(__need_size_t) || \ @@ -121,3 +129,5 @@ __WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */ #endif /* __need_wint_t */ #endif + +#endif /* !defined(__musl__) */ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits