From 141e46faf0d749356ec1de11963527aaea2b3078 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Mon, 26 Mar 2012 17:03:51 +0000 Subject: [PATCH] add tbaa metadata to vtable pointer loads/stores llvm-svn: 153447 --- clang/lib/CodeGen/CGClass.cpp | 7 +++++-- clang/lib/CodeGen/CodeGenModule.cpp | 6 ++++++ clang/lib/CodeGen/CodeGenModule.h | 1 + clang/lib/CodeGen/CodeGenTBAA.cpp | 4 ++++ clang/lib/CodeGen/CodeGenTBAA.h | 4 ++++ clang/test/CodeGen/tbaa-for-vptr.cpp | 19 +++++++++++++++++++ 6 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGen/tbaa-for-vptr.cpp diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index ee79c394ac04..b452c1b7ab43 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1514,7 +1514,8 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, llvm::Type *AddressPointPtrTy = VTableAddressPoint->getType()->getPointerTo(); VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy); - Builder.CreateStore(VTableAddressPoint, VTableField); + llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); + CGM.DecorateInstruction(Store, CGM.getTBAAInfoForVTablePtr()); } void @@ -1597,7 +1598,9 @@ void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { llvm::Value *CodeGenFunction::GetVTablePtr(llvm::Value *This, llvm::Type *Ty) { llvm::Value *VTablePtrSrc = Builder.CreateBitCast(This, Ty->getPointerTo()); - return Builder.CreateLoad(VTablePtrSrc, "vtable"); + llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); + CGM.DecorateInstruction(VTable, CGM.getTBAAInfoForVTablePtr()); + return VTable; } static const CXXRecordDecl *getMostDerivedClassDecl(const Expr *Base) { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 1c8f5f65f93d..cc19d950fc89 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -182,6 +182,12 @@ llvm::MDNode *CodeGenModule::getTBAAInfo(QualType QTy) { return TBAA->getTBAAInfo(QTy); } +llvm::MDNode *CodeGenModule::getTBAAInfoForVTablePtr() { + if (!TBAA) + return 0; + return TBAA->getTBAAInfoForVTablePtr(); +} + void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst, llvm::MDNode *TBAAInfo) { Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 8f9cdcd9a953..5719afb6123a 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -448,6 +448,7 @@ public: bool shouldUseTBAA() const { return TBAA != 0; } llvm::MDNode *getTBAAInfo(QualType QTy); + llvm::MDNode *getTBAAInfoForVTablePtr(); bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 148081e928ef..9ee3f1d2e67c 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -179,3 +179,7 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) { // For now, handle any other kind of type conservatively. return MetadataCache[Ty] = getChar(); } + +llvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() { + return getTBAAInfoForNamedType("vtable pointer", getRoot()); +} diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h index 9fe51fb33141..8e08498b7e59 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.h +++ b/clang/lib/CodeGen/CodeGenTBAA.h @@ -68,6 +68,10 @@ public: /// getTBAAInfo - Get the TBAA MDNode to be used for a dereference /// of the given type. llvm::MDNode *getTBAAInfo(QualType QTy); + + /// getTBAAInfoForVTablePtr - Get the TBAA MDNode to be used for a + /// dereference of a vtable pointer. + llvm::MDNode *getTBAAInfoForVTablePtr(); }; } // end namespace CodeGen diff --git a/clang/test/CodeGen/tbaa-for-vptr.cpp b/clang/test/CodeGen/tbaa-for-vptr.cpp new file mode 100644 index 000000000000..c63c7368524a --- /dev/null +++ b/clang/test/CodeGen/tbaa-for-vptr.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -emit-llvm -o - -O1 %s | FileCheck %s +// Check that we generate TBAA for vtable pointer loads and stores. +struct A { + virtual int foo() const ; + virtual ~A(); +}; + +void CreateA() { + new A; +} + +void CallFoo(A *a) { + a->foo(); +} + +// CHECK: %vtable = load {{.*}} !tbaa !0 +// CHECK: store {{.*}} !tbaa !0 +// CHECK: !0 = metadata !{metadata !"vtable pointer", metadata !1} +// CHECK: !1 = metadata !{metadata !"Simple C/C++ TBAA", null}