[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