diff options
author | Ben Langmuir <blangmuir@apple.com> | 2014-09-08 16:15:54 +0000 |
---|---|---|
committer | Ben Langmuir <blangmuir@apple.com> | 2014-09-08 16:15:54 +0000 |
commit | ab86fbe4250bf81f46025f9d1b50dfa1c07da9c5 (patch) | |
tree | ee3aeedce154c896f466f936fbe405b550ba736d /clang/lib/Basic/FileManager.cpp | |
parent | dfa274eb58a6fed420e98a652b1e72a88aed85a6 (diff) | |
download | bcm5719-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/FileManager.cpp')
-rw-r--r-- | clang/lib/Basic/FileManager.cpp | 17 |
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; |