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
