[cfe-commits] r47536 - in /cfe/trunk: Lex/HeaderSearch.cpp include/clang/AST/Decl.h include/clang/AST/DeclObjC.h include/clang/AST/Type.h include/clang/Basic/IdentifierTable.h include/clang/Lex/DirectoryLookup.h include/clang/Lex/HeaderSearch.h include/clang/Parse/DeclSpec.h

Ted Kremenek kremenek at apple.com
Sat Feb 23 19:55:15 PST 2008


Author: kremenek
Date: Sat Feb 23 21:55:14 2008
New Revision: 47536

URL: http://llvm.org/viewvc/llvm-project?rev=47536&view=rev
Log:
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!

Modified:
    cfe/trunk/Lex/HeaderSearch.cpp
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Basic/IdentifierTable.h
    cfe/trunk/include/clang/Lex/DirectoryLookup.h
    cfe/trunk/include/clang/Lex/HeaderSearch.h
    cfe/trunk/include/clang/Parse/DeclSpec.h

Modified: cfe/trunk/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Lex/HeaderSearch.cpp?rev=47536&r1=47535&r2=47536&view=diff

==============================================================================
--- cfe/trunk/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/Lex/HeaderSearch.cpp Sat Feb 23 21:55:14 2008
@@ -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;
 }
 

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=47536&r1=47535&r2=47536&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Feb 23 21:55:14 2008
@@ -408,7 +408,9 @@
     : VarDecl(ParmVar, L, Id, T, S, PrevDecl), 
     objcDeclQualifier(OBJC_TQ_None) {}
   
-  ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
+  ObjCDeclQualifier getObjCDeclQualifier() const {
+    return ObjCDeclQualifier(objcDeclQualifier);
+  }
   void setObjCDeclQualifier(ObjCDeclQualifier QTVal) 
   { objcDeclQualifier = QTVal; }
     
@@ -417,9 +419,10 @@
   static bool classof(const ParmVarDecl *D) { return true; }
   
 private:
+  // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
   /// FIXME: Also can be paced into the bitfields in Decl.
   /// in, inout, etc.
-  ObjCDeclQualifier objcDeclQualifier : 6;
+  unsigned objcDeclQualifier : 6;
   
 protected:
   /// EmitImpl - Serialize this ParmVarDecl. Called by Decl::Emit.
@@ -474,7 +477,7 @@
   QualType getResultType() const { 
     return cast<FunctionType>(getType())->getResultType();
   }
-  StorageClass getStorageClass() const { return SClass; }
+  StorageClass getStorageClass() const { return StorageClass(SClass); }
   bool isInline() const { return IsInline; }
     
   // Implement isa/cast/dyncast/etc.
@@ -494,7 +497,8 @@
   /// function.
   ScopedDecl *DeclChain;
 
-  StorageClass SClass : 2;
+  // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
+  unsigned SClass : 2;
   bool IsInline : 1;
 
 protected:

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=47536&r1=47535&r2=47536&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Sat Feb 23 21:55:14 2008
@@ -58,11 +58,13 @@
   bool IsInstance : 1;
   bool IsVariadic : 1;
   
+  // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
   /// @required/@optional
-  ImplementationControl DeclImplementation : 2;
+  unsigned DeclImplementation : 2;
   
+  // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
   /// in, inout, etc.
-  ObjCDeclQualifier objcDeclQualifier : 6;
+  unsigned objcDeclQualifier : 6;
   
   // Context this method is declared in.
   NamedDecl *MethodContext;
@@ -104,7 +106,9 @@
     MethodAttrs(M), EndLoc(endLoc), Body(0), SelfDecl(0) {}
   virtual ~ObjCMethodDecl();
   
-  ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
+  ObjCDeclQualifier getObjCDeclQualifier() const {
+    return ObjCDeclQualifier(objcDeclQualifier);
+  }
   void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
   
   // Location information, modeled after the Stmt API.
@@ -149,7 +153,7 @@
     DeclImplementation = ic; 
   }
   ImplementationControl getImplementationControl() const { 
-    return DeclImplementation; 
+    return ImplementationControl(DeclImplementation); 
   }
   Stmt *const getBody() const { return Body; }
   void setBody(Stmt *B) { Body = B; }
@@ -365,13 +369,14 @@
     None, Private, Protected, Public, Package
   };
   void setAccessControl(AccessControl ac) { DeclAccess = ac; }
-  AccessControl getAccessControl() const { return DeclAccess; }
+  AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
   
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; }
   static bool classof(const ObjCIvarDecl *D) { return true; }
 private:
-  AccessControl DeclAccess : 3;
+  // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
+  unsigned DeclAccess : 3;
 };
 
 
@@ -873,8 +878,9 @@
   // FIXME: Property is not an ivar.
   ObjCIvarDecl **PropertyDecls;
   int NumPropertyDecls;
-  
-  PropertyAttributeKind PropertyAttributes : 8;
+
+  // NOTE: VC++ treats enums as signed, avoid using PropertyAttributeKind enum
+  unsigned PropertyAttributes : 8;
   
   IdentifierInfo *GetterName;    // getter name of NULL if no getter
   IdentifierInfo *SetterName;    // setter name of NULL if no setter
@@ -892,7 +898,7 @@
   void setNumPropertyDecls(int num) { NumPropertyDecls = num; }
   
   const PropertyAttributeKind getPropertyAttributes() const 
-    { return PropertyAttributes; }
+    { return PropertyAttributeKind(PropertyAttributes); }
   void setPropertyAttributes(PropertyAttributeKind PRVal) { 
     PropertyAttributes = 
     (PropertyAttributeKind) (PropertyAttributes | PRVal);

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=47536&r1=47535&r2=47536&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sat Feb 23 21:55:14 2008
@@ -552,8 +552,9 @@
   /// ElementType - The element type of the array.
   QualType ElementType;
   
+  // NOTE: VC++ treats enums as signed, avoid using the ArraySizeModifier enum
   /// NOTE: These fields are packed into the bitfields space in the Type class.
-  ArraySizeModifier SizeModifier : 2;
+  unsigned SizeModifier : 2;
   
   /// IndexTypeQuals - Capture qualifiers in declarations like:
   /// 'int X[static restrict 4]'. For function parameters only.
@@ -566,7 +567,9 @@
   friend class ASTContext;  // ASTContext creates these.
 public:
   QualType getElementType() const { return ElementType; }
-  ArraySizeModifier getSizeModifier() const { return SizeModifier; }
+  ArraySizeModifier getSizeModifier() const {
+    return ArraySizeModifier(SizeModifier);
+  }
   unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
   
   QualType getBaseType() const {

Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=47536&r1=47535&r2=47536&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Sat Feb 23 21:55:14 2008
@@ -40,7 +40,8 @@
   //       signed char and TokenKinds > 127 won't be handled correctly.
   unsigned TokenID            : 8; // Front-end token ID or tok::identifier. 
   unsigned BuiltinID          : 9; // ID if this is a builtin (__builtin_inf).
-  tok::ObjCKeywordKind ObjCID : 5; // ID for objc @ keyword like @'protocol'.
+  // NOTE: VC++ treats enums as signed, avoid using tok::ObjCKeywordKind enum
+  unsigned ObjCID             : 5; // ID for objc @ keyword like @'protocol'.
   bool HasMacro               : 1; // True if there is a #define for this.
   bool IsExtension            : 1; // True if identifier is a lang extension.
   bool IsPoisoned             : 1; // True if identifier is poisoned.
@@ -91,7 +92,9 @@
   /// getObjCKeywordID - Return the Objective-C keyword ID for the this
   /// identifier.  For example, 'class' will return tok::objc_class if ObjC is
   /// enabled.
-  tok::ObjCKeywordKind getObjCKeywordID() const { return ObjCID; }
+  tok::ObjCKeywordKind getObjCKeywordID() const {
+    return tok::ObjCKeywordKind(ObjCID);
+  }
   void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCID = ID; }
   
   /// getBuiltinID - Return a value indicating whether this is a builtin

Modified: cfe/trunk/include/clang/Lex/DirectoryLookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/DirectoryLookup.h?rev=47536&r1=47535&r2=47536&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/DirectoryLookup.h (original)
+++ cfe/trunk/include/clang/Lex/DirectoryLookup.h Sat Feb 23 21:55:14 2008
@@ -48,9 +48,10 @@
     const HeaderMap *Map;
   } u;
   
+  // NOTE: VC++ treats enums as signed, avoid using the DirType enum
   /// DirCharacteristic - The type of directory this is, one of the DirType enum
   /// values.
-  DirType DirCharacteristic : 2;
+  unsigned DirCharacteristic : 2;
   
   /// UserSupplied - True if this is a user-supplied directory.
   ///
@@ -110,7 +111,7 @@
   
   /// DirCharacteristic - The type of directory this is, one of the DirType enum
   /// values.
-  DirType getDirCharacteristic() const { return DirCharacteristic; }
+  DirType getDirCharacteristic() const { return DirType(DirCharacteristic); }
   
   /// isUserSupplied - True if this is a user-supplied directory.
   ///

Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=47536&r1=47535&r2=47536&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)
+++ cfe/trunk/include/clang/Lex/HeaderSearch.h Sat Feb 23 21:55:14 2008
@@ -45,10 +45,11 @@
     /// isImport - True if this is a #import'd or #pragma once file.
     bool isImport : 1;
     
+    // NOTE: VC++ treats enums as signed, avoid using DirectoryLookup::DirType
     /// DirInfo - Keep track of whether this is a system header, and if so,
     /// whether it is C++ clean or not.  This can be set by the include paths or
     /// by #pragma gcc system_header.
-    DirectoryLookup::DirType DirInfo : 2;
+    unsigned DirInfo : 2;
     
     /// NumIncludes - This is the number of times the file has been included
     /// already.
@@ -155,7 +156,7 @@
   /// getFileDirFlavor - Return whether the specified file is a normal header,
   /// a system header, or a C++ friendly system header.
   DirectoryLookup::DirType getFileDirFlavor(const FileEntry *File) {
-    return getFileInfo(File).DirInfo;
+    return DirectoryLookup::DirType(getFileInfo(File).DirInfo);
   }
     
   /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=47536&r1=47535&r2=47536&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Sat Feb 23 21:55:14 2008
@@ -330,7 +330,7 @@
     { objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal); }
   
   const ObjCPropertyAttributeKind getPropertyAttributes() const 
-    { return PropertyAttributes; }
+    { return ObjCPropertyAttributeKind(PropertyAttributes); }
   void setPropertyAttributes(ObjCPropertyAttributeKind PRVal) { 
     PropertyAttributes = 
       (ObjCPropertyAttributeKind) (PropertyAttributes | PRVal);
@@ -349,7 +349,8 @@
   // (space saving is negligible).
   ObjCDeclQualifier objcDeclQualifier : 6;
   
-  ObjCPropertyAttributeKind PropertyAttributes : 8;
+  // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
+  unsigned PropertyAttributes : 8;
   IdentifierInfo *GetterName;    // getter name of NULL if no getter
   IdentifierInfo *SetterName;    // setter name of NULL if no setter
 };





More information about the cfe-commits mailing list