[clang] [clang][bytecode] Fix initing incomplete arrays from ImplicitValueIni… (PR #128729)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 25 07:37:25 PST 2025
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/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.
>From 86c68bb2af543829af3cbbfe9c9bb6055faa0ce0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 25 Feb 2025 16:18:57 +0100
Subject: [PATCH] [clang][bytecode] Fix initing incomplete arrays from
ImplicitValueInitExpr
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.
---
clang/lib/AST/ByteCode/Compiler.cpp | 13 ++++++-
.../test/AST/ByteCode/libcxx/make_unique.cpp | 34 +++++++++++++++++++
2 files changed, 46 insertions(+), 1 deletion(-)
create mode 100644 clang/test/AST/ByteCode/libcxx/make_unique.cpp
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