Two more Windows-related fixes:
- More enum signeness bitfield fixes (MSVC treats enums as signed).
- Fixed in Lex/HeaderSearch.cpp an unsafe copy between two
HeaderSearch::PerFileInfo entries in a common vector. The copy involved two
calls to getFileInfo() within the assignment; these calls could have
side-effects that enlarged the internal vector, and with MSVC this would
invalidate one of the values in the assignment.
Patch by Argiris Kirtzidis!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47536 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Lex/HeaderSearch.cpp b/Lex/HeaderSearch.cpp
index bd36f35..899c9d8 100644
--- a/Lex/HeaderSearch.cpp
+++ b/Lex/HeaderSearch.cpp
@@ -228,7 +228,22 @@
if (const FileEntry *FE = FileMgr.getFile(TmpDir.begin(), TmpDir.end())) {
// Leave CurDir unset.
// This file is a system header or C++ unfriendly if the old file is.
- getFileInfo(FE).DirInfo = getFileInfo(CurFileEnt).DirInfo;
+
+ // Note: Don't use:
+ //
+ // getFileInfo(FE).DirInfo = getFileInfo(CurFileEnt).DirInfo;
+ //
+ // MSVC, behind the scenes, does this:
+ //
+ // PerFileInfo &pf1 = getFileInfo(CurFileEnt);
+ // PerFileInfo &pf2 = getFileInfo(FE);
+ // pf2.DirInfo = pf1.DirInfo
+ //
+ // The problem is that if there's a resize() of the FileInfo vector during
+ // the getFileInfo(FE) call, pf1 will point to invalid data. To fix
+ // this problem, make the assignment through a temporary.
+ unsigned int tmp = getFileInfo(CurFileEnt).DirInfo;
+ getFileInfo(FE).DirInfo = tmp;
return FE;
}
}
@@ -357,7 +372,22 @@
}
// This file is a system header or C++ unfriendly if the old file is.
- getFileInfo(FE).DirInfo = getFileInfo(ContextFileEnt).DirInfo;
+
+ // Note: Don't use:
+ //
+ // getFileInfo(FE).DirInfo = getFileInfo(ContextFileEnt).DirInfo;
+ //
+ // MSVC, behind the scenes, does this:
+ //
+ // PerFileInfo &pf1 = getFileInfo(ContextFileEnt);
+ // PerFileInfo &pf2 = getFileInfo(FE);
+ // pf2.DirInfo = pf1.DirInfo
+ //
+ // The problem is that if there's a resize() of the FileInfo vector during
+ // the getFileInfo(FE) call, pf1 will point to invalid data. The solution
+ // is to make the assignment through a temporary.
+ unsigned int tmp = getFileInfo(ContextFileEnt).DirInfo;
+ getFileInfo(FE).DirInfo = tmp;
return FE;
}