[clang] 5f70043 - [clang] Fix filler handling for new expression with unspecified bound. (#182203)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 6 10:29:37 PST 2026
Author: Eli Friedman
Date: 2026-03-06T10:29:31-08:00
New Revision: 5f70043ac22f4b1de86f1fa141859bcec3e16531
URL: https://github.com/llvm/llvm-project/commit/5f70043ac22f4b1de86f1fa141859bcec3e16531
DIFF: https://github.com/llvm/llvm-project/commit/5f70043ac22f4b1de86f1fa141859bcec3e16531.diff
LOG: [clang] Fix filler handling for new expression with unspecified bound. (#182203)
Array new with a runtime bound requires an "array filler" to initialize
elements which aren't explicitly initialized. Array new with an
unspecified bound doesn't need this; the array length is a compile-time
constant. Make sure SemaInit doesn't confuse the two cases.
Fixes #81157.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Sema/Initialization.h
clang/lib/Sema/SemaExprCXX.cpp
clang/test/SemaCXX/new-delete.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 863c7392f7565..5d07bfc210e05 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -346,6 +346,7 @@ Bug Fixes to C++ Support
and produce a warning. (#GH162640)
- Fix initialization of GRO when GRO-return type mismatches, as part of CWG2563. (#GH98744)
+- Fix an error using an initializer list with array new for a type that is not default-constructible. (#GH81157)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h
index 0e2891f1ff5c2..1978ac41c58a4 100644
--- a/clang/include/clang/Sema/Initialization.h
+++ b/clang/include/clang/Sema/Initialization.h
@@ -160,6 +160,10 @@ class alignas(8) InitializedEntity {
/// Whether the entity being initialized may end up using the
/// named return value optimization (NRVO).
bool NRVO;
+
+ /// When Kind == EK_New, whether this is initializing an array of runtime
+ /// size (which needs an array filler).
+ bool VariableLengthArrayNew;
};
struct VD {
@@ -227,11 +231,12 @@ class alignas(8) InitializedEntity {
/// function, throwing an object, performing an explicit cast, or
/// initializing a parameter for which there is no declaration.
InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
- bool NRVO = false)
+ bool NRVO = false, bool VariableLengthArrayNew = false)
: Kind(Kind), Type(Type) {
new (&LocAndNRVO) LN;
LocAndNRVO.Location = Loc;
LocAndNRVO.NRVO = NRVO;
+ LocAndNRVO.VariableLengthArrayNew = VariableLengthArrayNew;
}
/// Create the initialization entity for a member subobject.
@@ -335,8 +340,10 @@ class alignas(8) InitializedEntity {
}
/// Create the initialization entity for an object allocated via new.
- static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) {
- return InitializedEntity(EK_New, NewLoc, Type);
+ static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type,
+ bool VariableLengthArrayNew) {
+ return InitializedEntity(EK_New, NewLoc, Type, /*NRVO=*/false,
+ VariableLengthArrayNew);
}
/// Create the initialization entity for a temporary.
@@ -506,8 +513,7 @@ class alignas(8) InitializedEntity {
/// Determine whether this is an array new with an unknown bound.
bool isVariableLengthArrayNew() const {
- return getKind() == EK_New && isa_and_nonnull<IncompleteArrayType>(
- getType()->getAsArrayTypeUnsafe());
+ return getKind() == EK_New && LocAndNRVO.VariableLengthArrayNew;
}
/// Is this the implicit initialization of a member of a class from
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 31b3a06bf10d0..5a5bbf4d900dc 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -2206,8 +2206,9 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
<< /*array*/ 2
<< (*ArraySize ? (*ArraySize)->getSourceRange() : TypeRange));
- InitializedEntity Entity
- = InitializedEntity::InitializeNew(StartLoc, AllocType);
+ InitializedEntity Entity =
+ InitializedEntity::InitializeNew(StartLoc, AllocType,
+ /*VariableLengthArrayNew=*/false);
AllocType = DeduceTemplateSpecializationFromInitializer(
AllocTypeInfo, Entity, Kind, Exprs);
if (AllocType.isNull())
@@ -2589,8 +2590,9 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
else
InitType = AllocType;
- InitializedEntity Entity
- = InitializedEntity::InitializeNew(StartLoc, InitType);
+ bool VariableLengthArrayNew = ArraySize && *ArraySize && !KnownArraySize;
+ InitializedEntity Entity = InitializedEntity::InitializeNew(
+ StartLoc, InitType, VariableLengthArrayNew);
InitializationSequence InitSeq(*this, Entity, Kind, Exprs);
ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, Exprs);
if (FullInit.isInvalid())
diff --git a/clang/test/SemaCXX/new-delete.cpp b/clang/test/SemaCXX/new-delete.cpp
index 1adb993f46c8f..2a2f91186871e 100644
--- a/clang/test/SemaCXX/new-delete.cpp
+++ b/clang/test/SemaCXX/new-delete.cpp
@@ -725,3 +725,19 @@ int (*const_fold)[12] = new int[3][&const_fold + 12 - &const_fold];
// expected-error at -5 {{cannot allocate object of variably modified type}}
// expected-warning at -6 {{variable length arrays in C++ are a Clang extension}}
#endif
+
+#if __cplusplus >= 201103L
+namespace PR81157 {
+ struct C { // #implicit-ctor
+ C(int); // #ctor
+ };
+ int f(int n) {
+ C *ptr1{new C[]{1L}};
+ C *ptr2{new C[n]{1L}};
+ // expected-error at -1 {{no matching constructor}}
+ // expected-note@#ctor {{candidate constructor}}
+ // expected-note@#implicit-ctor 2 {{candidate constructor}}
+ // expected-note at -4 {{in implicit initialization of trailing array elements in runtime-sized array new}}
+ }
+}
+#endif
More information about the cfe-commits
mailing list