[clang] 3f64899 - [clang][bytecode] Fix initing incomplete arrays from ImplicitValueIni… (#128729)

via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 25 23:14:03 PST 2025


Author: Timm Baeder
Date: 2025-02-26T08:14:00+01:00
New Revision: 3f648992bf317a3496c4d137374d2c1532423d1c

URL: https://github.com/llvm/llvm-project/commit/3f648992bf317a3496c4d137374d2c1532423d1c
DIFF: https://github.com/llvm/llvm-project/commit/3f648992bf317a3496c4d137374d2c1532423d1c.diff

LOG: [clang][bytecode] Fix initing incomplete arrays from ImplicitValueIni… (#128729)

…tExpr

If the ImplicitValueInitExpr is of incomplete array type, we ignore it
in its Visit function. This is a special case here, so pull out the
element type and zero the elements.

Added: 
    clang/test/AST/ByteCode/libcxx/make_unique.cpp

Modified: 
    clang/lib/AST/ByteCode/Compiler.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 74f5d6ebd9ca6..de0ce8b2644d3 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -3277,6 +3277,8 @@ bool Compiler<Emitter>::VisitCXXInheritedCtorInitExpr(
   return this->emitCall(F, 0, E);
 }
 
+// FIXME: This function has become rather unwieldy, especially
+// the part where we initialize an array allocation of dynamic size.
 template <class Emitter>
 bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) {
   assert(classifyPrim(E->getType()) == PT_Ptr);
@@ -3457,7 +3459,16 @@ bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) {
         if (!this->emitArrayElemPtr(SizeT, E))
           return false;
 
-        if (DynamicInit) {
+        if (isa_and_nonnull<ImplicitValueInitExpr>(DynamicInit) &&
+            DynamicInit->getType()->isArrayType()) {
+          QualType ElemType =
+              DynamicInit->getType()->getAsArrayTypeUnsafe()->getElementType();
+          PrimType InitT = classifyPrim(ElemType);
+          if (!this->visitZeroInitializer(InitT, ElemType, E))
+            return false;
+          if (!this->emitStorePop(InitT, E))
+            return false;
+        } else if (DynamicInit) {
           if (std::optional<PrimType> InitT = classify(DynamicInit)) {
             if (!this->visit(DynamicInit))
               return false;

diff  --git a/clang/test/AST/ByteCode/libcxx/make_unique.cpp b/clang/test/AST/ByteCode/libcxx/make_unique.cpp
new file mode 100644
index 0000000000000..f349b4b2b8238
--- /dev/null
+++ b/clang/test/AST/ByteCode/libcxx/make_unique.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++2c -fexperimental-new-constant-interpreter -verify=expected,both %s
+// RUN: %clang_cc1 -std=c++2c  -verify=ref,both %s
+
+/// This used to cause problems because the heap-allocated array
+/// is initialized by an ImplicitValueInitExpr of incomplete array type.
+
+inline namespace {
+template < class _Tp >
+using __add_lvalue_reference_t = __add_lvalue_reference(_Tp);
+template < class _Tp > using __remove_extent_t = __remove_extent(_Tp);
+}
+inline namespace {
+template < class > class unique_ptr;
+template < class _Tp > struct unique_ptr< _Tp[] > {
+_Tp *__ptr_;
+
+template <
+      class _Tag, class _Ptr>
+  constexpr unique_ptr(_Tag, _Ptr __ptr, unsigned) : __ptr_(__ptr){}
+  constexpr ~unique_ptr() { delete[] __ptr_; }
+  constexpr __add_lvalue_reference_t< _Tp >
+  operator[](decltype(sizeof(int)) __i) {
+    return __ptr_[__i];
+  }};
+constexpr unique_ptr< int[] > make_unique(decltype(sizeof(int)) __n) {
+  return unique_ptr< int[] >(int(), new __remove_extent_t< int>[__n](), __n);
+}}
+
+constexpr bool test() {
+  auto p1 = make_unique(5);
+  (p1[0] == 0); // both-warning {{expression result unused}}
+  return true;
+}
+static_assert(test());


        


More information about the cfe-commits mailing list