https://github.com/zwuis updated 
https://github.com/llvm/llvm-project/pull/179899

>From 16bc25e35bac87d7b1cedbe7ce9766fdb6498ace Mon Sep 17 00:00:00 2001
From: Yanzuo Liu <[email protected]>
Date: Thu, 5 Feb 2026 18:05:57 +0800
Subject: [PATCH 1/2] Fix reading union template parameter object

---
 clang/lib/AST/ByteCode/Compiler.cpp | 29 +++++++++++++++++++++++------
 clang/test/AST/ByteCode/cxx20.cpp   | 24 ++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index eb52112f16b82..673c603f27f4e 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5069,14 +5069,30 @@ bool Compiler<Emitter>::visitAPValueInitializer(const 
APValue &Val,
   }
   if (Val.isUnion()) {
     const FieldDecl *UnionField = Val.getUnionField();
-    const Record *R = this->getRecord(UnionField->getParent());
+    if (!UnionField)
+      // no active fields
+      return true;
+    const Record *R = this->getRecord(T);
     assert(R);
     const APValue &F = Val.getUnionValue();
     const Record::Field *RF = R->getField(UnionField);
-    PrimType T = classifyPrim(RF->Decl->getType());
-    if (!this->visitAPValue(F, T, E))
+    QualType FieldType = RF->Decl->getType();
+
+    if (OptPrimType PT = classify(FieldType)) {
+      if (!this->visitAPValue(F, *PT, E))
+        return false;
+      if (RF->isBitField())
+        return this->emitInitBitFieldActivate(*PT, RF, E);
+      return this->emitInitFieldActivate(*PT, RF->Offset, E);
+    }
+
+    if (!this->emitGetPtrField(RF->Offset, E))
       return false;
-    return this->emitInitField(T, RF->Offset, E);
+    if (!this->emitActivate(E))
+      return false;
+    if (!this->visitAPValueInitializer(F, E, FieldType))
+      return false;
+    return this->emitPopPtr(E);
   }
   if (Val.isArray()) {
     const auto *ArrType = T->getAsArrayTypeUnsafe();
@@ -7126,8 +7142,9 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, 
const Expr *E) {
           return false;
         return this->emitInitGlobal(*T, *Index, E);
       }
-      return this->visitAPValueInitializer(TPOD->getValue(), E,
-                                           TPOD->getType());
+      if (!this->visitAPValueInitializer(TPOD->getValue(), E, TPOD->getType()))
+        return false;
+      return this->emitFinishInit(E);
     }
     return false;
   }
diff --git a/clang/test/AST/ByteCode/cxx20.cpp 
b/clang/test/AST/ByteCode/cxx20.cpp
index 2abe8dd120e6f..139b6c873adce 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -785,6 +785,30 @@ namespace APValues {
   constexpr const A &w = get<A{1, &g, &A::n, "hello"}>;
 }
 
+namespace InitFromAPValues {
+  template <auto a> struct S {
+    static constexpr auto &ref = a;
+  };
+
+  union U1 { int x, y; };
+  static_assert(S<U1{1}>::ref.x == 1);
+  static_assert(S<U1{1}>::ref.y == 1); // both-error {{static assertion 
expression is not an integral constant expression}} \
+                                       // both-note {{read of member 'y' of 
union with active member 'x' is not allowed in a constant expression}}
+
+  union U2 {
+    bool x;
+    constexpr U2() {}
+  };
+  static_assert(S<U2{}>::ref.x); // both-error {{static assertion expression 
is not an integral constant expression}} \
+                                 // both-note {{read of member 'x' of union 
with no active member is not allowed in a constant expression}}
+
+  union U3 {
+    struct S { int x; };
+    S s;
+  };
+  static_assert(S<U3{2}>::ref.s.x == 2);
+}
+
 namespace self_referencing {
   struct S {
     S* ptr = nullptr;

>From 1067dd4c2233f32d99e0b965f77d3d155a502342 Mon Sep 17 00:00:00 2001
From: Yanzuo Liu <[email protected]>
Date: Thu, 5 Feb 2026 22:19:48 +0800
Subject: [PATCH 2/2] Update clang/lib/AST/ByteCode/Compiler.cpp

Co-authored-by: Timm Baeder <[email protected]>
---
 clang/lib/AST/ByteCode/Compiler.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 673c603f27f4e..a0138c402e143 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5070,7 +5070,6 @@ bool Compiler<Emitter>::visitAPValueInitializer(const 
APValue &Val,
   if (Val.isUnion()) {
     const FieldDecl *UnionField = Val.getUnionField();
     if (!UnionField)
-      // no active fields
       return true;
     const Record *R = this->getRecord(T);
     assert(R);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to