summaryrefslogtreecommitdiffstats
path: root/clang/lib/Basic
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2014-09-08 16:15:54 +0000
committerBen Langmuir <blangmuir@apple.com>2014-09-08 16:15:54 +0000
commitab86fbe4250bf81f46025f9d1b50dfa1c07da9c5 (patch)
treeee3aeedce154c896f466f936fbe405b550ba736d /clang/lib/Basic
parentdfa274eb58a6fed420e98a652b1e72a88aed85a6 (diff)
downloadbcm5719-llvm-ab86fbe4250bf81f46025f9d1b50dfa1c07da9c5.tar.gz
bcm5719-llvm-ab86fbe4250bf81f46025f9d1b50dfa1c07da9c5.zip
Make FileEntry::getName() valid across calls to FileManager::getFile()
Because we may change the name of a FileEntry inside getFile, the name returned by FileEntry::getName() could be destroyed. This was causing a use-after-free when searching the HeaderFileInfo on-disk hashtable for a module or pch. llvm-svn: 217385
Diffstat (limited to 'clang/lib/Basic')
-rw-r--r--clang/lib/Basic/FileManager.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp
index c0522966e38..87844864a85 100644
--- a/clang/lib/Basic/FileManager.cpp
+++ b/clang/lib/Basic/FileManager.cpp
@@ -270,6 +270,19 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
FileEntry &UFE = UniqueRealFiles[Data.UniqueID];
NamedFileEnt.setValue(&UFE);
+
+ // If the name returned by getStatValue is different than Filename, re-intern
+ // the name.
+ if (Data.Name != Filename) {
+ auto &NamedFileEnt = SeenFileEntries.GetOrCreateValue(Data.Name);
+ if (!NamedFileEnt.getValue())
+ NamedFileEnt.setValue(&UFE);
+ else
+ assert(NamedFileEnt.getValue() == &UFE &&
+ "filename from getStatValue() refers to wrong file");
+ InterndFileName = NamedFileEnt.getKeyData();
+ }
+
if (UFE.isValid()) { // Already have an entry with this inode, return it.
// FIXME: this hack ensures that if we look up a file by a virtual path in
@@ -286,13 +299,13 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// to switch towards a design where we return a FileName object that
// encapsulates both the name by which the file was accessed and the
// corresponding FileEntry.
- UFE.Name = Data.Name;
+ UFE.Name = InterndFileName;
return &UFE;
}
// Otherwise, we don't have this file yet, add it.
- UFE.Name = Data.Name;
+ UFE.Name = InterndFileName;
UFE.Size = Data.Size;
UFE.ModTime = Data.ModTime;
UFE.Dir = DirInfo;
OpenPOWER on IntegriCloud