Skip to content

Commit c309dc6

Browse files
authored
[Clang][Sema] placement new initializes typedef array with correct size (#83124)
When in-place new-ing a local variable of an array of trivial type, the generated code calls 'memset' with the correct size of the array, earlier it was generating size (squared of the typedef array + size). The cause: `typedef TYPE TArray[8]; TArray x;` The type of declarator is Tarray[8] and in `SemaExprCXX.cpp::BuildCXXNew` we check if it's of typedef and of constant size then we get the original type and it works fine for non-dependent cases. But in case of template we do `TreeTransform.h:TransformCXXNEWExpr` and there we again check the allocated type which is TArray[8] and it stays that way, so ArraySize=(Tarray[8] type, alloc Tarray[8*type]) so the squared size allocation. ArraySize gets calculated earlier in `TreeTransform.h` so that `if(!ArraySize)` condition was failing. fix: I changed that condition to `if(ArraySize)`. Fixes #41441
1 parent d4602a9 commit c309dc6

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,8 @@ Bug Fixes to C++ Support
539539
Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), (#GH86398), and (#GH86399).
540540
- Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329).
541541
- Fix a crash in requires expression with templated base class member function. Fixes (#GH84020).
542+
- placement new initializes typedef array with correct size
543+
(`#GH41441 <https://github.com/llvm/llvm-project/issues/41441>`_)
542544

543545
Bug Fixes to AST Handling
544546
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/TreeTransform.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12802,6 +12802,19 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
1280212802
ArraySize = NewArraySize.get();
1280312803
}
1280412804

12805+
// Per C++0x [expr.new]p5, the type being constructed may be a
12806+
// typedef of an array type.
12807+
QualType AllocType = AllocTypeInfo->getType();
12808+
if (ArraySize) {
12809+
if (const ConstantArrayType *Array =
12810+
SemaRef.Context.getAsConstantArrayType(AllocType)) {
12811+
ArraySize = IntegerLiteral::Create(SemaRef.Context, Array->getSize(),
12812+
SemaRef.Context.getSizeType(),
12813+
E->getBeginLoc());
12814+
AllocType = Array->getElementType();
12815+
}
12816+
}
12817+
1280512818
// Transform the placement arguments (if any).
1280612819
bool ArgumentChanged = false;
1280712820
SmallVector<Expr*, 8> PlacementArgs;
@@ -12863,7 +12876,6 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
1286312876
return E;
1286412877
}
1286512878

12866-
QualType AllocType = AllocTypeInfo->getType();
1286712879
if (!ArraySize) {
1286812880
// If no array size was specified, but the new expression was
1286912881
// instantiated with an array type (e.g., "new T" where T is
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %clang -S -fno-discard-value-names -emit-llvm -o - %s | FileCheck %s
2+
// Issue no: 41441
3+
#include <new>
4+
5+
// CHECK: call void @llvm.memset.p0.i64(ptr align 1 %x, i8 0, i64 8, i1 false)
6+
// CHECK: call void @llvm.memset.p0.i64(ptr align 16 %x, i8 0, i64 32, i1 false)
7+
template <typename TYPE>
8+
void f()
9+
{
10+
typedef TYPE TArray[8];
11+
12+
TArray x;
13+
new(&x) TArray();
14+
}
15+
16+
int main()
17+
{
18+
f<char>();
19+
f<int>();
20+
}

0 commit comments

Comments
 (0)