Skip to content

[clang][bytecode] Fix initing incomplete arrays from ImplicitValueIni… #128729

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 26, 2025

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