Index: clang/lib/CodeGen/CGDecl.cpp =================================================================== --- clang/lib/CodeGen/CGDecl.cpp +++ clang/lib/CodeGen/CGDecl.cpp @@ -2252,16 +2252,17 @@ // 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(); Index: clang/lib/CodeGen/CGDeclCXX.cpp =================================================================== --- clang/lib/CodeGen/CGDeclCXX.cpp +++ clang/lib/CodeGen/CGDeclCXX.cpp @@ -136,6 +136,7 @@ } // 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); Index: clang/test/CodeGenCXX/global-array-destruction.cpp =================================================================== --- clang/test/CodeGenCXX/global-array-destruction.cpp +++ clang/test/CodeGenCXX/global-array-destruction.cpp @@ -39,7 +39,7 @@ 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 ({{.*}} getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @t, i32 0, i32 0, i32 0), i64 6) +// CHECK: getelementptr inbounds (%struct.T, %struct.T* 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]]*), i32 0, i32 0, i32 0), i64 6) // CHECK: call void @_ZN1TD1Ev // CHECK: icmp eq {{.*}} @t // CHECK: br i1 {{.*}} @@ -47,7 +47,7 @@ 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 ({{.*}} getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @_ZL2t2, i32 0, i32 0, i32 0), i64 6) +// CHECK: getelementptr inbounds (%struct.T, %struct.T* 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]]*), i32 0, i32 0, i32 0), i64 6) // CHECK: call void @_ZN1TD1Ev // CHECK: icmp eq {{.*}} @_ZL2t2 // CHECK: br i1 {{.*}} @@ -56,7 +56,7 @@ 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 ({{.*}}* getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @_ZGR1u_, i32 0, i32 0, i32 0), i64 6) +// CHECK: getelementptr inbounds (%struct.T, %struct.T* getelementptr inbounds ([2 x [3 x %struct.T]], [2 x [3 x %struct.T]]* @_ZGR1u_, i32 0, i32 0, i32 0), i64 6) // CHECK: call void @_ZN1TD1Ev // CHECK: icmp eq {{.*}} @_ZGR1u_ // CHECK: br i1 {{.*}}