[llvm-cov] Get rid of all invalid filename references
We used to append filenames into a vector of std::string, and then
append a reference to each string into a separate vector. This made it
easier to work with the getUniqueSourceFiles API. But it's buggy.
std::string has a small-string optimization, so you can't expect to
capture a reference to one if you're copying it into a growing vector.
Add a test that triggers this invalid reference to std::string scenario,
and kill the issue with fire by just using ArrayRef<std::string>
everywhere.
llvm-svn: 282281
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index 237d877..51ac6ef 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -64,7 +64,8 @@
/// \brief Print the warning message to the error output stream.
void warning(const Twine &Message, StringRef Whence = "");
- /// \brief Copy \p Path into the list of input source files.
+ /// \brief Convert \p Path into an absolute path and append it to the list
+ /// of collected paths.
void addCollectedPath(const std::string &Path);
/// \brief If \p Path is a regular file, collect the path. If it's a
@@ -116,7 +117,7 @@
std::string PGOFilename;
/// A list of input source files.
- std::vector<StringRef> SourceFiles;
+ std::vector<std::string> SourceFiles;
/// Whether or not we're in -filename-equivalence mode.
bool CompareFilenamesOnly;
@@ -131,9 +132,6 @@
/// A cache for demangled symbol names.
StringMap<std::string> DemangledNames;
- /// File paths (absolute, or otherwise) to input source files.
- std::vector<std::string> CollectedPaths;
-
/// Errors and warnings which have not been printed.
std::mutex ErrsLock;
@@ -168,7 +166,7 @@
void CodeCoverageTool::addCollectedPath(const std::string &Path) {
if (CompareFilenamesOnly) {
- CollectedPaths.push_back(Path);
+ SourceFiles.emplace_back(Path);
} else {
SmallString<128> EffectivePath(Path);
if (std::error_code EC = sys::fs::make_absolute(EffectivePath)) {
@@ -176,10 +174,8 @@
return;
}
sys::path::remove_dots(EffectivePath, /*remove_dot_dots=*/true);
- CollectedPaths.push_back(EffectivePath.str());
+ SourceFiles.emplace_back(EffectivePath.str());
}
-
- SourceFiles.emplace_back(CollectedPaths.back());
}
void CodeCoverageTool::collectPaths(const std::string &Path) {
@@ -597,7 +593,7 @@
collectPaths(File);
if (DebugDumpCollectedPaths) {
- for (StringRef SF : SourceFiles)
+ for (const std::string &SF : SourceFiles)
outs() << SF << '\n';
::exit(0);
}
@@ -751,11 +747,11 @@
ThreadCount = std::thread::hardware_concurrency();
ThreadPool Pool(ThreadCount);
- for (StringRef SourceFile : SourceFiles) {
- Pool.async([this, SourceFile, &Coverage, &Printer, ShowFilenames] {
+ for (const std::string &SourceFile : SourceFiles) {
+ Pool.async([this, &SourceFile, &Coverage, &Printer, ShowFilenames] {
auto View = createSourceFileView(SourceFile, *Coverage);
if (!View) {
- warning("The file '" + SourceFile.str() + "' isn't covered.");
+ warning("The file '" + SourceFile + "' isn't covered.");
return;
}