forked from OSchip/llvm-project
Improvement on sized deallocation from r230160:
Do not declare sized deallocation functions dependently on whether it is found in global scope. Instead, enforce the branching in emitted code by (1) declaring the functions extern_weak and (2) emitting sized delete expressions as a branching between both forms delete. llvm-svn: 230580
This commit is contained in:
parent
17151eba64
commit
697b32a0cb
|
@ -1422,6 +1422,71 @@ CodeGenFunction::pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete,
|
|||
OperatorDelete, ElementType);
|
||||
}
|
||||
|
||||
static void EmitDelete(CodeGenFunction &CGF,
|
||||
const CXXDeleteExpr *DE,
|
||||
llvm::Value *Ptr,
|
||||
QualType ElementType);
|
||||
|
||||
static void EmitSizedDelete(CodeGenFunction &CGF,
|
||||
const CXXDeleteExpr *DE,
|
||||
llvm::Value *Ptr,
|
||||
QualType ElementType,
|
||||
FunctionDecl* UnsizedDealloc) {
|
||||
|
||||
if (CGF.getLangOpts().DefineSizedDeallocation) {
|
||||
// The delete operator in use is fixed. So simply emit the delete expr.
|
||||
EmitDelete(CGF, DE, Ptr, ElementType);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(UnsizedDealloc && "We must be emiting a 'sized' delete expr");
|
||||
|
||||
// Branch off over the value of operator delete:
|
||||
// Use the sized form if available, and default on the unsized form otherwise.
|
||||
llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("if.then");
|
||||
llvm::BasicBlock *ContBlock = CGF.createBasicBlock("if.end");
|
||||
llvm::BasicBlock *ElseBlock = CGF.createBasicBlock("if.else");
|
||||
|
||||
// Emit the condition.
|
||||
const FunctionDecl *OpDelFD = DE->getOperatorDelete();
|
||||
llvm::Value *OpDelAddr = CGF.CGM.GetAddrOfFunction(OpDelFD);
|
||||
//llvm::Function *OpDel = dyn_cast<llvm::Function>(OpDelAddr);
|
||||
llvm::Value *SDE = CGF.Builder.CreateIsNotNull(OpDelAddr, "sized.del.exists");
|
||||
CGF.Builder.CreateCondBr(SDE, ThenBlock, ElseBlock);
|
||||
|
||||
// Emit the 'then' code.
|
||||
CGF.EmitBlock(ThenBlock);
|
||||
EmitDelete(CGF, DE, Ptr, ElementType);
|
||||
CGF.EmitBranch(ContBlock);
|
||||
|
||||
// Compute the 'unsized' delete expr.
|
||||
CXXDeleteExpr * E = const_cast<CXXDeleteExpr*>(DE);
|
||||
CXXDeleteExpr *UnsizedDE =
|
||||
new (CGF.getContext()) CXXDeleteExpr(CGF.getContext().VoidTy,
|
||||
E->isGlobalDelete(),
|
||||
E->isArrayForm(),
|
||||
E->isArrayFormAsWritten(),
|
||||
E->doesUsualArrayDeleteWantSize(),
|
||||
UnsizedDealloc,
|
||||
E->getArgument(),
|
||||
E->getLocStart());
|
||||
// Emit the 'else' code.
|
||||
{
|
||||
// There is no need to emit line number for an unconditional branch.
|
||||
auto NL = ApplyDebugLocation::CreateEmpty(CGF);
|
||||
CGF.EmitBlock(ElseBlock);
|
||||
}
|
||||
EmitDelete(CGF, UnsizedDE, Ptr, ElementType);
|
||||
{
|
||||
// There is no need to emit line number for an unconditional branch.
|
||||
auto NL = ApplyDebugLocation::CreateEmpty(CGF);
|
||||
CGF.EmitBranch(ContBlock);
|
||||
}
|
||||
|
||||
// Emit the continuation block for code after the if.
|
||||
CGF.EmitBlock(ContBlock, true);
|
||||
}
|
||||
|
||||
/// Emit the code for deleting a single object.
|
||||
static void EmitObjectDelete(CodeGenFunction &CGF,
|
||||
const CXXDeleteExpr *DE,
|
||||
|
@ -1581,6 +1646,17 @@ static void EmitArrayDelete(CodeGenFunction &CGF,
|
|||
CGF.PopCleanupBlock();
|
||||
}
|
||||
|
||||
static void EmitDelete(CodeGenFunction &CGF,
|
||||
const CXXDeleteExpr *DE,
|
||||
llvm::Value *Ptr,
|
||||
QualType ElementType) {
|
||||
if (DE->isArrayForm()) {
|
||||
EmitArrayDelete(CGF, DE, Ptr, ElementType);
|
||||
} else {
|
||||
EmitObjectDelete(CGF, DE, Ptr, ElementType);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
|
||||
const Expr *Arg = E->getArgument();
|
||||
llvm::Value *Ptr = EmitScalarExpr(Arg);
|
||||
|
@ -1620,11 +1696,12 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
|
|||
assert(ConvertTypeForMem(DeleteTy) ==
|
||||
cast<llvm::PointerType>(Ptr->getType())->getElementType());
|
||||
|
||||
if (E->isArrayForm()) {
|
||||
EmitArrayDelete(*this, E, Ptr, DeleteTy);
|
||||
} else {
|
||||
EmitObjectDelete(*this, E, Ptr, DeleteTy);
|
||||
}
|
||||
const FunctionDecl *Dealloc = E->getOperatorDelete();
|
||||
if (FunctionDecl* UnsizedDealloc =
|
||||
Dealloc->getCorrespondingUnsizedGlobalDeallocationFunction())
|
||||
EmitSizedDelete(*this, E, Ptr, DeleteTy, UnsizedDealloc);
|
||||
else
|
||||
EmitDelete(*this, E, Ptr, DeleteTy);
|
||||
|
||||
EmitBlock(DeleteEnd);
|
||||
}
|
||||
|
|
|
@ -2090,15 +2090,6 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
|
|||
}
|
||||
}
|
||||
|
||||
// If the function is sized operator delete and has not already been
|
||||
// declared, and weak definitions have been disabled, do not declare
|
||||
// it implicitly. Instead, let deallocation function lookup pick up
|
||||
// unsized delete.
|
||||
// FIXME: We should remove this guard once backward compatibility is
|
||||
// no longer an issue
|
||||
if (NumParams == 2 && !getLangOpts().DefineSizedDeallocation)
|
||||
return;
|
||||
|
||||
FunctionProtoType::ExtProtoInfo EPI;
|
||||
|
||||
QualType BadAllocType;
|
||||
|
@ -2131,6 +2122,16 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
|
|||
Alloc->addAttr(VisibilityAttr::CreateImplicit(Context,
|
||||
VisibilityAttr::Default));
|
||||
|
||||
if (NumParams == 2 && !getLangOpts().DefineSizedDeallocation) {
|
||||
assert(getLangOpts().SizedDeallocation &&
|
||||
"Only sized deallocation can have two parameters");
|
||||
|
||||
// This declaration should be emited as extern_weak.
|
||||
LinkageInfo LV = Alloc->getLinkageAndVisibility();
|
||||
assert(LV.getLinkage() == clang::ExternalLinkage);
|
||||
Alloc->addAttr(WeakAttr::CreateImplicit(Context));
|
||||
}
|
||||
|
||||
if (AddRestrictAttr)
|
||||
Alloc->addAttr(
|
||||
RestrictAttr::CreateImplicit(Context, RestrictAttr::GNU_malloc));
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
|
||||
// RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -o - -DINLIB | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKUND
|
||||
// RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKUND
|
||||
// RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -fdefine-sized-deallocation -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKDEF
|
||||
// RUN: %clang_cc1 -std=c++11 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
|
||||
// RUN: %clang_cc1 -std=c++11 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - -DINLIB | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKUND
|
||||
// RUN: %clang_cc1 -std=c++11 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKUND
|
||||
// RUN: %clang_cc1 -std=c++11 -fsized-deallocation -fdefine-sized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKDEF
|
||||
// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
|
||||
// RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -fno-sized-deallocation -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
|
||||
|
@ -12,11 +10,6 @@
|
|||
|
||||
typedef decltype(sizeof(0)) size_t;
|
||||
|
||||
#ifdef INLIB
|
||||
void operator delete(void *, size_t) noexcept;
|
||||
void operator delete[](void *, size_t) noexcept;
|
||||
#endif
|
||||
|
||||
typedef int A;
|
||||
struct B { int n; };
|
||||
struct C { ~C() {} };
|
||||
|
@ -54,63 +47,92 @@ template void del<F>();
|
|||
D::D() {}
|
||||
|
||||
// CHECK-LABEL: define weak_odr void @_Z3delIiEvv()
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
|
||||
// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
|
||||
// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
|
||||
// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
|
||||
//
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
|
||||
// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
|
||||
// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
|
||||
// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
|
||||
|
||||
// CHECKDEF-LABEL: define linkonce void @_ZdlPvm(i8*, i64) #{{[0-9]+}} comdat
|
||||
// CHECKDEF: call void @_ZdlPv(i8* %0)
|
||||
// CHECKUND-LABEL: declare void @_ZdlPvm(i8*
|
||||
// CHECKUND-LABEL: declare extern_weak void @_ZdlPvm(i8*
|
||||
|
||||
// CHECK-LABEL: define weak_odr void @_Z3delI1BEvv()
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
|
||||
// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
|
||||
// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
|
||||
// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
|
||||
//
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
|
||||
// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
|
||||
// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
|
||||
// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
|
||||
|
||||
// CHECK-LABEL: define weak_odr void @_Z3delI1CEvv()
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
|
||||
// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
|
||||
// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
|
||||
// CHECK: mul i64 1, %{{[^ ]*}}
|
||||
// CHECK: add i64 %{{[^ ]*}}, 8
|
||||
// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
|
||||
// CHECKUND: call void @_ZdaPv(i8* %{{[^ ]*}})
|
||||
//
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
|
||||
// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
|
||||
// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
|
||||
// CHECK: mul i64 1, %{{[^ ]*}}
|
||||
// CHECK: add i64 %{{[^ ]*}}, 8
|
||||
// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
|
||||
// CHECKUND: call void @_ZdaPv(i8* %{{[^ ]*}})
|
||||
|
||||
// CHECKDEF-LABEL: define linkonce void @_ZdaPvm(i8*, i64) #{{[0-9]+}} comdat
|
||||
// CHECKDEF: call void @_ZdaPv(i8* %0)
|
||||
// CHECKUND-LABEL: declare void @_ZdaPvm(i8*
|
||||
// CHECKUND-LABEL: declare extern_weak void @_ZdaPvm(i8*
|
||||
|
||||
// CHECK-LABEL: define weak_odr void @_Z3delI1DEvv()
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
|
||||
// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 8)
|
||||
// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
|
||||
// CHECK: mul i64 8, %{{[^ ]*}}
|
||||
// CHECK: add i64 %{{[^ ]*}}, 8
|
||||
// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
|
||||
// CHECKUND: call void @_ZdaPv(i8* %{{[^ ]*}})
|
||||
//
|
||||
// CHECK-NOT: Zdl
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
|
||||
// CHECKDEF-NOT: Zdl
|
||||
// CHECK: call void %{{.*}}
|
||||
// CHECK-NOT: Zdl
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
|
||||
// CHECK: mul i64 8, %{{[^ ]*}}
|
||||
// CHECK: add i64 %{{[^ ]*}}, 8
|
||||
// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
|
||||
// CHECKUND: call void @_ZdaPv(i8* %{{[^ ]*}})
|
||||
|
||||
// CHECK-LABEL: define weak_odr void @_Z3delI1EEvv()
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
|
||||
// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
|
||||
// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
|
||||
// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
|
||||
//
|
||||
// CHECK: call void @_ZN1EdlEPv(i8* %{{[^ ]*}})
|
||||
// CHECK: call void @_ZN1EdaEPv(i8* %{{[^ ]*}})
|
||||
|
||||
// CHECK-LABEL: define weak_odr void @_Z3delI1FEvv()
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
|
||||
// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
|
||||
// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
|
||||
// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
|
||||
// CHECK: mul i64 1, %{{[^ ]*}}
|
||||
// CHECK: add i64 %{{[^ ]*}}, 8
|
||||
// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
|
||||
// CHECKUND: call void @_ZdaPv(i8* %{{[^ ]*}})
|
||||
//
|
||||
// CHECK: call void @_ZN1FdlEPvm(i8* %{{[^ ]*}}, i64 1)
|
||||
// CHECK: mul i64 1, %{{[^ ]*}}
|
||||
|
|
|
@ -1,21 +1,15 @@
|
|||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++11 %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK11
|
||||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++11 -fvisibility hidden %s 2>&1 | FileCheck %s -check-prefix=CHECKHID -check-prefix=CHECK11
|
||||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -DINLIB -fno-sized-deallocation %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK11
|
||||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -DINLIB %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14UND
|
||||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -DINLIB -fvisibility hidden %s 2>&1 | FileCheck %s -check-prefix=CHECKHID -check-prefix=CHECK14 -check-prefix=CHECK14UND
|
||||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -DINLIB -fdefine-sized-deallocation %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14DEFCOMDAT
|
||||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -DINLIB -fdefine-sized-deallocation -fvisibility hidden %s 2>&1 | FileCheck %s -check-prefix=CHECKHID -check-prefix=CHECK14 -check-prefix=CHECK14DEFCOMDAT
|
||||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-macosx -o - -std=c++14 -DINLIB -fdefine-sized-deallocation %s | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14DEFNOCOMDAT
|
||||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -fno-sized-deallocation %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK11
|
||||
// RU N: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14UND
|
||||
// RU N: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -fvisibility hidden %s 2>&1 | FileCheck %s -check-prefix=CHECKHID -check-prefix=CHECK14 -check-prefix=CHECK14UND
|
||||
// RU N: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -fdefine-sized-deallocation %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14DEFCOMDAT
|
||||
// RU N: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -fdefine-sized-deallocation -fvisibility hidden %s 2>&1 | FileCheck %s -check-prefix=CHECKHID -check-prefix=CHECK14 -check-prefix=CHECK14DEFCOMDAT
|
||||
// RU N: %clang_cc1 -emit-llvm -triple x86_64-apple-macosx -o - -std=c++14 -fdefine-sized-deallocation %s | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14DEFNOCOMDAT
|
||||
|
||||
// PR22419: Implicit sized deallocation functions always have default visibility.
|
||||
// Generalized to all implicit allocation functions.
|
||||
|
||||
#ifdef INLIB
|
||||
typedef decltype(sizeof(0)) size_t;
|
||||
void operator delete(void *, size_t) noexcept;
|
||||
void operator delete[](void *, size_t) noexcept;
|
||||
#endif
|
||||
|
||||
// CHECK14-DAG: %struct.A = type { i8 }
|
||||
struct A { };
|
||||
|
||||
|
@ -28,7 +22,9 @@ void foo(A* is) {
|
|||
is = new A();
|
||||
|
||||
// CHECK11-DAG: call void @_ZdlPv(i8* %{{.+}})
|
||||
// CHECK14UND-DAG: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
|
||||
// CHECK14-DAG: call void @_ZdlPvm(i8* %{{.+}}, i64 1)
|
||||
// CHECK14UND-DAG: call void @_ZdlPv(i8* %{{.+}})
|
||||
delete is;
|
||||
}
|
||||
|
||||
|
@ -36,7 +32,7 @@ void foo(A* is) {
|
|||
// CHECK11-DAG: declare void @_ZdlPv(i8*)
|
||||
|
||||
// CHECK14-DAG: declare noalias i8* @_Znwm(i64)
|
||||
// CHECK14UND-DAG: declare void @_ZdlPvm(i8*, i64)
|
||||
// CHECK14UND-DAG: declare extern_weak void @_ZdlPvm(i8*, i64)
|
||||
// CHECK14DEFCOMDAT-DAG: define linkonce void @_ZdlPvm(i8*, i64) #{{[0-9]+}} comdat {
|
||||
// CHECK14DEFCOMDAT-DAG: declare void @_ZdlPv(i8*)
|
||||
// CHECK14DEFNOCOMDAT-DAG: define linkonce void @_ZdlPvm(i8*, i64) #{{[0-9]+}} {
|
||||
|
@ -54,7 +50,9 @@ void f(B *p) {
|
|||
p = new B[5];
|
||||
|
||||
// CHECK11-DAG: call void @_ZdaPv(i8* %{{.+}})
|
||||
// CHECK14UND-DAG: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
|
||||
// CHECK14-DAG: call void @_ZdaPvm(i8* %{{.+}}, i64 %{{.+}})
|
||||
// CHECK14UND-DAG: call void @_ZdaPv(i8* %{{.+}})
|
||||
delete[] p;
|
||||
}
|
||||
|
||||
|
@ -62,7 +60,7 @@ void f(B *p) {
|
|||
// CHECK11-DAG: declare void @_ZdaPv(i8*)
|
||||
|
||||
// CHECK14-DAG: declare noalias i8* @_Znam(i64)
|
||||
// CHECK14UND-DAG: declare void @_ZdaPvm(i8*, i64)
|
||||
// CHECK14UND-DAG: declare extern_weak void @_ZdaPvm(i8*, i64)
|
||||
// CHECK14DEF-DAG: define linkonce void @_ZdaPvm(i8*, i64) #{{[0-9]+}} comdat {
|
||||
// CHECK14DEF-DAG: declare void @_ZdaPv(i8*)
|
||||
// CHECK14DEFNOCOMDAT-DAG: define linkonce void @_ZdaPvm(i8*, i64) #{{[0-9]+}} {
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -o - %s 2>&1 | FileCheck %s
|
||||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -fdefine-sized-deallocation -o - %s 2>&1 | FileCheck %s
|
||||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -fno-sized-deallocation -o - %s 2>&1 | FileCheck %s
|
||||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -fsized-deallocation -o - %s 2>&1 | FileCheck %s
|
||||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -fsized-deallocation -fdefine-sized-deallocation -o - %s 2>&1 | FileCheck %s
|
||||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -o - %s 2>&1 | FileCheck %s
|
||||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -o - %s 2>&1 | FileCheck %s --check-prefix=CHECKUND
|
||||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -fdefine-sized-deallocation -o - %s 2>&1 | FileCheck %s --check-prefix=CHECKDEF
|
||||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -fno-sized-deallocation -o - %s 2>&1 | FileCheck %s --check-prefix=CHECKNO
|
||||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -fsized-deallocation -o - %s 2>&1 | FileCheck %s --check-prefix=CHECKUND
|
||||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -fsized-deallocation -fdefine-sized-deallocation -o - %s 2>&1 | FileCheck %s --check-prefix=CHECKDEF
|
||||
// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -o - %s 2>&1 | FileCheck %s --check-prefix=CHECKNO
|
||||
|
||||
void operator delete(void*, unsigned long) throw() __attribute__((alias("foo")));
|
||||
extern "C" void foo(void*, unsigned long) {}
|
||||
|
||||
// CHECK-DAG: @_ZdlPvm = alias void (i8*, i64)* @foo
|
||||
// CHECKUND-DAG: @_ZdlPvm = weak alias void (i8*, i64)* @foo
|
||||
// CHECKDEF-DAG: @_ZdlPvm = alias void (i8*, i64)* @foo
|
||||
// CHECKNO-DAG: @_ZdlPvm = alias void (i8*, i64)* @foo
|
||||
|
|
Loading…
Reference in New Issue