[clang] [clang][bytecode] Fix initializer-list edge cases (PR #227587)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 30 00:13:32 PDT 2026


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/227587

Namely, initializer lists for primitive types and discarding the result of an initializer list.

>From 3cfe8607532cb7a2bfeff57b40b437b046e8b229 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Wed, 30 Sep 2026 09:11:52 +0200
Subject: [PATCH] [clang][bytecode] Fix initializer-list edge cases

Namely, initializer lists for primitive types and discarding the result
of an initializer list.
---
 clang/lib/AST/ByteCode/Compiler.cpp          | 23 +++++++++++++++++---
 clang/test/AST/ByteCode/initializer_list.cpp | 14 ++++++++++++
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index f7d2d202b2c9f..8ac06578bf54b 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -4908,8 +4908,16 @@ bool Compiler<Emitter>::VisitCXXStdInitializerListExpr(
   const ConstantArrayType *ArrayType =
       Ctx.getASTContext().getAsConstantArrayType(SubExpr->getType());
   const Record *R = getRecord(E->getType());
-  assert(Initializing);
   assert(SubExpr->isGLValue());
+  assert(!canClassify(E->getType()));
+
+  if (!Initializing) {
+    UnsignedOrNone LocalIndex = allocateLocal(E);
+    if (!LocalIndex)
+      return false;
+    if (!this->emitGetPtrLocal(*LocalIndex, E))
+      return false;
+  }
 
   if (!this->visit(SubExpr))
     return false;
@@ -4924,7 +4932,11 @@ bool Compiler<Emitter>::VisitCXXStdInitializerListExpr(
   if (isIntegerOrBoolType(SecondFieldT)) {
     if (!this->emitConst(ArrayType->getSize(), SecondFieldT, E))
       return false;
-    return this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E);
+    if (!this->emitInitField(SecondFieldT, R->getField(1u)->Offset, E))
+      return false;
+    if (DiscardResult)
+      return this->emitPopPtr(E);
+    return true;
   }
   assert(SecondFieldT == PT_Ptr);
 
@@ -4936,7 +4948,12 @@ bool Compiler<Emitter>::VisitCXXStdInitializerListExpr(
     return false;
   if (!this->emitArrayElemPtrPop(PT_Uint64, E))
     return false;
-  return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
+
+  if (!this->emitInitFieldPtr(R->getField(1u)->Offset, E))
+    return false;
+  if (DiscardResult)
+    return this->emitPopPtr(E);
+  return true;
 }
 
 template <class Emitter>
diff --git a/clang/test/AST/ByteCode/initializer_list.cpp b/clang/test/AST/ByteCode/initializer_list.cpp
index b3adefc580cc3..ea96cee756322 100644
--- a/clang/test/AST/ByteCode/initializer_list.cpp
+++ b/clang/test/AST/ByteCode/initializer_list.cpp
@@ -94,3 +94,17 @@ namespace CopiedForRangeIterator {
   }
   static_assert(copies() == 0);
 }
+
+namespace Primitive {
+  constexpr auto A = std::initializer_list<int>{42};
+  static_assert(A.size() == 1);
+  static_assert(*A.begin() == 42);
+}
+
+namespace Ignored {
+  constexpr int foo() {
+    std::initializer_list<int>{42}; // both-warning {{expression result unused}}
+    return 1;
+  }
+  static_assert(foo() == 1);
+}



More information about the cfe-commits mailing list