Index: cfe/trunk/lib/CodeGen/CGClass.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGClass.cpp +++ cfe/trunk/lib/CodeGen/CGClass.cpp @@ -2423,7 +2423,8 @@ VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy); llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); - CGM.DecorateInstructionWithTBAA(Store, CGM.getTBAAVTablePtrAccessInfo()); + TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTablePtrTy); + CGM.DecorateInstructionWithTBAA(Store, TBAAInfo); if (CGM.getCodeGenOpts().OptimizationLevel > 0 && CGM.getCodeGenOpts().StrictVTablePointers) CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.VTableClass); @@ -2517,7 +2518,8 @@ const CXXRecordDecl *RD) { Address VTablePtrSrc = Builder.CreateElementBitCast(This, VTableTy); llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); - CGM.DecorateInstructionWithTBAA(VTable, CGM.getTBAAVTablePtrAccessInfo()); + TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy); + CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo); if (CGM.getCodeGenOpts().OptimizationLevel > 0 && CGM.getCodeGenOpts().StrictVTablePointers) Index: cfe/trunk/lib/CodeGen/CodeGenModule.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.h +++ cfe/trunk/lib/CodeGen/CodeGenModule.h @@ -664,7 +664,7 @@ /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an /// access to a virtual table pointer. - TBAAAccessInfo getTBAAVTablePtrAccessInfo(); + TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType); llvm::MDNode *getTBAAStructInfo(QualType QTy); Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp @@ -136,7 +136,7 @@ // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0. if (LangOpts.Sanitize.has(SanitizerKind::Thread) || (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) - TBAA.reset(new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(), + TBAA.reset(new CodeGenTBAA(Context, TheModule, CodeGenOpts, getLangOpts(), getCXXABI().getMangleContext())); // If debug info or coverage generation is enabled, create the CGDebugInfo @@ -579,13 +579,20 @@ } TBAAAccessInfo CodeGenModule::getTBAAAccessInfo(QualType AccessType) { - return TBAAAccessInfo(getTBAATypeInfo(AccessType)); + // Pointee values may have incomplete types, but they shall never be + // dereferenced. + if (AccessType->isIncompleteType()) + return TBAAAccessInfo::getIncompleteInfo(); + + uint64_t Size = Context.getTypeSizeInChars(AccessType).getQuantity(); + return TBAAAccessInfo(getTBAATypeInfo(AccessType), Size); } -TBAAAccessInfo CodeGenModule::getTBAAVTablePtrAccessInfo() { +TBAAAccessInfo +CodeGenModule::getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType) { if (!TBAA) return TBAAAccessInfo(); - return TBAA->getVTablePtrAccessInfo(); + return TBAA->getVTablePtrAccessInfo(VTablePtrType); } llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) { Index: cfe/trunk/lib/CodeGen/CodeGenTBAA.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenTBAA.h +++ cfe/trunk/lib/CodeGen/CodeGenTBAA.h @@ -36,40 +36,53 @@ enum class TBAAAccessKind : unsigned { Ordinary, MayAlias, + Incomplete, }; // TBAAAccessInfo - Describes a memory access in terms of TBAA. struct TBAAAccessInfo { TBAAAccessInfo(TBAAAccessKind Kind, llvm::MDNode *BaseType, - llvm::MDNode *AccessType, uint64_t Offset) - : Kind(Kind), BaseType(BaseType), AccessType(AccessType), Offset(Offset) + llvm::MDNode *AccessType, uint64_t Offset, uint64_t Size) + : Kind(Kind), BaseType(BaseType), AccessType(AccessType), + Offset(Offset), Size(Size) {} TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType, - uint64_t Offset) - : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, Offset) + uint64_t Offset, uint64_t Size) + : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, + Offset, Size) {} - explicit TBAAAccessInfo(llvm::MDNode *AccessType) - : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0) + explicit TBAAAccessInfo(llvm::MDNode *AccessType, uint64_t Size) + : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0, Size) {} TBAAAccessInfo() - : TBAAAccessInfo(/* AccessType= */ nullptr) + : TBAAAccessInfo(/* AccessType= */ nullptr, /* Size= */ 0) {} static TBAAAccessInfo getMayAliasInfo() { - return TBAAAccessInfo(TBAAAccessKind::MayAlias, /* BaseType= */ nullptr, - /* AccessType= */ nullptr, /* Offset= */ 0); + return TBAAAccessInfo(TBAAAccessKind::MayAlias, + /* BaseType= */ nullptr, /* AccessType= */ nullptr, + /* Offset= */ 0, /* Size= */ 0); } bool isMayAlias() const { return Kind == TBAAAccessKind::MayAlias; } + static TBAAAccessInfo getIncompleteInfo() { + return TBAAAccessInfo(TBAAAccessKind::Incomplete, + /* BaseType= */ nullptr, /* AccessType= */ nullptr, + /* Offset= */ 0, /* Size= */ 0); + } + + bool isIncomplete() const { return Kind == TBAAAccessKind::Incomplete; } + bool operator==(const TBAAAccessInfo &Other) const { return Kind == Other.Kind && BaseType == Other.BaseType && AccessType == Other.AccessType && - Offset == Other.Offset; + Offset == Other.Offset && + Size == Other.Size; } bool operator!=(const TBAAAccessInfo &Other) const { @@ -95,12 +108,16 @@ /// Offset - The byte offset of the final access within the base one. Must be /// zero if the base access type is not specified. uint64_t Offset; + + /// Size - The size of access, in bytes. + uint64_t Size; }; /// CodeGenTBAA - This class organizes the cross-module state that is used /// while lowering AST types to LLVM types. class CodeGenTBAA { ASTContext &Context; + llvm::Module &Module; const CodeGenOptions &CodeGenOpts; const LangOptions &Features; MangleContext &MContext; @@ -138,10 +155,10 @@ SmallVectorImpl &Fields, bool MayAlias); - /// A wrapper function to create a scalar type. For struct-path aware TBAA, - /// the scalar type has the same format as the struct type: name, offset, - /// pointer to another node in the type DAG. - llvm::MDNode *createTBAAScalarType(StringRef Name, llvm::MDNode *Parent); + /// createScalarTypeNode - A wrapper function to create a metadata node + /// describing a scalar type. + llvm::MDNode *createScalarTypeNode(StringRef Name, llvm::MDNode *Parent, + uint64_t Size); /// getTypeInfoHelper - An internal helper function to generate metadata used /// to describe accesses to objects of the given type. @@ -152,10 +169,8 @@ llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty); public: - CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext, - const CodeGenOptions &CGO, - const LangOptions &Features, - MangleContext &MContext); + CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO, + const LangOptions &Features, MangleContext &MContext); ~CodeGenTBAA(); /// getTypeInfo - Get metadata used to describe accesses to objects of the @@ -164,7 +179,7 @@ /// getVTablePtrAccessInfo - Get the TBAA information that describes an /// access to a virtual table pointer. - TBAAAccessInfo getVTablePtrAccessInfo(); + TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType); /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of /// the given type. @@ -200,6 +215,7 @@ static_cast(UnsignedKey), DenseMapInfo::getEmptyKey(), DenseMapInfo::getEmptyKey(), + DenseMapInfo::getEmptyKey(), DenseMapInfo::getEmptyKey()); } @@ -209,6 +225,7 @@ static_cast(UnsignedKey), DenseMapInfo::getTombstoneKey(), DenseMapInfo::getTombstoneKey(), + DenseMapInfo::getTombstoneKey(), DenseMapInfo::getTombstoneKey()); } @@ -217,7 +234,8 @@ return DenseMapInfo::getHashValue(KindValue) ^ DenseMapInfo::getHashValue(Val.BaseType) ^ DenseMapInfo::getHashValue(Val.AccessType) ^ - DenseMapInfo::getHashValue(Val.Offset); + DenseMapInfo::getHashValue(Val.Offset) ^ + DenseMapInfo::getHashValue(Val.Size); } static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS, Index: cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp +++ cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp @@ -25,16 +25,18 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" #include "llvm/IR/Type.h" using namespace clang; using namespace CodeGen; -CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext& VMContext, +CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO, const LangOptions &Features, MangleContext &MContext) - : Context(Ctx), CodeGenOpts(CGO), Features(Features), MContext(MContext), - MDHelper(VMContext), Root(nullptr), Char(nullptr) { -} + : Context(Ctx), Module(M), CodeGenOpts(CGO), + Features(Features), MContext(MContext), MDHelper(M.getContext()), + Root(nullptr), Char(nullptr) +{} CodeGenTBAA::~CodeGenTBAA() { } @@ -54,10 +56,10 @@ return Root; } -// For both scalar TBAA and struct-path aware TBAA, the scalar type has the -// same format: name, parent node, and offset. -llvm::MDNode *CodeGenTBAA::createTBAAScalarType(StringRef Name, - llvm::MDNode *Parent) { +llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name, + llvm::MDNode *Parent, + uint64_t Size) { + (void)Size; // TODO: Support generation of size-aware type nodes. return MDHelper.createTBAAScalarTypeNode(Name, Parent); } @@ -67,7 +69,7 @@ // these special powers only cover user-accessible memory, and doesn't // include things like vtables. if (!Char) - Char = createTBAAScalarType("omnipotent char", getRoot()); + Char = createScalarTypeNode("omnipotent char", getRoot(), /* Size= */ 1); return Char; } @@ -108,6 +110,8 @@ } llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { + uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity(); + // Handle builtin types. if (const BuiltinType *BTy = dyn_cast(Ty)) { switch (BTy->getKind()) { @@ -138,7 +142,7 @@ // treating wchar_t, char16_t, and char32_t as distinct from their // "underlying types". default: - return createTBAAScalarType(BTy->getName(Features), getChar()); + return createScalarTypeNode(BTy->getName(Features), getChar(), Size); } } @@ -152,7 +156,7 @@ // TODO: Implement C++'s type "similarity" and consider dis-"similar" // pointers distinct. if (Ty->isPointerType() || Ty->isReferenceType()) - return createTBAAScalarType("any pointer", getChar()); + return createScalarTypeNode("any pointer", getChar(), Size); // Enum types are distinct types. In C++ they have "underlying types", // however they aren't related for TBAA. @@ -167,7 +171,7 @@ SmallString<256> OutName; llvm::raw_svector_ostream Out(OutName); MContext.mangleTypeName(QualType(ETy, 0), Out); - return createTBAAScalarType(OutName, getChar()); + return createScalarTypeNode(OutName, getChar(), Size); } // For now, handle any other kind of type conservatively. @@ -204,8 +208,11 @@ return MetadataCache[Ty] = TypeNode; } -TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo() { - return TBAAAccessInfo(createTBAAScalarType("vtable pointer", getRoot())); +TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo(llvm::Type *VTablePtrType) { + llvm::DataLayout DL(&Module); + unsigned Size = DL.getPointerTypeSize(VTablePtrType); + return TBAAAccessInfo(createScalarTypeNode("vtable pointer", getRoot(), Size), + Size); } bool @@ -245,7 +252,7 @@ uint64_t Offset = BaseOffset; uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity(); llvm::MDNode *TBAAType = MayAlias ? getChar() : getTypeInfo(QTy); - llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType)); + llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType, Size)); Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); return true; } @@ -268,19 +275,20 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) { if (auto *TTy = dyn_cast(Ty)) { const RecordDecl *RD = TTy->getDecl()->getDefinition(); - const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); - SmallVector , 4> Fields; - unsigned idx = 0; - for (RecordDecl::field_iterator i = RD->field_begin(), - e = RD->field_end(); i != e; ++i, ++idx) { - QualType FieldQTy = i->getType(); - llvm::MDNode *FieldNode = isValidBaseType(FieldQTy) ? + SmallVector Fields; + for (FieldDecl *Field : RD->fields()) { + QualType FieldQTy = Field->getType(); + llvm::MDNode *TypeNode = isValidBaseType(FieldQTy) ? getBaseTypeInfo(FieldQTy) : getTypeInfo(FieldQTy); - if (!FieldNode) + if (!TypeNode) return BaseTypeMetadataCache[Ty] = nullptr; - Fields.push_back(std::make_pair( - FieldNode, Layout.getFieldOffset(idx) / Context.getCharWidth())); + + uint64_t BitOffset = Layout.getFieldOffset(Field->getFieldIndex()); + uint64_t Offset = Context.toCharUnitsFromBits(BitOffset).getQuantity(); + uint64_t Size = Context.getTypeSizeInChars(FieldQTy).getQuantity(); + Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, + TypeNode)); } SmallString<256> OutName; @@ -291,8 +299,15 @@ } else { OutName = RD->getName(); } + + // TODO: Support size-aware type nodes and create one here for the + // given aggregate type. + // Create the struct type node with a vector of pairs (offset, type). - return MDHelper.createTBAAStructTypeNode(OutName, Fields); + SmallVector, 4> OffsetsAndTypes; + for (const auto &Field : Fields) + OffsetsAndTypes.push_back(std::make_pair(Field.TBAA, Field.Offset)); + return MDHelper.createTBAAStructTypeNode(OutName, OffsetsAndTypes); } return nullptr; @@ -314,14 +329,16 @@ } llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) { + assert(!Info.isIncomplete() && "Access to an object of an incomplete type!"); + if (Info.isMayAlias()) - Info = TBAAAccessInfo(getChar()); + Info = TBAAAccessInfo(getChar(), Info.Size); if (!Info.AccessType) return nullptr; if (!CodeGenOpts.StructPathTBAA) - Info = TBAAAccessInfo(Info.AccessType); + Info = TBAAAccessInfo(Info.AccessType, Info.Size); llvm::MDNode *&N = AccessTagMetadataCache[Info]; if (N)