@@ -20,7 +20,7 @@ using namespace clang;
2020using namespace clang ::interp;
2121
2222template <typename T>
23- static void ctorTy (Block *, std::byte *Ptr, bool , bool , bool ,
23+ static void ctorTy (Block *, std::byte *Ptr, bool , bool , bool , bool ,
2424 const Descriptor *) {
2525 new (Ptr) T ();
2626}
@@ -40,7 +40,7 @@ static void moveTy(Block *, const std::byte *Src, std::byte *Dst,
4040}
4141
4242template <typename T>
43- static void ctorArrayTy (Block *, std::byte *Ptr, bool , bool , bool ,
43+ static void ctorArrayTy (Block *, std::byte *Ptr, bool , bool , bool , bool ,
4444 const Descriptor *D) {
4545 new (Ptr) InitMapPtr (std::nullopt );
4646
@@ -83,7 +83,8 @@ static void moveArrayTy(Block *, const std::byte *Src, std::byte *Dst,
8383}
8484
8585static void ctorArrayDesc (Block *B, std::byte *Ptr, bool IsConst,
86- bool IsMutable, bool IsActive, const Descriptor *D) {
86+ bool IsMutable, bool IsActive, bool InUnion,
87+ const Descriptor *D) {
8788 const unsigned NumElems = D->getNumElems ();
8889 const unsigned ElemSize =
8990 D->ElemDesc ->getAllocSize () + sizeof (InlineDescriptor);
@@ -102,9 +103,11 @@ static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst,
102103 Desc->IsActive = IsActive;
103104 Desc->IsConst = IsConst || D->IsConst ;
104105 Desc->IsFieldMutable = IsMutable || D->IsMutable ;
106+ Desc->InUnion = InUnion;
107+
105108 if (auto Fn = D->ElemDesc ->CtorFn )
106109 Fn (B, ElemLoc, Desc->IsConst , Desc->IsFieldMutable , IsActive,
107- D->ElemDesc );
110+ Desc-> InUnion || SD-> isUnion (), D->ElemDesc );
108111 }
109112}
110113
@@ -146,25 +149,26 @@ static void moveArrayDesc(Block *B, const std::byte *Src, std::byte *Dst,
146149}
147150
148151static void initField (Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
149- bool IsActive, bool IsUnion, const Descriptor *D ,
150- unsigned FieldOffset) {
152+ bool IsActive, bool IsUnionField, bool InUnion ,
153+ const Descriptor *D, unsigned FieldOffset) {
151154 auto *Desc = reinterpret_cast <InlineDescriptor *>(Ptr + FieldOffset) - 1 ;
152155 Desc->Offset = FieldOffset;
153156 Desc->Desc = D;
154157 Desc->IsInitialized = D->IsArray ;
155158 Desc->IsBase = false ;
156- Desc->IsActive = IsActive && !IsUnion;
159+ Desc->IsActive = IsActive && !IsUnionField;
160+ Desc->InUnion = InUnion;
157161 Desc->IsConst = IsConst || D->IsConst ;
158162 Desc->IsFieldMutable = IsMutable || D->IsMutable ;
159163
160164 if (auto Fn = D->CtorFn )
161165 Fn (B, Ptr + FieldOffset, Desc->IsConst , Desc->IsFieldMutable ,
162- Desc->IsActive , D);
166+ Desc->IsActive , InUnion || D-> isUnion (), D);
163167}
164168
165169static void initBase (Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
166- bool IsActive, const Descriptor *D, unsigned FieldOffset ,
167- bool IsVirtualBase) {
170+ bool IsActive, bool InUnion, const Descriptor *D,
171+ unsigned FieldOffset, bool IsVirtualBase) {
168172 assert (D);
169173 assert (D->ElemRecord );
170174
@@ -180,21 +184,26 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
180184 Desc->IsFieldMutable = IsMutable || D->IsMutable ;
181185
182186 for (const auto &V : D->ElemRecord ->bases ())
183- initBase (B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, V. Desc ,
184- V.Offset , false );
187+ initBase (B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion ,
188+ V.Desc , V. Offset , false );
185189 for (const auto &F : D->ElemRecord ->fields ())
186- initField (B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, IsUnion ,
187- F.Desc , F.Offset );
190+ initField (B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion ,
191+ IsUnion, F.Desc , F.Offset );
188192}
189193
190194static void ctorRecord (Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
191- bool IsActive, const Descriptor *D) {
195+ bool IsActive, bool InUnion, const Descriptor *D) {
192196 for (const auto &V : D->ElemRecord ->bases ())
193- initBase (B, Ptr, IsConst, IsMutable, IsActive, V.Desc , V.Offset , false );
194- for (const auto &F : D->ElemRecord ->fields ())
195- initField (B, Ptr, IsConst, IsMutable, IsActive, D->ElemRecord ->isUnion (), F.Desc , F.Offset );
197+ initBase (B, Ptr, IsConst, IsMutable, IsActive, false , V.Desc , V.Offset ,
198+ false );
199+ for (const auto &F : D->ElemRecord ->fields ()) {
200+ bool IsUnionField = D->isUnion ();
201+ initField (B, Ptr, IsConst, IsMutable, IsActive, IsUnionField,
202+ InUnion || IsUnionField, F.Desc , F.Offset );
203+ }
196204 for (const auto &V : D->ElemRecord ->virtual_bases ())
197- initBase (B, Ptr, IsConst, IsMutable, IsActive, V.Desc , V.Offset , true );
205+ initBase (B, Ptr, IsConst, IsMutable, IsActive, false , V.Desc , V.Offset ,
206+ true );
198207}
199208
200209static void destroyField (Block *B, std::byte *Ptr, const Descriptor *D,
@@ -403,6 +412,8 @@ SourceLocation Descriptor::getLocation() const {
403412 llvm_unreachable (" Invalid descriptor type" );
404413}
405414
415+ bool Descriptor::isUnion () const { return isRecord () && ElemRecord->isUnion (); }
416+
406417InitMap::InitMap (unsigned N)
407418 : UninitFields(N), Data(std::make_unique<T[]>(numFields(N))) {
408419 std::fill_n (data (), numFields (N), 0 );
0 commit comments