diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 36185faf942f..18d658436086 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -2252,16 +2252,17 @@ void CodeGenFunction::emitArrayDestroy(llvm::Value *begin, // Shift the address back by one element. llvm::Value *negativeOne = llvm::ConstantInt::get(SizeTy, -1, true); + llvm::Type *llvmElementType = ConvertTypeForMem(elementType); llvm::Value *element = Builder.CreateInBoundsGEP( - elementPast->getType()->getPointerElementType(), elementPast, negativeOne, - "arraydestroy.element"); + llvmElementType, elementPast, negativeOne, "arraydestroy.element"); if (useEHCleanup) pushRegularPartialArrayCleanup(begin, element, elementType, elementAlign, destroyer); // Perform the actual destruction there. - destroyer(*this, Address(element, elementAlign), elementType); + destroyer(*this, Address(element, llvmElementType, elementAlign), + elementType); if (useEHCleanup) PopCleanupBlock(); diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index 3579761f1429..7b880c1354e1 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -136,6 +136,7 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, } // Otherwise, the standard logic requires a helper function. } else { + Addr = Addr.getElementBitCast(CGF.ConvertTypeForMem(Type)); Func = CodeGenFunction(CGM) .generateDestroyHelper(Addr, Type, CGF.getDestroyer(DtorKind), CGF.needsEHCleanup(DtorKind), &D); diff --git a/clang/test/CodeGenCXX/global-array-destruction.cpp b/clang/test/CodeGenCXX/global-array-destruction.cpp index 0f280e000112..686c8a6c580a 100644 --- a/clang/test/CodeGenCXX/global-array-destruction.cpp +++ b/clang/test/CodeGenCXX/global-array-destruction.cpp @@ -39,7 +39,7 @@ struct T { T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 }; // CHECK: call {{.*}} @__cxa_atexit -// CHECK: getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @t, i64 1, i64 0, i64 0) +// CHECK: getelementptr inbounds ([2 x [3 x %struct.T]], [2 x [3 x %struct.T]]* bitcast ([2 x [3 x { double, i32 }]]* @t to [2 x [3 x %struct.T]]*), i64 1, i64 0, i64 0) // CHECK: call void @_ZN1TD1Ev // CHECK: icmp eq {{.*}} @t // CHECK: br i1 {{.*}} @@ -47,7 +47,7 @@ T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 }; static T t2[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 }; // CHECK: call {{.*}} @__cxa_atexit -// CHECK: getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @_ZL2t2, i64 1, i64 0, i64 0) +// CHECK: getelementptr inbounds ([2 x [3 x %struct.T]], [2 x [3 x %struct.T]]* bitcast ([2 x [3 x { double, i32 }]]* @_ZL2t2 to [2 x [3 x %struct.T]]*), i64 1, i64 0, i64 0) // CHECK: call void @_ZN1TD1Ev // CHECK: icmp eq {{.*}} @_ZL2t2 // CHECK: br i1 {{.*}} @@ -56,7 +56,7 @@ using U = T[2][3]; U &&u = U{ {{1.0, 2}, {3.0, 4}, {5.0, 6}}, {{7.0, 8}, {9.0, 10}, {11.0, 12}} }; // CHECK: call {{.*}} @__cxa_atexit -// CHECK: getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @_ZGR1u_, i64 1, i64 0, i64 0) +// CHECK: getelementptr inbounds ([2 x [3 x %struct.T]], [2 x [3 x %struct.T]]* @_ZGR1u_, i64 1, i64 0, i64 0) // CHECK: call void @_ZN1TD1Ev // CHECK: icmp eq {{.*}} @_ZGR1u_ // CHECK: br i1 {{.*}}