[clang] [Clang] Prioritise built-in headers, even on musl. (PR #85092)
Alastair Houghton via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 13 07:47:29 PDT 2024
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 <ahoughton at 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__) */
More information about the cfe-commits
mailing list