aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorHarald van Dijk <harald.vandijk@codeplay.com>2025-07-24 18:43:17 +0100
committerGitHub <noreply@github.com>2025-07-24 18:43:17 +0100
commit2228b4b46c3e45b5aab801a636041ed13ae47375 (patch)
tree0744587eae650a2c64592c6fb2c8a1bbd6dd61fa /clang/lib/CodeGen
parentd750c6de8a75cbe2bc16c136764195471be8f0b7 (diff)
downloadllvm-2228b4b46c3e45b5aab801a636041ed13ae47375.zip
llvm-2228b4b46c3e45b5aab801a636041ed13ae47375.tar.gz
llvm-2228b4b46c3e45b5aab801a636041ed13ae47375.tar.bz2
clang: Handle deleting pointers to incomplete array types (#150359)
CodeGenFunction::EmitCXXDeleteExpr contains logic to go from a pointer to an array to a pointer to the first element of the array using a getelementptr LLVM IR instruction. This was done for pointers that were not variable length arrays, as pointers to variable length arrays never existed in LLVM IR, but rather than checking for arrays that were not variable length arrays, it checked for arrays that had a constant bound. This caused incomplete arrays to be inadvertently omitted. This getelementptr was necessary back when LLVM IR used typed pointers, but they have been gone for a while, a gep with a constant zero offset does nothing now, so we can simplify the code by removing that.
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp27
1 files changed, 3 insertions, 24 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 359e30c..b8238a4 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -2146,30 +2146,9 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
return;
}
- // We might be deleting a pointer to array. If so, GEP down to the
- // first non-array element.
- // (this assumes that A(*)[3][7] is converted to [3 x [7 x %A]]*)
- if (DeleteTy->isConstantArrayType()) {
- llvm::Value *Zero = Builder.getInt32(0);
- SmallVector<llvm::Value*,8> GEP;
-
- GEP.push_back(Zero); // point at the outermost array
-
- // For each layer of array type we're pointing at:
- while (const ConstantArrayType *Arr
- = getContext().getAsConstantArrayType(DeleteTy)) {
- // 1. Unpeel the array type.
- DeleteTy = Arr->getElementType();
-
- // 2. GEP to the first element of the array.
- GEP.push_back(Zero);
- }
-
- Ptr = Builder.CreateInBoundsGEP(Ptr, GEP, ConvertTypeForMem(DeleteTy),
- Ptr.getAlignment(), "del.first");
- }
-
- assert(ConvertTypeForMem(DeleteTy) == Ptr.getElementType());
+ // We might be deleting a pointer to array.
+ DeleteTy = getContext().getBaseElementType(DeleteTy);
+ Ptr = Ptr.withElementType(ConvertTypeForMem(DeleteTy));
if (E->isArrayForm()) {
EmitArrayDelete(*this, E, Ptr, DeleteTy);