Skip to content

Commit c558cf6

Browse files
committed
Commit progress
1 parent b4a8a03 commit c558cf6

File tree

4 files changed

+71
-4
lines changed

4 files changed

+71
-4
lines changed

clang/lib/CIR/CodeGen/Address.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,18 @@ class Address {
183183
template <typename T> T getDefiningOp() const {
184184
return mlir::dyn_cast_or_null<T>(getDefiningOp());
185185
}
186+
187+
/// Return address with different element type, but same pointer and
188+
/// alignment.
189+
Address withElementType(mlir::Type elemTy) const {
190+
if (!hasOffset())
191+
return Address(getBasePointer(), elemTy, getAlignment(),
192+
getPointerAuthInfo(), /*Offset=*/nullptr,
193+
isKnownNonNull());
194+
Address a(*this);
195+
a.ElementType = elemTy;
196+
return a;
197+
}
186198
};
187199

188200
} // namespace clang::CIRGen

clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,36 @@ bool CIRGenCXXABI::requiresArrayCookie(const CXXNewExpr *E) {
104104

105105
return E->getAllocatedType().isDestructedType();
106106
}
107+
108+
bool CIRGenCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
109+
QualType elementType) {
110+
// If the class's usual deallocation function takes two arguments,
111+
// it needs a cookie.
112+
if (expr->doesUsualArrayDeleteWantSize())
113+
return true;
114+
115+
return elementType.isDestructedType();
116+
}
117+
118+
void CIRGenCXXABI::readArrayCookie(CIRGenFunction &cgf, Address ptr,
119+
const CXXDeleteExpr *expr, QualType eltTy,
120+
mlir::Value &numElements,
121+
mlir::Value &allocPtr,
122+
CharUnits &cookieSize) {
123+
// Derive a char* in the same address space as the pointer.
124+
ptr = ptr.withElementType(cgf.UInt8Ty);
125+
126+
// If we don't need an array cookie, bail out early.
127+
if (!requiresArrayCookie(expr, eltTy)) {
128+
allocPtr = ptr.emitRawPointer();
129+
numElements = nullptr;
130+
cookieSize = CharUnits::Zero();
131+
return;
132+
}
133+
134+
cookieSize = getArrayCookieSizeImpl(eltTy);
135+
Address allocAddr =
136+
cgf.getBuilder().CreateConstInBoundsByteGEP(ptr, -cookieSize);
137+
allocPtr = allocAddr.emitRawPointer();
138+
numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize);
139+
}

clang/lib/CIR/CodeGen/CIRGenCXXABI.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class CIRGenCXXABI {
3939
clang::ASTContext &getContext() const { return CGM.getASTContext(); }
4040

4141
virtual bool requiresArrayCookie(const CXXNewExpr *E);
42+
virtual bool requiresArrayCookie(const CXXDeleteExpr *e, QualType eltType);
4243

4344
public:
4445
/// Similar to AddedStructorArgs, but only notes the number of additional
@@ -403,6 +404,24 @@ class CIRGenCXXABI {
403404
const CXXNewExpr *E,
404405
QualType ElementType) = 0;
405406

407+
/// Reads the array cookie associated with the given pointer,
408+
/// if it has one.
409+
///
410+
/// \param ptr - a pointer to the first element in the array
411+
/// \param elementType - the base element type of elements of the array
412+
/// \param numElements - an out parameter which will be initialized
413+
/// with the number of elements allocated, or zero if there is no
414+
/// cookie
415+
/// \param allocPtr - an out parameter which will be initialized
416+
/// with a char* pointing to the address returned by the allocation
417+
/// function
418+
/// \param cookieSize - an out parameter which will be initialized
419+
/// with the size of the cookie, or zero if there is no cookie
420+
virtual void readArrayCookie(CIRGenFunction &cgf, Address ptr,
421+
const CXXDeleteExpr *expr, QualType elementType,
422+
mlir::Value &numElements, mlir::Value &allocPtr,
423+
CharUnits &cookieSize);
424+
406425
protected:
407426
/// Returns the extra size required in order to store the array
408427
/// cookie for the given type. Assumes that an array cookie is

clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,10 +1305,10 @@ struct CallArrayDelete final : EHScopeStack::Cleanup {
13051305
/// Emit the code for deleting an array of objects.
13061306
static void EmitArrayDelete(CIRGenFunction &CGF, const CXXDeleteExpr *E,
13071307
Address deletedPtr, QualType elementType) {
1308-
mlir::Value *numElements = nullptr;
1309-
mlir::Value *allocatedPtr = nullptr;
1308+
mlir::Value numElements = nullptr;
1309+
mlir::Value allocatedPtr = nullptr;
13101310
CharUnits cookieSize;
1311-
CGF.CGM.getCXXABI().ReadArrayCookie(CGF, deletedPtr, E, elementType,
1311+
CGF.CGM.getCXXABI().readArrayCookie(CGF, deletedPtr, E, elementType,
13121312
numElements, allocatedPtr, cookieSize);
13131313

13141314
assert(allocatedPtr && "ReadArrayCookie didn't set allocated pointer");
@@ -1328,11 +1328,14 @@ static void EmitArrayDelete(CIRGenFunction &CGF, const CXXDeleteExpr *E,
13281328
deletedPtr.getAlignment().alignmentOfArrayElement(elementSize);
13291329

13301330
mlir::Value arrayBegin = deletedPtr.emitRawPointer();
1331+
auto loc = CGF.getLoc(E->getBeginLoc());
1332+
mlir::Value arrayEnd =
1333+
CGF.getBuilder().createPtrStride(loc, arrayBegin, *numElements);
13311334

13321335
// Note that it is legal to allocate a zero-length array, and we
13331336
// can never fold the check away because the length should always
13341337
// come from a cookie.
1335-
CGF.emitArrayDestroy(arrayBegin, *numElements, elementType, elementAlign,
1338+
CGF.emitArrayDestroy(arrayBegin, arrayEnd, elementType, elementAlign,
13361339
CGF.getDestroyer(dtorKind),
13371340
/*checkZeroLength*/ true,
13381341
CGF.needsEHCleanup(dtorKind));

0 commit comments

Comments
 (0)