forked from OSchip/llvm-project
[clang] Don't look into <sysroot> for C++ headers if they are found alongside the toolchain
Currently, Clang looks for libc++ headers alongside the installation directory of Clang, and it also adds a search path for headers in the -isysroot. This is problematic if headers are found in both the toolchain and in the sysroot, since #include_next will end up finding the libc++ headers in the sysroot instead of the intended system headers. This patch changes the logic such that if the toolchain contains libc++ headers, no C++ header paths are added in the sysroot. However, if the toolchain does *not* contain libc++ headers, the sysroot is searched as usual. This should not be a breaking change, since any code that previously relied on some libc++ headers being found in the sysroot suffered from the #include_next issue described above, which renders any libc++ header basically useless. Differential Revision: https://reviews.llvm.org/D89001
This commit is contained in:
parent
12805513a6
commit
a3a2431608
|
@ -2020,21 +2020,42 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs(
|
|||
|
||||
switch (GetCXXStdlibType(DriverArgs)) {
|
||||
case ToolChain::CST_Libcxx: {
|
||||
// On Darwin, libc++ is installed alongside the compiler in
|
||||
// include/c++/v1, so get from '<install>/bin' to '<install>/include/c++/v1'.
|
||||
{
|
||||
llvm::SmallString<128> P = llvm::StringRef(getDriver().getInstalledDir());
|
||||
// Note that P can be relative, so we have to '..' and not parent_path.
|
||||
llvm::sys::path::append(P, "..", "include", "c++", "v1");
|
||||
addSystemInclude(DriverArgs, CC1Args, P);
|
||||
// On Darwin, libc++ can be installed in one of the following two places:
|
||||
// 1. Alongside the compiler in <install>/include/c++/v1
|
||||
// 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
|
||||
//
|
||||
// The precendence of paths is as listed above, i.e. we take the first path
|
||||
// that exists. Also note that we never include libc++ twice -- we take the
|
||||
// first path that exists and don't send the other paths to CC1 (otherwise
|
||||
// include_next could break).
|
||||
|
||||
// Check for (1)
|
||||
// Get from '<install>/bin' to '<install>/include/c++/v1'.
|
||||
// Note that InstallBin can be relative, so we use '..' instead of
|
||||
// parent_path.
|
||||
llvm::SmallString<128> InstallBin =
|
||||
llvm::StringRef(getDriver().getInstalledDir()); // <install>/bin
|
||||
llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1");
|
||||
if (getVFS().exists(InstallBin)) {
|
||||
addSystemInclude(DriverArgs, CC1Args, InstallBin);
|
||||
return;
|
||||
} else if (DriverArgs.hasArg(options::OPT_v)) {
|
||||
llvm::errs() << "ignoring nonexistent directory \"" << InstallBin
|
||||
<< "\"\n";
|
||||
}
|
||||
// Also add <sysroot>/usr/include/c++/v1 unless -nostdinc is used,
|
||||
// to match the legacy behavior in CC1.
|
||||
if (!DriverArgs.hasArg(options::OPT_nostdinc)) {
|
||||
llvm::SmallString<128> P = Sysroot;
|
||||
llvm::sys::path::append(P, "usr", "include", "c++", "v1");
|
||||
addSystemInclude(DriverArgs, CC1Args, P);
|
||||
|
||||
// Otherwise, check for (2)
|
||||
llvm::SmallString<128> SysrootUsr = Sysroot;
|
||||
llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1");
|
||||
if (getVFS().exists(SysrootUsr)) {
|
||||
addSystemInclude(DriverArgs, CC1Args, SysrootUsr);
|
||||
return;
|
||||
} else if (DriverArgs.hasArg(options::OPT_v)) {
|
||||
llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr
|
||||
<< "\"\n";
|
||||
}
|
||||
|
||||
// Otherwise, don't add any path.
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,39 +13,57 @@
|
|||
// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-NONE %s
|
||||
// CHECK-LIBCXX-NONE: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
|
||||
|
||||
// Check with only headers alongside the installation (those should be used,
|
||||
// but we should still add /usr/include/c++/v1 after to preserve legacy).
|
||||
// Check with only headers alongside the installation (those should be used).
|
||||
//
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
|
||||
// RUN: -target x86_64-apple-darwin \
|
||||
// RUN: -stdlib=libc++ \
|
||||
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \
|
||||
// RUN: --sysroot="" \
|
||||
// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain --check-prefix=CHECK-LIBCXX-TOOLCHAIN-1 %s
|
||||
// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \
|
||||
// RUN: --check-prefix=CHECK-LIBCXX-TOOLCHAIN-1 %s
|
||||
// CHECK-LIBCXX-TOOLCHAIN-1: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
|
||||
// CHECK-LIBCXX-TOOLCHAIN-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
|
||||
// CHECK-LIBCXX-TOOLCHAIN-1: "-internal-isystem" "/usr/include/c++/v1"
|
||||
// CHECK-LIBCXX-TOOLCHAIN-1-NOT: "-internal-isystem" "/usr/include/c++/v1"
|
||||
//
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
|
||||
// RUN: -target x86_64-apple-darwin \
|
||||
// RUN: -stdlib=libc++ \
|
||||
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_no_libcxx \
|
||||
// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain --check-prefix=CHECK-LIBCXX-TOOLCHAIN-2 %s
|
||||
// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \
|
||||
// RUN: -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \
|
||||
// RUN: --check-prefix=CHECK-LIBCXX-TOOLCHAIN-2 %s
|
||||
// CHECK-LIBCXX-TOOLCHAIN-2: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
|
||||
// CHECK-LIBCXX-TOOLCHAIN-2: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
|
||||
// CHECK-LIBCXX-TOOLCHAIN-2-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
|
||||
|
||||
// Check with only headers in the sysroot (those should be used).
|
||||
//
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
|
||||
// RUN: -target x86_64-apple-darwin \
|
||||
// RUN: -stdlib=libc++ \
|
||||
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
|
||||
// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
|
||||
// RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \
|
||||
// RUN: --check-prefix=CHECK-LIBCXX-SYSROOT-1 %s
|
||||
// CHECK-LIBCXX-SYSROOT-1: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
|
||||
// CHECK-LIBCXX-SYSROOT-1: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
|
||||
// CHECK-LIBCXX-SYSROOT-1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
|
||||
|
||||
// Check with both headers in the sysroot and headers alongside the installation
|
||||
// (the headers in <sysroot> should be added after the toolchain headers).
|
||||
// Ensure that both -isysroot and --sysroot work, and that isysroot has precedence.
|
||||
// (the headers in the toolchain should be preferred over the <sysroot> headers).
|
||||
// Ensure that both -isysroot and --sysroot work, and that isysroot has precedence
|
||||
// over --sysroot.
|
||||
//
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
|
||||
// RUN: -target x86_64-apple-darwin \
|
||||
// RUN: -stdlib=libc++ \
|
||||
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \
|
||||
// RUN: -resource-dir=%S/Inputs/resource_dir \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr \
|
||||
// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
|
||||
// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
|
||||
// RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \
|
||||
// RUN: --check-prefix=CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1 %s
|
||||
//
|
||||
|
@ -54,8 +72,8 @@
|
|||
// RUN: -stdlib=libc++ \
|
||||
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \
|
||||
// RUN: -resource-dir=%S/Inputs/resource_dir \
|
||||
// RUN: --sysroot %S/Inputs/basic_darwin_sdk_usr \
|
||||
// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \
|
||||
// RUN: --sysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
|
||||
// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
|
||||
// RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \
|
||||
// RUN: --check-prefix=CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1 %s
|
||||
//
|
||||
|
@ -64,32 +82,46 @@
|
|||
// RUN: -stdlib=libc++ \
|
||||
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \
|
||||
// RUN: -resource-dir=%S/Inputs/resource_dir \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
|
||||
// RUN: --sysroot %S/Inputs/basic_darwin_sdk_no_libcxx \
|
||||
// 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-SYSROOT_AND_TOOLCHAIN-1 %s
|
||||
//
|
||||
// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
|
||||
// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
|
||||
// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
|
||||
// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
|
||||
|
||||
// Make sure that using -nostdinc will drop the sysroot C++ library include
|
||||
// path, but not the toolchain one.
|
||||
// Make sure that using -nostdinc does not drop any C++ library include path.
|
||||
// This behavior is strange, but it is compatible with the legacy CC1 behavior.
|
||||
//
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
|
||||
// RUN: -target x86_64-apple-darwin16 \
|
||||
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \
|
||||
// RUN: -resource-dir=%S/Inputs/resource_dir \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr \
|
||||
// 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-NOSTDINC %s
|
||||
// CHECK-LIBCXX-NOSTDINC: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
|
||||
// CHECK-LIBCXX-NOSTDINC: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
|
||||
// CHECK-LIBCXX-NOSTDINC-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
|
||||
// RUN: --check-prefix=CHECK-LIBCXX-NOSTDINC-1 %s
|
||||
// CHECK-LIBCXX-NOSTDINC-1: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
|
||||
// CHECK-LIBCXX-NOSTDINC-1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
|
||||
// CHECK-LIBCXX-NOSTDINC-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
|
||||
//
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
|
||||
// RUN: -target x86_64-apple-darwin16 \
|
||||
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \
|
||||
// RUN: -resource-dir=%S/Inputs/resource_dir \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_no_libcxx \
|
||||
// RUN: -stdlib=platform \
|
||||
// RUN: -nostdinc \
|
||||
// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \
|
||||
// RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \
|
||||
// RUN: --check-prefix=CHECK-LIBCXX-NOSTDINC-2 %s
|
||||
// CHECK-LIBCXX-NOSTDINC-2: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
|
||||
// CHECK-LIBCXX-NOSTDINC-2: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
|
||||
// CHECK-LIBCXX-NOSTDINC-2-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
|
||||
|
||||
// Make sure that using -nostdinc++ or -nostdlib will drop both the toolchain
|
||||
// C++ include path and the sysroot one.
|
||||
|
@ -98,7 +130,7 @@
|
|||
// RUN: -target x86_64-apple-darwin16 \
|
||||
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \
|
||||
// RUN: -resource-dir=%S/Inputs/resource_dir \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
|
||||
// RUN: -stdlib=platform \
|
||||
// RUN: -nostdinc++ \
|
||||
// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \
|
||||
|
@ -121,3 +153,26 @@
|
|||
// CHECK-LIBCXX-NOSTDLIBINC: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
|
||||
// CHECK-LIBCXX-NOSTDLIBINC-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
|
||||
// CHECK-LIBCXX-NOSTDLIBINC-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
|
||||
|
||||
// Make sure we explain that we considered a path but didn't add it when it
|
||||
// doesn't exist.
|
||||
//
|
||||
// RUN: %clang -no-canonical-prefixes %s -fsyntax-only -v 2>&1 \
|
||||
// RUN: -target x86_64-apple-darwin \
|
||||
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk \
|
||||
// RUN: -stdlib=libc++ \
|
||||
// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \
|
||||
// RUN: --check-prefix=CHECK-LIBCXX-MISSING-TOOLCHAIN %s
|
||||
// CHECK-LIBCXX-MISSING-TOOLCHAIN: ignoring nonexistent directory "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
|
||||
//
|
||||
// RUN: %clang -no-canonical-prefixes %s -fsyntax-only -v 2>&1 \
|
||||
// RUN: -target x86_64-apple-darwin \
|
||||
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \
|
||||
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_no_libcxx \
|
||||
// RUN: -stdlib=libc++ \
|
||||
// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \
|
||||
// RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \
|
||||
// RUN: --check-prefix=CHECK-LIBCXX-MISSING-BOTH %s
|
||||
// CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
|
||||
// CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[SYSROOT]]/usr/include/c++/v1"
|
||||
|
|
Loading…
Reference in New Issue