forked from OSchip/llvm-project
PR46908: Emit undef destroying_delete_t as an aggregate RValue.
We previously used a non-aggregate RValue to represent the passed value, which violated the assumptions of call arg lowering in some cases, in particular on 32-bit Windows, where we'd end up producing an FCA store with TBAA metadata, that the IR verifier would reject.
This commit is contained in:
parent
c89e46e767
commit
1e7f026c3b
|
@ -1788,11 +1788,14 @@ void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD,
|
|||
DeleteArgs.add(RValue::get(DeletePtr), ArgTy);
|
||||
|
||||
// Pass the std::destroying_delete tag if present.
|
||||
llvm::AllocaInst *DestroyingDeleteTag = nullptr;
|
||||
if (Params.DestroyingDelete) {
|
||||
QualType DDTag = *ParamTypeIt++;
|
||||
// Just pass an 'undef'. We expect the tag type to be an empty struct.
|
||||
auto *V = llvm::UndefValue::get(getTypes().ConvertType(DDTag));
|
||||
DeleteArgs.add(RValue::get(V), DDTag);
|
||||
llvm::Type *Ty = getTypes().ConvertType(DDTag);
|
||||
CharUnits Align = CGM.getNaturalTypeAlignment(DDTag);
|
||||
DestroyingDeleteTag = CreateTempAlloca(Ty, "destroying.delete.tag");
|
||||
DestroyingDeleteTag->setAlignment(Align.getAsAlign());
|
||||
DeleteArgs.add(RValue::getAggregate(Address(DestroyingDeleteTag, Align)), DDTag);
|
||||
}
|
||||
|
||||
// Pass the size if the delete function has a size_t parameter.
|
||||
|
@ -1829,6 +1832,11 @@ void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD,
|
|||
|
||||
// Emit the call to delete.
|
||||
EmitNewDeleteCall(*this, DeleteFD, DeleteFTy, DeleteArgs);
|
||||
|
||||
// If call argument lowering didn't use the destroying_delete_t alloca,
|
||||
// remove it again.
|
||||
if (DestroyingDeleteTag && DestroyingDeleteTag->use_empty())
|
||||
DestroyingDeleteTag->eraseFromParent();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM
|
||||
// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-windows -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MSABI
|
||||
// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefixes=CHECK,CHECK-ITANIUM,CHECK-64BIT
|
||||
// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI64,CHECK-64BIT
|
||||
// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple i386-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI32,CHECK-32BIT
|
||||
|
||||
// PR46908: ensure the IR passes the verifier with optimizations enabled.
|
||||
// RUN: %clang_cc1 -std=c++2a -emit-llvm-only %s -triple x86_64-linux-gnu -O2
|
||||
// RUN: %clang_cc1 -std=c++2a -emit-llvm-only %s -triple x86_64-windows -O2
|
||||
// RUN: %clang_cc1 -std=c++2a -emit-llvm-only %s -triple i386-windows -O2
|
||||
|
||||
namespace std {
|
||||
using size_t = decltype(sizeof(0));
|
||||
|
@ -21,7 +27,8 @@ void delete_A(A *a) { delete a; }
|
|||
// Ensure that we call the destroying delete and not the destructor.
|
||||
// CHECK-NOT: call
|
||||
// CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* %[[a]])
|
||||
// CHECK-MSABI: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
|
||||
// CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
|
||||
// CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], %{{.*}}* byval(%{{.*}}) align 4 %{{.*}})
|
||||
// CHECK-NOT: call
|
||||
// CHECK: }
|
||||
|
||||
|
@ -39,7 +46,7 @@ void delete_B(B *b) { delete b; }
|
|||
// CHECK-NOT: call
|
||||
// CHECK: %[[VTABLE:.*]] = load
|
||||
// CHECK: %[[DTOR:.*]] = load
|
||||
// CHECK: call {{void|i8\*}} %[[DTOR]](%{{.*}}* %[[b]]
|
||||
// CHECK: call {{void|i8\*|x86_thiscallcc i8\*}} %[[DTOR]](%{{.*}}* %[[b]]
|
||||
// CHECK-MSABI-SAME: , i32 1)
|
||||
// CHECK-NOT: call
|
||||
// CHECK: }
|
||||
|
@ -56,7 +63,8 @@ void delete_C(C *c) { delete c; }
|
|||
// CHECK: icmp eq %{{.*}} %[[c]], null
|
||||
// CHECK: br i1
|
||||
//
|
||||
// CHECK: %[[base:.*]] = getelementptr {{.*}}, i64 8
|
||||
// CHECK-64BIT: %[[base:.*]] = getelementptr {{.*}}, i64 8
|
||||
// CHECK-32BIT: %[[base:.*]] = getelementptr {{.*}}, i32 4
|
||||
// CHECK: %[[castbase:.*]] = bitcast {{.*}} %[[base]]
|
||||
//
|
||||
// CHECK: %[[a:.*]] = phi {{.*}} %[[castbase]]
|
||||
|
@ -65,7 +73,8 @@ void delete_C(C *c) { delete c; }
|
|||
//
|
||||
// CHECK-NOT: call
|
||||
// CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* %[[a]])
|
||||
// CHECK-MSABI: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
|
||||
// CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
|
||||
// CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], %{{.*}}* byval(%{{.*}}) align 4 %{{.*}})
|
||||
// CHECK-NOT: call
|
||||
// CHECK: }
|
||||
|
||||
|
@ -81,13 +90,14 @@ void delete_D(D *d) { delete d; }
|
|||
// For MS, we don't add a new vtable slot to the primary vtable for the virtual
|
||||
// destructor. Instead we cast to the VDel base class.
|
||||
// CHECK-MSABI: bitcast {{.*}} %[[d]]
|
||||
// CHECK-MSABI-NEXT: getelementptr {{.*}}, i64 8
|
||||
// CHECK-MSABI64-NEXT: getelementptr {{.*}}, i64 8
|
||||
// CHECK-MSABI32-NEXT: getelementptr {{.*}}, i32 4
|
||||
// CHECK-MSABI-NEXT: %[[d:.*]] = bitcast i8*
|
||||
//
|
||||
// CHECK: %[[VTABLE:.*]] = load
|
||||
// CHECK: %[[DTOR:.*]] = load
|
||||
//
|
||||
// CHECK: call {{void|i8\*}} %[[DTOR]](%{{.*}}* %[[d]]
|
||||
// CHECK: call {{void|i8\*|x86_thiscallcc i8\*}} %[[DTOR]](%{{.*}}* %[[d]]
|
||||
// CHECK-MSABI-SAME: , i32 1)
|
||||
// CHECK-NOT: call
|
||||
// CHECK: }
|
||||
|
@ -100,7 +110,8 @@ void delete_G(G *g) { delete g; }
|
|||
// CHECK-LABEL: define {{.*}}delete_G
|
||||
// CHECK-NOT: call
|
||||
// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t(%{{.*}}* %[[a]], i64 32, i64 16)
|
||||
// CHECK-MSABI: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"(%{{.*}}* %[[a]], i8 {{[^,]*}}, i64 32, i64 16)
|
||||
// CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"(%{{.*}}* %[[a]], i8 {{[^,]*}}, i64 32, i64 16)
|
||||
// CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"(%{{.*}}* %[[a]], %{{.*}}* byval(%{{.*}}) align 4 %{{.*}}, i32 16, i32 16)
|
||||
// CHECK-NOT: call
|
||||
// CHECK: }
|
||||
|
||||
|
@ -116,19 +127,23 @@ H::~H() { call_in_dtor(); }
|
|||
// CHECK-ITANIUM-NOT: call
|
||||
// CHECK-ITANIUM: }
|
||||
|
||||
// CHECK-MSABI: define {{.*}} @"??_GH@@UEAAPEAXI@Z"(
|
||||
// CHECK-MSABI64: define {{.*}} @"??_GH@@UEAAPEAXI@Z"(
|
||||
// CHECK-MSABI32: define {{.*}} @"??_GH@@UAEPAXI@Z"(
|
||||
// CHECK-MSABI-NOT: call{{ }}
|
||||
// CHECK-MSABI: load i32
|
||||
// CHECK-MSABI: icmp eq i32 {{.*}}, 0
|
||||
// CHECK-MSABI: br i1
|
||||
//
|
||||
// CHECK-MSABI-NOT: call{{ }}
|
||||
// CHECK-MSABI: getelementptr {{.*}}, i64 24
|
||||
// CHECK-MSABI64: getelementptr {{.*}}, i64 24
|
||||
// CHECK-MSABI32: getelementptr {{.*}}, i32 20
|
||||
// CHECK-MSABI-NOT: call{{ }}
|
||||
// CHECK-MSABI: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 48, i64 16)
|
||||
// CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 48, i64 16)
|
||||
// CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 32, i32 16)
|
||||
// CHECK-MSABI: br label %[[RETURN:.*]]
|
||||
//
|
||||
// CHECK-MSABI: call void @"??1H@@UEAA@XZ"(
|
||||
// CHECK-MSABI64: call void @"??1H@@UEAA@XZ"(
|
||||
// CHECK-MSABI32: call x86_thiscallcc void @"??1H@@UAE@XZ"(
|
||||
// CHECK-MSABI: br label %[[RETURN]]
|
||||
//
|
||||
// CHECK-MSABI: }
|
||||
|
@ -143,19 +158,23 @@ I::~I() { call_in_dtor(); }
|
|||
// CHECK-ITANIUM-NOT: call
|
||||
// CHECK-ITANIUM: }
|
||||
|
||||
// CHECK-MSABI: define {{.*}} @"??_GI@@UEAAPEAXI@Z"(
|
||||
// CHECK-MSABI64: define {{.*}} @"??_GI@@UEAAPEAXI@Z"(
|
||||
// CHECK-MSABI32: define {{.*}} @"??_GI@@UAEPAXI@Z"(
|
||||
// CHECK-MSABI-NOT: call{{ }}
|
||||
// CHECK-MSABI: load i32
|
||||
// CHECK-MSABI: icmp eq i32 {{.*}}, 0
|
||||
// CHECK-MSABI: br i1
|
||||
//
|
||||
// CHECK-MSABI-NOT: call{{ }}
|
||||
// CHECK-MSABI: getelementptr {{.*}}, i64 24
|
||||
// CHECK-MSABI64: getelementptr {{.*}}, i64 24
|
||||
// CHECK-MSABI32: getelementptr {{.*}}, i32 20
|
||||
// CHECK-MSABI-NOT: call{{ }}
|
||||
// CHECK-MSABI: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 96, i64 32)
|
||||
// CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 96, i64 32)
|
||||
// CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 64, i32 32)
|
||||
// CHECK-MSABI: br label %[[RETURN:.*]]
|
||||
//
|
||||
// CHECK-MSABI: call void @"??1I@@UEAA@XZ"(
|
||||
// CHECK-MSABI64: call void @"??1I@@UEAA@XZ"(
|
||||
// CHECK-MSABI32: call x86_thiscallcc void @"??1I@@UAE@XZ"(
|
||||
// CHECK-MSABI: br label %[[RETURN]]
|
||||
//
|
||||
// CHECK-MSABI: }
|
||||
|
|
Loading…
Reference in New Issue