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;
 }