mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 08:06:08 +00:00
PR13684: Emit vtable entries for deleted functions as __cxa_deleted_function.
This is consistent/interoperable with GCC 4.7 (& __cxa_deleted_function isn't present in 4.4 - not sure when it got added, but you'll need something with that function available for this to work). llvm-svn: 166069
This commit is contained in:
parent
4df59a9ff8
commit
eb7d598cec
@ -205,6 +205,9 @@ public:
|
||||
/// Gets the pure virtual member call function.
|
||||
virtual StringRef GetPureVirtualCallName() = 0;
|
||||
|
||||
/// Gets the deleted virtual member call name.
|
||||
virtual StringRef GetDeletedVirtualCallName() = 0;
|
||||
|
||||
/**************************** Array cookies ******************************/
|
||||
|
||||
/// Returns the extra size required in order to store the array
|
||||
|
@ -537,7 +537,7 @@ CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
|
||||
|
||||
unsigned NextVTableThunkIndex = 0;
|
||||
|
||||
llvm::Constant* PureVirtualFn = 0;
|
||||
llvm::Constant *PureVirtualFn = 0, *DeletedVirtualFn = 0;
|
||||
|
||||
for (unsigned I = 0; I != NumComponents; ++I) {
|
||||
VTableComponent Component = Components[I];
|
||||
@ -594,6 +594,17 @@ CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
|
||||
CGM.Int8PtrTy);
|
||||
}
|
||||
Init = PureVirtualFn;
|
||||
} else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) {
|
||||
if (!DeletedVirtualFn) {
|
||||
llvm::FunctionType *Ty =
|
||||
llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
|
||||
StringRef DeletedCallName =
|
||||
CGM.getCXXABI().GetDeletedVirtualCallName();
|
||||
DeletedVirtualFn = CGM.CreateRuntimeFunction(Ty, DeletedCallName);
|
||||
DeletedVirtualFn = llvm::ConstantExpr::getBitCast(DeletedVirtualFn,
|
||||
CGM.Int8PtrTy);
|
||||
}
|
||||
Init = DeletedVirtualFn;
|
||||
} else {
|
||||
// Check if we should use a thunk.
|
||||
if (NextVTableThunkIndex < NumVTableThunks &&
|
||||
|
@ -113,6 +113,7 @@ public:
|
||||
void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
|
||||
|
||||
StringRef GetPureVirtualCallName() { return "__cxa_pure_virtual"; }
|
||||
StringRef GetDeletedVirtualCallName() { return "__cxa_deleted_virtual"; }
|
||||
|
||||
CharUnits getArrayCookieSizeImpl(QualType elementType);
|
||||
llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
|
||||
|
@ -29,6 +29,9 @@ public:
|
||||
MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {}
|
||||
|
||||
StringRef GetPureVirtualCallName() { return "_purecall"; }
|
||||
// No known support for deleted functions in MSVC yet, so this choice is
|
||||
// arbitrary.
|
||||
StringRef GetDeletedVirtualCallName() { return "_purecall"; }
|
||||
|
||||
llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
|
||||
llvm::Value *ptr,
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s
|
||||
|
||||
// Test1::B should just have a single entry in its VTT, which points to the vtable.
|
||||
namespace Test1 {
|
||||
@ -68,8 +68,19 @@ namespace Test5 {
|
||||
}
|
||||
}
|
||||
|
||||
namespace Test6 {
|
||||
struct A {
|
||||
virtual void f() = delete;
|
||||
virtual void anchor();
|
||||
};
|
||||
|
||||
void A::anchor() {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTVN5Test11BE, i64 0, i64 3) to i8*)]
|
||||
// CHECK: @_ZTVN5Test51AE = unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test51AE to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*), i8* bitcast (void (%"struct.Test5::A"*)* @_ZN5Test51A6anchorEv to i8*)]
|
||||
// CHECK: @_ZTVN5Test61AE = unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test61AE to i8*), i8* bitcast (void ()* @__cxa_deleted_virtual to i8*), i8* bitcast (void (%"struct.Test6::A"*)* @_ZN5Test61A6anchorEv to i8*)]
|
||||
// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 12) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 18) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 17) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 20) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 10) to i8*)]
|
||||
// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 5) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 6) to i8*)]
|
||||
// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user