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

Reply via email to