Author: Timm Baeder Date: 2026-01-09T16:35:07+01:00 New Revision: 3c51ed98701aa08c5fedb6d779530ff25efb6a81
URL: https://github.com/llvm/llvm-project/commit/3c51ed98701aa08c5fedb6d779530ff25efb6a81 DIFF: https://github.com/llvm/llvm-project/commit/3c51ed98701aa08c5fedb6d779530ff25efb6a81.diff LOG: [clang][bytecode] Fix initializing array elems from string (#175170) In the `= {"foo"}` case, we don't have an array filler we can use and we need to explicitily zero the remaining elements. Added: Modified: clang/lib/AST/ByteCode/Compiler.cpp clang/test/AST/ByteCode/new-delete.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index cbee7691565a9..b68576158decc 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -3685,34 +3685,42 @@ bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) { QualType InitType = Init->getType(); size_t StaticInitElems = 0; const Expr *DynamicInit = nullptr; + OptPrimType ElemT; + if (const ConstantArrayType *CAT = Ctx.getASTContext().getAsConstantArrayType(InitType)) { StaticInitElems = CAT->getZExtSize(); + // Initialize the first S element from the initializer. if (!this->visitInitializer(Init)) return false; - if (const auto *ILE = dyn_cast<InitListExpr>(Init); - ILE && ILE->hasArrayFiller()) - DynamicInit = ILE->getArrayFiller(); + if (const auto *ILE = dyn_cast<InitListExpr>(Init)) { + if (ILE->hasArrayFiller()) + DynamicInit = ILE->getArrayFiller(); + else if (isa<StringLiteral>(ILE->getInit(0))) + ElemT = classifyPrim(CAT->getElementType()); + } } // The initializer initializes a certain number of elements, S. // However, the complete number of elements, N, might be larger than that. // In this case, we need to get an initializer for the remaining elements. - // There are to cases: + // There are three cases: // 1) For the form 'new Struct[n];', the initializer is a // CXXConstructExpr and its type is an IncompleteArrayType. // 2) For the form 'new Struct[n]{1,2,3}', the initializer is an // InitListExpr and the initializer for the remaining elements // is the array filler. + // 3) StringLiterals don't have an array filler, so we need to zero + // the remaining elements. - if (DynamicInit || InitType->isIncompleteArrayType()) { + if (DynamicInit || ElemT || InitType->isIncompleteArrayType()) { const Function *CtorFunc = nullptr; if (const auto *CE = dyn_cast<CXXConstructExpr>(Init)) { CtorFunc = getFunction(CE->getConstructor()); if (!CtorFunc) return false; - } else if (!DynamicInit) + } else if (!DynamicInit && !ElemT) DynamicInit = Init; LabelTy EndLabel = this->getLabel(); @@ -3778,6 +3786,13 @@ bool Compiler<Emitter>::VisitCXXNewExpr(const CXXNewExpr *E) { if (!this->emitPopPtr(E)) return false; } + } else if (ElemT) { + if (!this->visitZeroInitializer( + *ElemT, InitType->getAsArrayTypeUnsafe()->getElementType(), + Init)) + return false; + if (!this->emitStorePop(*ElemT, E)) + return false; } else { assert(CtorFunc); if (!this->emitCall(CtorFunc, 0, E)) diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp index 9345946a31e99..e88e970c63ba4 100644 --- a/clang/test/AST/ByteCode/new-delete.cpp +++ b/clang/test/AST/ByteCode/new-delete.cpp @@ -763,7 +763,7 @@ namespace Limits { return n; } static_assert(dynarray<char>(5, 0) == 'f'); - + static_assert(dynarray<char>(5, 4) == 0); #if __LP64__ template <typename T> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
