llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Eli Friedman (efriedma-quic) <details> <summary>Changes</summary> 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. --- Full diff: https://github.com/llvm/llvm-project/pull/182203.diff 3 Files Affected: - (modified) clang/include/clang/Sema/Initialization.h (+11-5) - (modified) clang/lib/Sema/SemaExprCXX.cpp (+6-4) - (modified) clang/test/SemaCXX/new-delete.cpp (+16) ``````````diff diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index 0e2891f1ff5c2..cd729aa16dc28 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 91967a7a9ff97..a1e95dbe676de 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..cda49a02098b0 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@-5 {{cannot allocate object of variably modified type}} // expected-warning@-6 {{variable length arrays in C++ are a Clang extension}} #endif + +#if __cplusplus >= 201103L +namespace PR81157 { + struct C { + C(int); + }; + int f(int n) { + C *ptr1{new C[]{1L}}; + C *ptr2{new C[n]{1L}}; + // expected-error@-1 {{no matching constructor}} + // expected-note@-6 {{candidate constructor}} + // expected-note@-8 2 {{candidate constructor}} + // expected-note@-4 {{in implicit initialization of trailing array elements in runtime-sized array new}} + } +} +#endif `````````` </details> https://github.com/llvm/llvm-project/pull/182203 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
