Skip to content

Commit 7ca8c21

Browse files
authored
[Driver] Fix detection of libc++ with empty sysroot. (#66947)
b1e3cd1 dropped the leading slash here, presumably unintentionally. (I don't understand Driver well enough to know how/where this is supposed to be tested, but it broke clangd on any project that uses the system-installed -stdlib=libc++ on a standard debian install)
1 parent 4a55d42 commit 7ca8c21

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

clang/lib/Driver/ToolChains/Gnu.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3100,6 +3100,8 @@ Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
31003100
llvm::opt::ArgStringList &CC1Args) const {
31013101
const Driver &D = getDriver();
31023102
std::string SysRoot = computeSysRoot();
3103+
if (SysRoot.empty())
3104+
SysRoot = llvm::sys::path::get_separator();
31033105

31043106
auto AddIncludePath = [&](StringRef Path, bool TargetDirRequired = false) {
31053107
std::string Version = detectLibcxxVersion(Path);

clang/unittests/Driver/ToolChainTest.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
#include "clang/Driver/Driver.h"
2020
#include "clang/Frontend/CompilerInstance.h"
2121
#include "llvm/ADT/ArrayRef.h"
22+
#include "llvm/ADT/StringExtras.h"
2223
#include "llvm/MC/TargetRegistry.h"
2324
#include "llvm/Support/TargetSelect.h"
2425
#include "llvm/Support/VirtualFileSystem.h"
2526
#include "llvm/Support/raw_ostream.h"
27+
#include "gmock/gmock.h"
2628
#include "gtest/gtest.h"
2729
#include <memory>
2830

@@ -316,6 +318,52 @@ TEST(ToolChainTest, VFSSolarisMultiGCCInstallation) {
316318
}
317319
}
318320

321+
MATCHER_P(jobHasArgs, Substr, "") {
322+
const driver::Command &C = arg;
323+
std::string Args = "";
324+
llvm::ListSeparator Sep(" ");
325+
for (const char *Arg : C.getArguments()) {
326+
Args += Sep;
327+
Args += Arg;
328+
}
329+
if (is_style_windows(llvm::sys::path::Style::native))
330+
std::replace(Args.begin(), Args.end(), '\\', '/');
331+
if (llvm::StringRef(Args).contains(Substr))
332+
return true;
333+
*result_listener << "whose args are '" << Args << "'";
334+
return false;
335+
}
336+
337+
TEST(ToolChainTest, VFSGnuLibcxxPathNoSysroot) {
338+
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
339+
340+
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
341+
struct TestDiagnosticConsumer : public DiagnosticConsumer {};
342+
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
343+
new llvm::vfs::InMemoryFileSystem);
344+
345+
const char *EmptyFiles[] = {
346+
"foo.cpp",
347+
"/bin/clang",
348+
"/usr/include/c++/v1/cstdio",
349+
};
350+
351+
for (const char *Path : EmptyFiles)
352+
InMemoryFileSystem->addFile(Path, 0,
353+
llvm::MemoryBuffer::getMemBuffer("\n"));
354+
355+
{
356+
DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
357+
Driver TheDriver("/bin/clang", "x86_64-unknown-linux-gnu", Diags,
358+
"clang LLVM compiler", InMemoryFileSystem);
359+
std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
360+
{"/bin/clang", "-fsyntax-only", "-stdlib=libc++", "foo.cpp"}));
361+
ASSERT_TRUE(C);
362+
EXPECT_THAT(C->getJobs(), testing::ElementsAre(jobHasArgs(
363+
"-internal-isystem /usr/include/c++/v1")));
364+
}
365+
}
366+
319367
TEST(ToolChainTest, DefaultDriverMode) {
320368
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
321369

0 commit comments

Comments
 (0)