Skip to content

Commit

Permalink
[CodeGen] Make element type in emitArrayDestroy() predictable
Browse files Browse the repository at this point in the history
When calling emitArrayDestroy(), the pointer will usually have
ConvertTypeForMem(EltType) as the element type, as one would expect.
However, globals with initializers sometimes don't use the same
types as values normally would, e.g. here the global uses
{ double, i32 } rather than %struct.T as element type.

Add an early cast to the global destruction path to avoid this
special case. The cast would happen lateron anyway, it only gets
moved to an earlier point.

Differential Revision: https://reviews.llvm.org/D116219
  • Loading branch information
nikic committed Jan 11, 2022
1 parent 065e032 commit 2d1b55e
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 6 deletions.
7 changes: 4 additions & 3 deletions clang/lib/CodeGen/CGDecl.cpp
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGDeclCXX.cpp
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CodeGenCXX/global-array-destruction.cpp
Expand Up @@ -39,15 +39,15 @@ 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 {{.*}}

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 {{.*}}
Expand All @@ -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 {{.*}}

0 comments on commit 2d1b55e

Please sign in to comment.