From 83748cc5abc199a5219b0e7d9ba308984a8df613 Mon Sep 17 00:00:00 2001 From: Marco Antognini Date: Thu, 18 Jul 2019 10:04:18 +0000 Subject: [OpenCL] Improve destructor support in C++ for OpenCL Summary: This patch does mainly three things: 1. It fixes a false positive error detection in Sema that is similar to D62156. The error happens when explicitly calling an overloaded destructor for different address spaces. 2. It selects the correct destructor when multiple overloads for address spaces are available. 3. It inserts the expected address space cast when invoking a destructor, if needed, and therefore fixes a crash due to the unmet assertion in llvm::CastInst::Create. The following is a reproducer of the three issues: struct MyType { ~MyType() {} ~MyType() __constant {} }; __constant MyType myGlobal{}; kernel void foo() { myGlobal.~MyType(); // 1 and 2. // 1. error: cannot initialize object parameter of type // '__generic MyType' with an expression of type '__constant MyType' // 2. error: no matching member function for call to '~MyType' } kernel void bar() { // 3. The implicit call to the destructor crashes due to: // Assertion `castIsValid(op, S, Ty) && "Invalid cast!"' failed. // in llvm::CastInst::Create. MyType myLocal; } The added test depends on D62413 and covers a few more things than the above reproducer. Subscribers: yaxunl, Anastasia, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D64569 llvm-svn: 366422 --- clang/lib/CodeGen/MicrosoftCXXABI.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'clang/lib/CodeGen/MicrosoftCXXABI.cpp') diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index a91a949d024..fa34414de5d 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -258,7 +258,8 @@ public: void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, - bool Delegating, Address This) override; + bool Delegating, Address This, + QualType ThisTy) override; void emitVTableTypeMetadata(const VPtrInfo &Info, const CXXRecordDecl *RD, llvm::GlobalVariable *VTable); @@ -296,9 +297,8 @@ public: llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, - CXXDtorType DtorType, - Address This, - const CXXMemberCallExpr *CE) override; + CXXDtorType DtorType, Address This, + DeleteOrMemberCallExpr E) override; void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD, CallArgList &CallArgs) override { @@ -844,8 +844,7 @@ void MicrosoftCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF, // CXXMemberCallExpr for dtor call. bool UseGlobalDelete = DE->isGlobalDelete(); CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting; - llvm::Value *MDThis = - EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, /*CE=*/nullptr); + llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE); if (UseGlobalDelete) CGF.EmitDeleteCall(DE->getOperatorDelete(), MDThis, ElementType); } @@ -1569,7 +1568,8 @@ CGCXXABI::AddedStructorArgs MicrosoftCXXABI::addImplicitConstructorArgs( void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, - bool Delegating, Address This) { + bool Delegating, Address This, + QualType ThisTy) { // Use the base destructor variant in place of the complete destructor variant // if the class has no virtual bases. This effectively implements some of the // -mconstructor-aliases optimization, but as part of the MS C++ ABI. @@ -1591,7 +1591,7 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF); } - CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), + CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, /*ImplicitParam=*/nullptr, /*ImplicitParamTy=*/QualType(), nullptr); if (BaseDtorEndBB) { @@ -1900,7 +1900,10 @@ CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall( CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, - Address This, const CXXMemberCallExpr *CE) { + Address This, DeleteOrMemberCallExpr E) { + auto *CE = E.dyn_cast(); + auto *D = E.dyn_cast(); + assert((CE != nullptr) ^ (D != nullptr)); assert(CE == nullptr || CE->arg_begin() == CE->arg_end()); assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); @@ -1917,8 +1920,14 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall( llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()), DtorType == Dtor_Deleting); + QualType ThisTy; + if (CE) + ThisTy = CE->getImplicitObjectArgument()->getType()->getPointeeType(); + else + ThisTy = D->getDestroyedType(); + This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true); - RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), + RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, ImplicitParam, Context.IntTy, CE); return RV.getScalarVal(); } -- cgit v1.2.3