Skip to content

Conversation

@tbaederr
Copy link
Contributor

…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.

…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.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Feb 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 25, 2025

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

…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.


Full diff: https://github.com/llvm/llvm-project/pull/128729.diff

2 Files Affected:

  • (modified) clang/lib/AST/ByteCode/Compiler.cpp (+12-1)
  • (added) clang/test/AST/ByteCode/libcxx/make_unique.cpp (+34)
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());

@tbaederr tbaederr merged commit 3f64899 into llvm:main Feb 26, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants