@@ -80,7 +80,7 @@ static void swapBytes(std::byte *M, size_t N) {
80
80
// / We use this to recursively iterate over all fields and elements of a pointer
81
81
// / and extract relevant data for a bitcast.
82
82
static bool enumerateData (const Pointer &P, const Context &Ctx, Bits Offset,
83
- DataFunc F) {
83
+ Bits BitsToRead, DataFunc F) {
84
84
const Descriptor *FieldDesc = P.getFieldDesc ();
85
85
assert (FieldDesc);
86
86
@@ -97,9 +97,11 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset,
97
97
bool PackedBools = FieldDesc->getType ()->isExtVectorBoolType ();
98
98
unsigned NumElems = FieldDesc->getNumElems ();
99
99
bool Ok = true ;
100
- for (unsigned I = 0 ; I != NumElems; ++I) {
100
+ for (unsigned I = P. getIndex () ; I != NumElems; ++I) {
101
101
Ok = Ok && F (P.atIndex (I), ElemT, Offset, PackedBools);
102
102
Offset += PackedBools ? 1 : ElemSizeInBits;
103
+ if (Offset >= BitsToRead)
104
+ break ;
103
105
}
104
106
return Ok;
105
107
}
@@ -109,8 +111,10 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset,
109
111
QualType ElemType = FieldDesc->getElemQualType ();
110
112
size_t ElemSizeInBits = Ctx.getASTContext ().getTypeSize (ElemType);
111
113
for (unsigned I = 0 ; I != FieldDesc->getNumElems (); ++I) {
112
- enumerateData (P.atIndex (I).narrow (), Ctx, Offset, F);
114
+ enumerateData (P.atIndex (I).narrow (), Ctx, Offset, BitsToRead, F);
113
115
Offset += ElemSizeInBits;
116
+ if (Offset >= BitsToRead)
117
+ break ;
114
118
}
115
119
return true ;
116
120
}
@@ -126,14 +130,14 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset,
126
130
Pointer Elem = P.atField (Fi.Offset );
127
131
Bits BitOffset =
128
132
Offset + Bits (Layout.getFieldOffset (Fi.Decl ->getFieldIndex ()));
129
- Ok = Ok && enumerateData (Elem, Ctx, BitOffset, F);
133
+ Ok = Ok && enumerateData (Elem, Ctx, BitOffset, BitsToRead, F);
130
134
}
131
135
for (const Record::Base &B : R->bases ()) {
132
136
Pointer Elem = P.atField (B.Offset );
133
137
CharUnits ByteOffset =
134
138
Layout.getBaseClassOffset (cast<CXXRecordDecl>(B.Decl ));
135
139
Bits BitOffset = Offset + Bits (Ctx.getASTContext ().toBits (ByteOffset));
136
- Ok = Ok && enumerateData (Elem, Ctx, BitOffset, F);
140
+ Ok = Ok && enumerateData (Elem, Ctx, BitOffset, BitsToRead, F);
137
141
}
138
142
139
143
return Ok;
@@ -143,8 +147,8 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset,
143
147
}
144
148
145
149
static bool enumeratePointerFields (const Pointer &P, const Context &Ctx,
146
- DataFunc F) {
147
- return enumerateData (P, Ctx, Bits::zero (), F);
150
+ Bits BitsToRead, DataFunc F) {
151
+ return enumerateData (P, Ctx, Bits::zero (), BitsToRead, F);
148
152
}
149
153
150
154
// This function is constexpr if and only if To, From, and the types of
@@ -222,7 +226,7 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
222
226
ASTCtx.getTargetInfo ().isLittleEndian () ? Endian::Little : Endian::Big;
223
227
224
228
return enumeratePointerFields (
225
- FromPtr, Ctx,
229
+ FromPtr, Ctx, Buffer. size (),
226
230
[&](const Pointer &P, PrimType T, Bits BitOffset,
227
231
bool PackedBools) -> bool {
228
232
// if (!P.isInitialized()) {
@@ -327,7 +331,7 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
327
331
Endian TargetEndianness =
328
332
ASTCtx.getTargetInfo ().isLittleEndian () ? Endian::Little : Endian::Big;
329
333
bool Success = enumeratePointerFields (
330
- ToPtr, S.getContext (),
334
+ ToPtr, S.getContext (), Buffer. size (),
331
335
[&](const Pointer &P, PrimType T, Bits BitOffset,
332
336
bool PackedBools) -> bool {
333
337
CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars (P.getType ());
0 commit comments