`Issue 57516 <https://github.com/llvm/llvm-project/issues/57516>`_
- Fix ``__builtin_assume_aligned`` crash when the 1st arg is array type. This fixes
`Issue 57169 <https://github.com/llvm/llvm-project/issues/57169>`_
+- Clang configuration files are now read through the virtual file system
+ rather than the physical one, if these are different.
Improvements to Clang's diagnostics
/// by Dirs.
///
static bool searchForFile(SmallVectorImpl<char> &FilePath,
- ArrayRef<StringRef> Dirs, StringRef FileName) {
+ ArrayRef<StringRef> Dirs, StringRef FileName,
+ llvm::vfs::FileSystem &FS) {
SmallString<128> WPath;
for (const StringRef &Dir : Dirs) {
if (Dir.empty())
WPath.clear();
llvm::sys::path::append(WPath, Dir, FileName);
llvm::sys::path::native(WPath);
- if (llvm::sys::fs::is_regular_file(WPath)) {
+ auto Status = FS.status(WPath);
+ if (Status && Status->getType() == llvm::sys::fs::file_type::regular_file) {
FilePath = std::move(WPath);
return true;
}
bool Driver::readConfigFile(StringRef FileName) {
// Try reading the given file.
SmallVector<const char *, 32> NewCfgArgs;
- if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) {
+ if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs, getVFS())) {
Diag(diag::err_drv_cannot_read_config_file) << FileName;
return true;
}
SmallString<128> CfgDir;
CfgDir.append(
CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
- if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+ if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
SystemConfigDir.clear();
else
SystemConfigDir = static_cast<std::string>(CfgDir);
SmallString<128> CfgDir;
CfgDir.append(
CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ));
- if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+ if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
UserConfigDir.clear();
else
UserConfigDir = static_cast<std::string>(CfgDir);
// If argument contains directory separator, treat it as a path to
// configuration file.
if (llvm::sys::path::has_parent_path(CfgFileName)) {
- SmallString<128> CfgFilePath;
- if (llvm::sys::path::is_relative(CfgFileName))
- llvm::sys::fs::current_path(CfgFilePath);
- llvm::sys::path::append(CfgFilePath, CfgFileName);
- if (!llvm::sys::fs::is_regular_file(CfgFilePath)) {
- Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
- return true;
+ SmallString<128> CfgFilePath(CfgFileName);
+ if (llvm::sys::path::is_relative(CfgFilePath)) {
+ if (getVFS().makeAbsolute(CfgFilePath))
+ return true;
+ auto Status = getVFS().status(CfgFilePath);
+ if (!Status ||
+ Status->getType() != llvm::sys::fs::file_type::regular_file) {
+ Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
+ return true;
+ }
}
return readConfigFile(CfgFilePath);
}
// Try to find config file. First try file with corrected architecture.
llvm::SmallString<128> CfgFilePath;
if (!FixedConfigFile.empty()) {
- if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile))
+ if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile,
+ getVFS()))
return readConfigFile(CfgFilePath);
// If 'x86_64-clang.cfg' was not found, try 'x86_64.cfg'.
FixedConfigFile.resize(FixedArchPrefixLen);
FixedConfigFile.append(".cfg");
- if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile))
+ if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile,
+ getVFS()))
return readConfigFile(CfgFilePath);
}
// Then try original file name.
- if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName))
+ if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS()))
return readConfigFile(CfgFilePath);
// Finally try removing driver mode part: 'x86_64-clang.cfg' -> 'x86_64.cfg'.
!ClangNameParts.TargetPrefix.empty()) {
CfgFileName.assign(ClangNameParts.TargetPrefix);
CfgFileName.append(".cfg");
- if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName))
+ if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS()))
return readConfigFile(CfgFilePath);
}
}
}
+TEST(ToolChainTest, ConfigFileSearch) {
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+ struct TestDiagnosticConsumer : public DiagnosticConsumer {};
+ DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+ IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
+ new llvm::vfs::InMemoryFileSystem);
+
+#ifdef _WIN32
+ const char *TestRoot = "C:\\";
+#else
+ const char *TestRoot = "/";
+#endif
+ FS->setCurrentWorkingDirectory(TestRoot);
+
+ FS->addFile(
+ "/opt/sdk/root.cfg", 0,
+ llvm::MemoryBuffer::getMemBuffer("--sysroot=/opt/sdk/platform0\n"));
+ FS->addFile(
+ "/home/test/sdk/root.cfg", 0,
+ llvm::MemoryBuffer::getMemBuffer("--sysroot=/opt/sdk/platform1\n"));
+ FS->addFile(
+ "/home/test/bin/root.cfg", 0,
+ llvm::MemoryBuffer::getMemBuffer("--sysroot=/opt/sdk/platform2\n"));
+
+ {
+ Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
+ "clang LLVM compiler", FS);
+ std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
+ {"/home/test/bin/clang", "--config", "root.cfg",
+ "--config-system-dir=/opt/sdk", "--config-user-dir=/home/test/sdk"}));
+ ASSERT_TRUE(C);
+ ASSERT_FALSE(C->containsError());
+ EXPECT_EQ("/opt/sdk/platform1", TheDriver.SysRoot);
+ }
+ {
+ Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
+ "clang LLVM compiler", FS);
+ std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
+ {"/home/test/bin/clang", "--config", "root.cfg",
+ "--config-system-dir=/opt/sdk", "--config-user-dir="}));
+ ASSERT_TRUE(C);
+ ASSERT_FALSE(C->containsError());
+ EXPECT_EQ("/opt/sdk/platform0", TheDriver.SysRoot);
+ }
+ {
+ Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
+ "clang LLVM compiler", FS);
+ std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
+ {"/home/test/bin/clang", "--config", "root.cfg",
+ "--config-system-dir=", "--config-user-dir="}));
+ ASSERT_TRUE(C);
+ ASSERT_FALSE(C->containsError());
+ EXPECT_EQ("/opt/sdk/platform2", TheDriver.SysRoot);
+ }
+}
+
} // end anonymous namespace.
/// current config file.
///
bool readConfigFile(StringRef CfgFileName, StringSaver &Saver,
- SmallVectorImpl<const char *> &Argv);
+ SmallVectorImpl<const char *> &Argv,
+ llvm::vfs::FileSystem &FS);
/// Expand response files on a command line recursively using the given
/// StringSaver and tokenization strategy. Argv should contain the command line
/// the current response file.
/// \param [in] FS File system used for all file access when running the tool.
/// \param [in] CurrentDir Path used to resolve relative rsp files. If set to
-/// None, process' cwd is used instead.
+/// None, the file system current directory is used instead.
/// \return true if all @files were expanded successfully or there were none.
bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
SmallVectorImpl<const char *> &Argv, bool MarkEOLs,
// always have an absolute path deduced from the containing file.
SmallString<128> CurrDir;
if (llvm::sys::path::is_relative(FName)) {
- if (!CurrentDir)
- llvm::sys::fs::current_path(CurrDir);
- else
+ if (!CurrentDir) {
+ if (auto CWD = FS.getCurrentWorkingDirectory()) {
+ CurrDir = *CWD;
+ } else {
+ // TODO: The error should be propagated up the stack.
+ llvm::consumeError(llvm::errorCodeToError(CWD.getError()));
+ return false;
+ }
+ } else {
CurrDir = *CurrentDir;
+ }
llvm::sys::path::append(CurrDir, FName);
FName = CurrDir.c_str();
}
}
bool cl::readConfigFile(StringRef CfgFile, StringSaver &Saver,
- SmallVectorImpl<const char *> &Argv) {
+ SmallVectorImpl<const char *> &Argv,
+ llvm::vfs::FileSystem &FS) {
SmallString<128> AbsPath;
if (sys::path::is_relative(CfgFile)) {
- llvm::sys::fs::current_path(AbsPath);
- llvm::sys::path::append(AbsPath, CfgFile);
+ AbsPath.assign(CfgFile);
+ if (std::error_code EC = FS.makeAbsolute(AbsPath))
+ return false;
CfgFile = AbsPath.str();
}
- if (llvm::Error Err = ExpandResponseFile(
- CfgFile, Saver, cl::tokenizeConfigFile, Argv,
- /*MarkEOLs=*/false, /*RelativeNames=*/true, /*ExpandBasePath=*/true,
- *llvm::vfs::getRealFileSystem())) {
+ if (llvm::Error Err =
+ ExpandResponseFile(CfgFile, Saver, cl::tokenizeConfigFile, Argv,
+ /*MarkEOLs=*/false, /*RelativeNames=*/true,
+ /*ExpandBasePath=*/true, FS)) {
// TODO: The error should be propagated up the stack.
llvm::consumeError(std::move(Err));
return false;
}
return ExpandResponseFiles(Saver, cl::tokenizeConfigFile, Argv,
/*MarkEOLs=*/false, /*RelativeNames=*/true,
- /*ExpandBasePath=*/true, llvm::None);
+ /*ExpandBasePath=*/true, llvm::None, FS);
}
static void initCommonOptions();