llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> …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 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()); `````````` </details> https://github.com/llvm/llvm-project/pull/128729 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits