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
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) {
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);
bool shouldUseTBAA() const { return TBAA != 0; }
llvm::MDNode *getTBAAInfo(QualType QTy);
+ llvm::MDNode *getTBAAInfoForVTablePtr();
bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor);
// For now, handle any other kind of type conservatively.
return MetadataCache[Ty] = getChar();
}
+
+llvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() {
+ return getTBAAInfoForNamedType("vtable pointer", getRoot());
+}
/// 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
--- /dev/null
+// 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}