@@ -20,7 +20,7 @@ using namespace clang;
20
20
using namespace clang ::interp;
21
21
22
22
template <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 ,
24
24
const Descriptor *) {
25
25
new (Ptr ) T ();
26
26
}
@@ -40,7 +40,7 @@ static void moveTy(Block *, const std::byte *Src, std::byte *Dst,
40
40
}
41
41
42
42
template <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 ,
44
44
const Descriptor *D) {
45
45
new (Ptr ) InitMapPtr (std::nullopt);
46
46
@@ -83,7 +83,8 @@ static void moveArrayTy(Block *, const std::byte *Src, std::byte *Dst,
83
83
}
84
84
85
85
static 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) {
87
88
const unsigned NumElems = D->getNumElems ();
88
89
const unsigned ElemSize =
89
90
D->ElemDesc ->getAllocSize () + sizeof (InlineDescriptor);
@@ -102,9 +103,11 @@ static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst,
102
103
Desc->IsActive = IsActive;
103
104
Desc->IsConst = IsConst || D->IsConst ;
104
105
Desc->IsFieldMutable = IsMutable || D->IsMutable ;
106
+ Desc->InUnion = InUnion;
107
+
105
108
if (auto Fn = D->ElemDesc ->CtorFn )
106
109
Fn (B, ElemLoc, Desc->IsConst , Desc->IsFieldMutable , IsActive,
107
- D->ElemDesc );
110
+ Desc-> InUnion || SD-> isUnion (), D->ElemDesc );
108
111
}
109
112
}
110
113
@@ -146,25 +149,26 @@ static void moveArrayDesc(Block *B, const std::byte *Src, std::byte *Dst,
146
149
}
147
150
148
151
static 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) {
151
154
auto *Desc = reinterpret_cast <InlineDescriptor *>(Ptr + FieldOffset) - 1 ;
152
155
Desc->Offset = FieldOffset;
153
156
Desc->Desc = D;
154
157
Desc->IsInitialized = D->IsArray ;
155
158
Desc->IsBase = false ;
156
- Desc->IsActive = IsActive && !IsUnion;
159
+ Desc->IsActive = IsActive && !IsUnionField;
160
+ Desc->InUnion = InUnion;
157
161
Desc->IsConst = IsConst || D->IsConst ;
158
162
Desc->IsFieldMutable = IsMutable || D->IsMutable ;
159
163
160
164
if (auto Fn = D->CtorFn )
161
165
Fn (B, Ptr + FieldOffset, Desc->IsConst , Desc->IsFieldMutable ,
162
- Desc->IsActive , D);
166
+ Desc->IsActive , InUnion || D-> isUnion (), D);
163
167
}
164
168
165
169
static 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) {
168
172
assert (D);
169
173
assert (D->ElemRecord );
170
174
@@ -180,21 +184,26 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
180
184
Desc->IsFieldMutable = IsMutable || D->IsMutable ;
181
185
182
186
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 );
185
189
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 );
188
192
}
189
193
190
194
static 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) {
192
196
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
+ }
196
204
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 );
198
207
}
199
208
200
209
static void destroyField (Block *B, std::byte *Ptr , const Descriptor *D,
@@ -403,6 +412,8 @@ SourceLocation Descriptor::getLocation() const {
403
412
llvm_unreachable (" Invalid descriptor type" );
404
413
}
405
414
415
+ bool Descriptor::isUnion () const { return isRecord () && ElemRecord->isUnion (); }
416
+
406
417
InitMap::InitMap (unsigned N)
407
418
: UninitFields(N), Data(std::make_unique<T[]>(numFields(N))) {
408
419
std::fill_n (data (), numFields (N), 0 );
0 commit comments