https://github.com/ldionne updated 
https://github.com/llvm/llvm-project/pull/170912

>From 12a532cc430c3b89483ce9cc89bbfc7bea8541e5 Mon Sep 17 00:00:00 2001
From: Kewen Meng <[email protected]>
Date: Fri, 5 Dec 2025 12:01:47 -0800
Subject: [PATCH 1/3] =?UTF-8?q?Revert=20"[clang][Darwin]=20Prefer=20the=20?=
 =?UTF-8?q?toolchain-provided=20libc++.dylib=20if=20there=20i=E2=80=A6"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This reverts commit 190b8d0b4f19e1c3d68c5d153ec7be71a9969192.
---
 clang/lib/Driver/ToolChains/Darwin.cpp        | 44 +---------
 .../usr/lib/libc++.dylib                      |  0
 .../usr/lib/libc++experimental.a              |  0
 .../usr/bin/.keep                             |  0
 .../usr/include/c++/v1/.keep                  |  0
 .../usr/lib/libc++.a                          |  0
 .../usr/lib/libc++experimental.a              |  0
 .../Driver/darwin-header-search-libcxx.cpp    |  4 +-
 clang/test/Driver/darwin-link-libcxx.cpp      | 81 -------------------
 .../test/Driver/experimental-library-flag.cpp |  8 +-
 compiler-rt/cmake/config-ix.cmake             | 15 ----
 11 files changed, 8 insertions(+), 144 deletions(-)
 delete mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++.dylib
 delete mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++experimental.a
 delete mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/bin/.keep
 delete mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/include/c++/v1/.keep
 delete mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++.a
 delete mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++experimental.a
 delete mode 100644 clang/test/Driver/darwin-link-libcxx.cpp

diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp 
b/clang/lib/Driver/ToolChains/Darwin.cpp
index 30c53389dc22f..fc3cd9030f71d 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -2846,49 +2846,11 @@ void AppleMachO::AddCXXStdlibLibArgs(const ArgList 
&Args,
   CXXStdlibType Type = GetCXXStdlibType(Args);
 
   switch (Type) {
-  case ToolChain::CST_Libcxx: {
-    // On Darwin, we prioritize a libc++ located in the toolchain to a libc++
-    // located in the sysroot. Unlike the driver for most other platforms, on
-    // Darwin we do that by explicitly passing the library path to the linker
-    // to avoid having to add the toolchain's `lib/` directory to the linker
-    // search path, which would make other libraries findable as well.
-    //
-    // Prefering the toolchain library over the sysroot library matches the
-    // behavior we have for headers, where we prefer headers in the toolchain
-    // over headers in the sysroot if there are any. Note that it's important
-    // for the header search path behavior to match the link-time search path
-    // behavior to ensure that we link the program against a library that
-    // matches the headers that were used to compile it.
-    //
-    // Otherwise, we end up compiling against some set of headers and then
-    // linking against a different library (which, confusingly, shares the same
-    // name) which may have been configured with different options, be at a
-    // different version, etc.
-    SmallString<128> InstallLib = 
llvm::sys::path::parent_path(getDriver().Dir);
-    llvm::sys::path::append(InstallLib, "lib"); // <install>/lib
-    auto Link = [&](StringRef Library) {
-      SmallString<128> Shared(InstallLib);
-      llvm::sys::path::append(Shared,
-                              SmallString<4>("lib") + Library + ".dylib");
-      SmallString<128> Static(InstallLib);
-      llvm::sys::path::append(Static, SmallString<4>("lib") + Library + ".a");
-      SmallString<32> Relative("-l");
-      Relative += Library;
-
-      if (getVFS().exists(Shared)) {
-        CmdArgs.push_back(Args.MakeArgString(Shared));
-      } else if (getVFS().exists(Static)) {
-        CmdArgs.push_back(Args.MakeArgString(Static));
-      } else {
-        CmdArgs.push_back(Args.MakeArgString(Relative));
-      }
-    };
-
-    Link("c++");
+  case ToolChain::CST_Libcxx:
+    CmdArgs.push_back("-lc++");
     if (Args.hasArg(options::OPT_fexperimental_library))
-      Link("c++experimental");
+      CmdArgs.push_back("-lc++experimental");
     break;
-  }
 
   case ToolChain::CST_Libstdcxx:
     // Unfortunately, -lstdc++ doesn't always exist in the standard search 
path;
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++.dylib 
b/clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++.dylib
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++experimental.a 
b/clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++experimental.a
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/bin/.keep 
b/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/bin/.keep
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/include/c++/v1/.keep
 
b/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/include/c++/v1/.keep
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++.a 
b/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++.a
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++experimental.a
 
b/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++experimental.a
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git a/clang/test/Driver/darwin-header-search-libcxx.cpp 
b/clang/test/Driver/darwin-header-search-libcxx.cpp
index e8985a4e22b2f..cc8ec9ceb89b3 100644
--- a/clang/test/Driver/darwin-header-search-libcxx.cpp
+++ b/clang/test/Driver/darwin-header-search-libcxx.cpp
@@ -92,7 +92,7 @@
 // CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" 
"[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
 // CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1-NOT: "-internal-isystem" 
"[[SYSROOT]]/usr/include/c++/v1"
 
-// Make sure that using -nostdinc, -nostdinc++ or -nostdlibinc will drop both 
the toolchain
+// Make sure that using -nostdinc, -nostdinc++ or -nostdlib will drop both the 
toolchain
 // C++ include path and the sysroot one.
 //
 // RUN: %clang -### %s -fsyntax-only 2>&1 \
@@ -116,7 +116,7 @@
 // RUN:     -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
 // RUN:     -stdlib=platform \
 // RUN:     -nostdinc++ \
-// RUN:   | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
+// RUN:   | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \
 // RUN:               -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \
 // RUN:               --check-prefix=CHECK-LIBCXX-NOSTDINCXX %s
 // CHECK-LIBCXX-NOSTDINCXX: "-cc1"
diff --git a/clang/test/Driver/darwin-link-libcxx.cpp 
b/clang/test/Driver/darwin-link-libcxx.cpp
deleted file mode 100644
index 1c4f31b257512..0000000000000
--- a/clang/test/Driver/darwin-link-libcxx.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-// UNSUPPORTED: system-windows
-
-// Tests to check that we link against the toolchain-provided libc++ built 
library when it is provided.
-// This is required to prefer the toolchain's libc++ over the system's libc++, 
which matches the behavior
-// we have for header search paths.
-
-// When libc++.dylib is NOT in the toolchain, we should use -lc++ and fall 
back to the libc++
-// in the sysroot.
-//
-// (1) Without -fexperimental-library.
-// RUN: %clangxx -### %s 2>&1                                                  
 \
-// RUN:     --target=x86_64-apple-darwin                                       
 \
-// RUN:     -ccc-install-dir 
%S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \
-// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx   
 \
-// RUN:               --check-prefix=CHECK-1 %s
-// CHECK-1: "/usr/bin/ld"
-// CHECK-1: "-lc++"
-// CHECK-1-NOT: "[[TOOLCHAIN]]/usr/lib"
-//
-// (2) With -fexperimental-library.
-// RUN: %clangxx -### %s 2>&1                                                  
 \
-// RUN:     --target=x86_64-apple-darwin                                       
 \
-// RUN:     -ccc-install-dir 
%S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \
-// RUN:     -fexperimental-library                                             
 \
-// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx   
 \
-// RUN:               --check-prefix=CHECK-2 %s
-// CHECK-2: "/usr/bin/ld"
-// CHECK-2: "-lc++" "-lc++experimental"
-// CHECK-2-NOT: "[[TOOLCHAIN]]/usr/lib"
-
-// When we have libc++.dylib in the toolchain, it should be used over the one 
in the sysroot.
-// There are a few cases worth testing.
-//
-// (1) Without -fexperimental-library.
-// RUN: %clangxx -### %s 2>&1                                                  
 \
-// RUN:     --target=x86_64-apple-darwin                                       
 \
-// RUN:     -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin          
 \
-// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain             
 \
-// RUN:               --check-prefix=CHECK-3 %s
-// CHECK-3: "/usr/bin/ld"
-// CHECK-3: "[[TOOLCHAIN]]/usr/lib/libc++.dylib"
-// CHECK-3-NOT: "-lc++"
-//
-// (2) With -fexperimental-library.
-// RUN: %clangxx -### %s 2>&1                                                  
 \
-// RUN:     --target=x86_64-apple-darwin                                       
 \
-// RUN:     -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin          
 \
-// RUN:     -fexperimental-library                                             
 \
-// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain             
 \
-// RUN:               --check-prefix=CHECK-4 %s
-// CHECK-4: "/usr/bin/ld"
-// CHECK-4: "[[TOOLCHAIN]]/usr/lib/libc++.dylib"
-// CHECK-4: "[[TOOLCHAIN]]/usr/lib/libc++experimental.a"
-// CHECK-4-NOT: "-lc++"
-// CHECK-4-NOT: "-lc++experimental"
-
-// When we have libc++.a in the toolchain instead of libc++.dylib, it should be
-// used over the one in the sysroot.
-//
-// (1) Without -fexperimental-library.
-// RUN: %clangxx -### %s 2>&1                                                  
 \
-// RUN:     --target=x86_64-apple-darwin                                       
 \
-// RUN:     -ccc-install-dir %S/Inputs/basic_darwin_toolchain_static/usr/bin   
 \
-// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_static      
 \
-// RUN:               --check-prefix=CHECK-5 %s
-// CHECK-5: "/usr/bin/ld"
-// CHECK-5: "[[TOOLCHAIN]]/usr/lib/libc++.a"
-// CHECK-5-NOT: "-lc++"
-//
-// (2) With -fexperimental-library.
-// RUN: %clangxx -### %s 2>&1                                                  
 \
-// RUN:     --target=x86_64-apple-darwin                                       
 \
-// RUN:     -ccc-install-dir %S/Inputs/basic_darwin_toolchain_static/usr/bin   
 \
-// RUN:     -fexperimental-library                                             
 \
-// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_static      
 \
-// RUN:               --check-prefix=CHECK-6 %s
-// CHECK-6: "/usr/bin/ld"
-// CHECK-6: "[[TOOLCHAIN]]/usr/lib/libc++.a"
-// CHECK-6: "[[TOOLCHAIN]]/usr/lib/libc++experimental.a"
-// CHECK-6-NOT: "-lc++"
-// CHECK-6-NOT: "-lc++experimental"
diff --git a/clang/test/Driver/experimental-library-flag.cpp 
b/clang/test/Driver/experimental-library-flag.cpp
index 0546a09d5518b..62b007516897e 100644
--- a/clang/test/Driver/experimental-library-flag.cpp
+++ b/clang/test/Driver/experimental-library-flag.cpp
@@ -18,8 +18,6 @@
 // CHECK: -fexperimental-library
 
 // Depending on the stdlib in use, we should (or not) pass -lc++experimental.
-// Note that we don't check for `-lc++experimental` specifically, since some 
targets
-// like Darwin pass the path to the library explicitly instead of using `-lx`.
-// CHECK-LIBCXX: c++experimental
-// CHECK-LIBSTDCXX-NOT: c++experimental
-// CHECK-NOSTDLIB-NOT: c++experimental
+// CHECK-LIBCXX: -lc++experimental
+// CHECK-LIBSTDCXX-NOT: -lc++experimental
+// CHECK-NOSTDLIB-NOT: -lc++experimental
diff --git a/compiler-rt/cmake/config-ix.cmake 
b/compiler-rt/cmake/config-ix.cmake
index 30a78b69515cc..084a7060e8d13 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -507,23 +507,8 @@ if(APPLE)
   set(CMAKE_OSX_DEPLOYMENT_TARGET "")
 
   set(DARWIN_COMMON_CFLAGS -stdlib=libc++)
-
-  # This is tricky: We want to link against libc++, however the libc++ for the
-  # architecture we're currently building may not have been built yet, since
-  # compiler-rt on Darwin builds for all targets at once while libc++ builds 
for
-  # a single target. Hence, we pass -nostdlib++ to disable the default 
mechanism
-  # for finding libc++, and we pass -lc++ which will end up finding libc++ in 
the
-  # SDK currently in use. That libc++ is the wrong libc++ to use if we're using
-  # headers from a just-built libc++, but at least it contains all the 
architectures
-  # we should be interested in.
-  #
-  # Fixing this properly would require removing the impedence mismatch between
-  # the compiler-rt build on Darwin (which wants to build all architectures at
-  # once) and the libc++ build, which produces a single architecture per CMake
-  # invocation.
   set(DARWIN_COMMON_LINK_FLAGS
     -stdlib=libc++
-    -nostdlib++
     -lc++
     -lc++abi)
 

>From 3ac8417fb4d6d0916cf5082d76d9794420a9cd8e Mon Sep 17 00:00:00 2001
From: Louis Dionne <[email protected]>
Date: Fri, 5 Dec 2025 15:19:05 -0500
Subject: [PATCH 2/3] =?UTF-8?q?Reapply=20"[clang][Darwin]=20Prefer=20the?=
 =?UTF-8?q?=20toolchain-provided=20libc++.dylib=20if=20there=20i=E2=80=A6"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This reverts commit 12a532cc430c3b89483ce9cc89bbfc7bea8541e5.
---
 clang/lib/Driver/ToolChains/Darwin.cpp        | 44 +++++++++-
 .../usr/lib/libc++.dylib                      |  0
 .../usr/lib/libc++experimental.a              |  0
 .../usr/bin/.keep                             |  0
 .../usr/include/c++/v1/.keep                  |  0
 .../usr/lib/libc++.a                          |  0
 .../usr/lib/libc++experimental.a              |  0
 .../Driver/darwin-header-search-libcxx.cpp    |  4 +-
 clang/test/Driver/darwin-link-libcxx.cpp      | 81 +++++++++++++++++++
 .../test/Driver/experimental-library-flag.cpp |  8 +-
 compiler-rt/cmake/config-ix.cmake             | 15 ++++
 11 files changed, 144 insertions(+), 8 deletions(-)
 create mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++.dylib
 create mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++experimental.a
 create mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/bin/.keep
 create mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/include/c++/v1/.keep
 create mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++.a
 create mode 100644 
clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++experimental.a
 create mode 100644 clang/test/Driver/darwin-link-libcxx.cpp

diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp 
b/clang/lib/Driver/ToolChains/Darwin.cpp
index fc3cd9030f71d..30c53389dc22f 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -2846,11 +2846,49 @@ void AppleMachO::AddCXXStdlibLibArgs(const ArgList 
&Args,
   CXXStdlibType Type = GetCXXStdlibType(Args);
 
   switch (Type) {
-  case ToolChain::CST_Libcxx:
-    CmdArgs.push_back("-lc++");
+  case ToolChain::CST_Libcxx: {
+    // On Darwin, we prioritize a libc++ located in the toolchain to a libc++
+    // located in the sysroot. Unlike the driver for most other platforms, on
+    // Darwin we do that by explicitly passing the library path to the linker
+    // to avoid having to add the toolchain's `lib/` directory to the linker
+    // search path, which would make other libraries findable as well.
+    //
+    // Prefering the toolchain library over the sysroot library matches the
+    // behavior we have for headers, where we prefer headers in the toolchain
+    // over headers in the sysroot if there are any. Note that it's important
+    // for the header search path behavior to match the link-time search path
+    // behavior to ensure that we link the program against a library that
+    // matches the headers that were used to compile it.
+    //
+    // Otherwise, we end up compiling against some set of headers and then
+    // linking against a different library (which, confusingly, shares the same
+    // name) which may have been configured with different options, be at a
+    // different version, etc.
+    SmallString<128> InstallLib = 
llvm::sys::path::parent_path(getDriver().Dir);
+    llvm::sys::path::append(InstallLib, "lib"); // <install>/lib
+    auto Link = [&](StringRef Library) {
+      SmallString<128> Shared(InstallLib);
+      llvm::sys::path::append(Shared,
+                              SmallString<4>("lib") + Library + ".dylib");
+      SmallString<128> Static(InstallLib);
+      llvm::sys::path::append(Static, SmallString<4>("lib") + Library + ".a");
+      SmallString<32> Relative("-l");
+      Relative += Library;
+
+      if (getVFS().exists(Shared)) {
+        CmdArgs.push_back(Args.MakeArgString(Shared));
+      } else if (getVFS().exists(Static)) {
+        CmdArgs.push_back(Args.MakeArgString(Static));
+      } else {
+        CmdArgs.push_back(Args.MakeArgString(Relative));
+      }
+    };
+
+    Link("c++");
     if (Args.hasArg(options::OPT_fexperimental_library))
-      CmdArgs.push_back("-lc++experimental");
+      Link("c++experimental");
     break;
+  }
 
   case ToolChain::CST_Libstdcxx:
     // Unfortunately, -lstdc++ doesn't always exist in the standard search 
path;
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++.dylib 
b/clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++.dylib
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++experimental.a 
b/clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++experimental.a
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/bin/.keep 
b/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/bin/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/include/c++/v1/.keep
 
b/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/include/c++/v1/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++.a 
b/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++.a
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git 
a/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++experimental.a
 
b/clang/test/Driver/Inputs/basic_darwin_toolchain_static/usr/lib/libc++experimental.a
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/darwin-header-search-libcxx.cpp 
b/clang/test/Driver/darwin-header-search-libcxx.cpp
index cc8ec9ceb89b3..e8985a4e22b2f 100644
--- a/clang/test/Driver/darwin-header-search-libcxx.cpp
+++ b/clang/test/Driver/darwin-header-search-libcxx.cpp
@@ -92,7 +92,7 @@
 // CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" 
"[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
 // CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1-NOT: "-internal-isystem" 
"[[SYSROOT]]/usr/include/c++/v1"
 
-// Make sure that using -nostdinc, -nostdinc++ or -nostdlib will drop both the 
toolchain
+// Make sure that using -nostdinc, -nostdinc++ or -nostdlibinc will drop both 
the toolchain
 // C++ include path and the sysroot one.
 //
 // RUN: %clang -### %s -fsyntax-only 2>&1 \
@@ -116,7 +116,7 @@
 // RUN:     -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
 // RUN:     -stdlib=platform \
 // RUN:     -nostdinc++ \
-// RUN:   | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \
+// RUN:   | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
 // RUN:               -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \
 // RUN:               --check-prefix=CHECK-LIBCXX-NOSTDINCXX %s
 // CHECK-LIBCXX-NOSTDINCXX: "-cc1"
diff --git a/clang/test/Driver/darwin-link-libcxx.cpp 
b/clang/test/Driver/darwin-link-libcxx.cpp
new file mode 100644
index 0000000000000..1c4f31b257512
--- /dev/null
+++ b/clang/test/Driver/darwin-link-libcxx.cpp
@@ -0,0 +1,81 @@
+// UNSUPPORTED: system-windows
+
+// Tests to check that we link against the toolchain-provided libc++ built 
library when it is provided.
+// This is required to prefer the toolchain's libc++ over the system's libc++, 
which matches the behavior
+// we have for header search paths.
+
+// When libc++.dylib is NOT in the toolchain, we should use -lc++ and fall 
back to the libc++
+// in the sysroot.
+//
+// (1) Without -fexperimental-library.
+// RUN: %clangxx -### %s 2>&1                                                  
 \
+// RUN:     --target=x86_64-apple-darwin                                       
 \
+// RUN:     -ccc-install-dir 
%S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \
+// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx   
 \
+// RUN:               --check-prefix=CHECK-1 %s
+// CHECK-1: "/usr/bin/ld"
+// CHECK-1: "-lc++"
+// CHECK-1-NOT: "[[TOOLCHAIN]]/usr/lib"
+//
+// (2) With -fexperimental-library.
+// RUN: %clangxx -### %s 2>&1                                                  
 \
+// RUN:     --target=x86_64-apple-darwin                                       
 \
+// RUN:     -ccc-install-dir 
%S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \
+// RUN:     -fexperimental-library                                             
 \
+// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx   
 \
+// RUN:               --check-prefix=CHECK-2 %s
+// CHECK-2: "/usr/bin/ld"
+// CHECK-2: "-lc++" "-lc++experimental"
+// CHECK-2-NOT: "[[TOOLCHAIN]]/usr/lib"
+
+// When we have libc++.dylib in the toolchain, it should be used over the one 
in the sysroot.
+// There are a few cases worth testing.
+//
+// (1) Without -fexperimental-library.
+// RUN: %clangxx -### %s 2>&1                                                  
 \
+// RUN:     --target=x86_64-apple-darwin                                       
 \
+// RUN:     -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin          
 \
+// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain             
 \
+// RUN:               --check-prefix=CHECK-3 %s
+// CHECK-3: "/usr/bin/ld"
+// CHECK-3: "[[TOOLCHAIN]]/usr/lib/libc++.dylib"
+// CHECK-3-NOT: "-lc++"
+//
+// (2) With -fexperimental-library.
+// RUN: %clangxx -### %s 2>&1                                                  
 \
+// RUN:     --target=x86_64-apple-darwin                                       
 \
+// RUN:     -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin          
 \
+// RUN:     -fexperimental-library                                             
 \
+// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain             
 \
+// RUN:               --check-prefix=CHECK-4 %s
+// CHECK-4: "/usr/bin/ld"
+// CHECK-4: "[[TOOLCHAIN]]/usr/lib/libc++.dylib"
+// CHECK-4: "[[TOOLCHAIN]]/usr/lib/libc++experimental.a"
+// CHECK-4-NOT: "-lc++"
+// CHECK-4-NOT: "-lc++experimental"
+
+// When we have libc++.a in the toolchain instead of libc++.dylib, it should be
+// used over the one in the sysroot.
+//
+// (1) Without -fexperimental-library.
+// RUN: %clangxx -### %s 2>&1                                                  
 \
+// RUN:     --target=x86_64-apple-darwin                                       
 \
+// RUN:     -ccc-install-dir %S/Inputs/basic_darwin_toolchain_static/usr/bin   
 \
+// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_static      
 \
+// RUN:               --check-prefix=CHECK-5 %s
+// CHECK-5: "/usr/bin/ld"
+// CHECK-5: "[[TOOLCHAIN]]/usr/lib/libc++.a"
+// CHECK-5-NOT: "-lc++"
+//
+// (2) With -fexperimental-library.
+// RUN: %clangxx -### %s 2>&1                                                  
 \
+// RUN:     --target=x86_64-apple-darwin                                       
 \
+// RUN:     -ccc-install-dir %S/Inputs/basic_darwin_toolchain_static/usr/bin   
 \
+// RUN:     -fexperimental-library                                             
 \
+// RUN:   | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_static      
 \
+// RUN:               --check-prefix=CHECK-6 %s
+// CHECK-6: "/usr/bin/ld"
+// CHECK-6: "[[TOOLCHAIN]]/usr/lib/libc++.a"
+// CHECK-6: "[[TOOLCHAIN]]/usr/lib/libc++experimental.a"
+// CHECK-6-NOT: "-lc++"
+// CHECK-6-NOT: "-lc++experimental"
diff --git a/clang/test/Driver/experimental-library-flag.cpp 
b/clang/test/Driver/experimental-library-flag.cpp
index 62b007516897e..0546a09d5518b 100644
--- a/clang/test/Driver/experimental-library-flag.cpp
+++ b/clang/test/Driver/experimental-library-flag.cpp
@@ -18,6 +18,8 @@
 // CHECK: -fexperimental-library
 
 // Depending on the stdlib in use, we should (or not) pass -lc++experimental.
-// CHECK-LIBCXX: -lc++experimental
-// CHECK-LIBSTDCXX-NOT: -lc++experimental
-// CHECK-NOSTDLIB-NOT: -lc++experimental
+// Note that we don't check for `-lc++experimental` specifically, since some 
targets
+// like Darwin pass the path to the library explicitly instead of using `-lx`.
+// CHECK-LIBCXX: c++experimental
+// CHECK-LIBSTDCXX-NOT: c++experimental
+// CHECK-NOSTDLIB-NOT: c++experimental
diff --git a/compiler-rt/cmake/config-ix.cmake 
b/compiler-rt/cmake/config-ix.cmake
index 084a7060e8d13..30a78b69515cc 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -507,8 +507,23 @@ if(APPLE)
   set(CMAKE_OSX_DEPLOYMENT_TARGET "")
 
   set(DARWIN_COMMON_CFLAGS -stdlib=libc++)
+
+  # This is tricky: We want to link against libc++, however the libc++ for the
+  # architecture we're currently building may not have been built yet, since
+  # compiler-rt on Darwin builds for all targets at once while libc++ builds 
for
+  # a single target. Hence, we pass -nostdlib++ to disable the default 
mechanism
+  # for finding libc++, and we pass -lc++ which will end up finding libc++ in 
the
+  # SDK currently in use. That libc++ is the wrong libc++ to use if we're using
+  # headers from a just-built libc++, but at least it contains all the 
architectures
+  # we should be interested in.
+  #
+  # Fixing this properly would require removing the impedence mismatch between
+  # the compiler-rt build on Darwin (which wants to build all architectures at
+  # once) and the libc++ build, which produces a single architecture per CMake
+  # invocation.
   set(DARWIN_COMMON_LINK_FLAGS
     -stdlib=libc++
+    -nostdlib++
     -lc++
     -lc++abi)
 

>From 4c50d83e8ddecf0cf6f642671523e14770d1c3e7 Mon Sep 17 00:00:00 2001
From: Louis Dionne <[email protected]>
Date: Fri, 5 Dec 2025 15:23:05 -0500
Subject: [PATCH 3/3] Require darwin

---
 clang/test/Driver/darwin-link-libcxx.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/test/Driver/darwin-link-libcxx.cpp 
b/clang/test/Driver/darwin-link-libcxx.cpp
index 1c4f31b257512..fca1e3c6f3d6f 100644
--- a/clang/test/Driver/darwin-link-libcxx.cpp
+++ b/clang/test/Driver/darwin-link-libcxx.cpp
@@ -1,5 +1,8 @@
 // UNSUPPORTED: system-windows
 
+// TODO: Make this test portable across platforms
+// REQUIRES: system-darwin
+
 // Tests to check that we link against the toolchain-provided libc++ built 
library when it is provided.
 // This is required to prefer the toolchain's libc++ over the system's libc++, 
which matches the behavior
 // we have for header search paths.

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to