diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index c21c221b5c5b..ce2aeccb9044 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -144,7 +144,7 @@ namespace SrcMgr { FileInfo X; X.IncludeLoc = IL.getRawEncoding(); X.Data = (uintptr_t)Con; - assert((X.Data & 3) == 0 &&"ContentCache pointer insufficiently aligned"); + assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned"); assert((unsigned)FileCharacter < 4 && "invalid file character"); X.Data |= (unsigned)FileCharacter; return X; @@ -154,7 +154,7 @@ namespace SrcMgr { return SourceLocation::getFromRawEncoding(IncludeLoc); } const ContentCache* getContentCache() const { - return reinterpret_cast(Data & ~3UL); + return reinterpret_cast(Data & ~7UL); } /// getCharacteristic - Return whether this is a system header or not. diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 191b6155f095..6f78ee175c62 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -160,8 +160,12 @@ SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) { ContentCache *&Entry = FileInfos[FileEnt]; if (Entry) return Entry; - // Nope, create a new Cache entry. - Entry = ContentCacheAlloc.Allocate(); + // Nope, create a new Cache entry. Make sure it is at least 8-byte aligned + // so that FileInfo can use the low 3 bits of the pointer for its own + // nefarious purposes. + unsigned EntryAlign = llvm::AlignOf::Alignment; + EntryAlign = std::max(8U, EntryAlign); + Entry = ContentCacheAlloc.Allocate(1, EntryAlign); new (Entry) ContentCache(FileEnt); return Entry; } @@ -171,11 +175,12 @@ SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) { /// memory buffer. This does no caching. const ContentCache* SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) { - // Add a new ContentCache to the MemBufferInfos list and return it. We - // must default construct the object first that the instance actually - // stored within MemBufferInfos actually owns the Buffer, and not any - // temporary we would use in the call to "push_back". - ContentCache *Entry = ContentCacheAlloc.Allocate(); + // Add a new ContentCache to the MemBufferInfos list and return it. Make sure + // it is at least 8-byte aligned so that FileInfo can use the low 3 bits of + // the pointer for its own nefarious purposes. + unsigned EntryAlign = llvm::AlignOf::Alignment; + EntryAlign = std::max(8U, EntryAlign); + ContentCache *Entry = ContentCacheAlloc.Allocate(1, EntryAlign); new (Entry) ContentCache(); MemBufferInfos.push_back(Entry); Entry->setBuffer(Buffer);