Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- BitstreamReader.cpp - BitstreamReader implementation ---------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "llvm/Bitstream/BitstreamReader.h"
10
#include "llvm/ADT/StringRef.h"
11
#include <cassert>
12
#include <optional>
13
#include <string>
14
15
using namespace llvm;
16
17
//===----------------------------------------------------------------------===//
18
//  BitstreamCursor implementation
19
//===----------------------------------------------------------------------===//
20
//
21
2.06k
static Error error(const char *Message) {
22
2.06k
  return createStringError(std::errc::illegal_byte_sequence, Message);
23
2.06k
}
24
25
/// Having read the ENTER_SUBBLOCK abbrevid, enter the block.
26
4.33M
Error BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
27
  // Save the current block's state on BlockScope.
28
4.33M
  BlockScope.push_back(Block(CurCodeSize));
29
4.33M
  BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
30
31
  // Add the abbrevs specific to this block to the CurAbbrevs list.
32
4.33M
  if (BlockInfo) {
33
3.97M
    if (const BitstreamBlockInfo::BlockInfo *Info =
34
3.97M
            BlockInfo->getBlockInfo(BlockID)) {
35
2.88M
      llvm::append_range(CurAbbrevs, Info->Abbrevs);
36
2.88M
    }
37
3.97M
  }
38
39
  // Get the codesize of this block.
40
4.33M
  Expected<uint32_t> MaybeVBR = ReadVBR(bitc::CodeLenWidth);
41
4.33M
  if (!MaybeVBR)
42
16
    return MaybeVBR.takeError();
43
4.33M
  CurCodeSize = MaybeVBR.get();
44
45
4.33M
  if (CurCodeSize > MaxChunkSize)
46
155
    return llvm::createStringError(
47
155
        std::errc::illegal_byte_sequence,
48
155
        "can't read more than %zu at a time, trying to read %u", +MaxChunkSize,
49
155
        CurCodeSize);
50
51
4.33M
  SkipToFourByteBoundary();
52
4.33M
  Expected<word_t> MaybeNum = Read(bitc::BlockSizeWidth);
53
4.33M
  if (!MaybeNum)
54
70
    return MaybeNum.takeError();
55
4.33M
  word_t NumWords = MaybeNum.get();
56
4.33M
  if (NumWordsP)
57
0
    *NumWordsP = NumWords;
58
59
4.33M
  if (CurCodeSize == 0)
60
264
    return llvm::createStringError(
61
264
        std::errc::illegal_byte_sequence,
62
264
        "can't enter sub-block: current code size is 0");
63
4.33M
  if (AtEndOfStream())
64
66
    return llvm::createStringError(
65
66
        std::errc::illegal_byte_sequence,
66
66
        "can't enter sub block: already at end of stream");
67
68
4.33M
  return Error::success();
69
4.33M
}
70
71
static Expected<uint64_t> readAbbreviatedField(BitstreamCursor &Cursor,
72
40.8M
                                               const BitCodeAbbrevOp &Op) {
73
40.8M
  assert(!Op.isLiteral() && "Not to be used with literals!");
74
75
  // Decode the value as we are commanded.
76
0
  switch (Op.getEncoding()) {
77
0
  case BitCodeAbbrevOp::Array:
78
0
  case BitCodeAbbrevOp::Blob:
79
0
    llvm_unreachable("Should not reach here");
80
13.3M
  case BitCodeAbbrevOp::Fixed:
81
13.3M
    assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
82
0
    return Cursor.Read((unsigned)Op.getEncodingData());
83
27.5M
  case BitCodeAbbrevOp::VBR:
84
27.5M
    assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
85
0
    return Cursor.ReadVBR64((unsigned)Op.getEncodingData());
86
13.0k
  case BitCodeAbbrevOp::Char6:
87
13.0k
    if (Expected<unsigned> Res = Cursor.Read(6))
88
12.9k
      return BitCodeAbbrevOp::DecodeChar6(Res.get());
89
15
    else
90
15
      return Res.takeError();
91
40.8M
  }
92
0
  llvm_unreachable("invalid abbreviation encoding");
93
0
}
94
95
/// skipRecord - Read the current record and discard it.
96
25.2k
Expected<unsigned> BitstreamCursor::skipRecord(unsigned AbbrevID) {
97
  // Skip unabbreviated records by reading past their entries.
98
25.2k
  if (AbbrevID == bitc::UNABBREV_RECORD) {
99
25.2k
    Expected<uint32_t> MaybeCode = ReadVBR(6);
100
25.2k
    if (!MaybeCode)
101
35
      return MaybeCode.takeError();
102
25.2k
    unsigned Code = MaybeCode.get();
103
25.2k
    Expected<uint32_t> MaybeVBR = ReadVBR(6);
104
25.2k
    if (!MaybeVBR)
105
30
      return MaybeVBR.takeError();
106
25.2k
    unsigned NumElts = MaybeVBR.get();
107
684k
    for (unsigned i = 0; i != NumElts; ++i)
108
659k
      if (Expected<uint64_t> Res = ReadVBR64(6))
109
658k
        ; // Skip!
110
490
      else
111
490
        return Res.takeError();
112
24.7k
    return Code;
113
25.2k
  }
114
115
0
  Expected<const BitCodeAbbrev *> MaybeAbbv = getAbbrev(AbbrevID);
116
0
  if (!MaybeAbbv)
117
0
    return MaybeAbbv.takeError();
118
119
0
  const BitCodeAbbrev *Abbv = MaybeAbbv.get();
120
0
  const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
121
0
  unsigned Code;
122
0
  if (CodeOp.isLiteral())
123
0
    Code = CodeOp.getLiteralValue();
124
0
  else {
125
0
    if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
126
0
        CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
127
0
      return llvm::createStringError(
128
0
          std::errc::illegal_byte_sequence,
129
0
          "Abbreviation starts with an Array or a Blob");
130
0
    Expected<uint64_t> MaybeCode = readAbbreviatedField(*this, CodeOp);
131
0
    if (!MaybeCode)
132
0
      return MaybeCode.takeError();
133
0
    Code = MaybeCode.get();
134
0
  }
135
136
0
  for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i < e; ++i) {
137
0
    const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
138
0
    if (Op.isLiteral())
139
0
      continue;
140
141
0
    if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
142
0
        Op.getEncoding() != BitCodeAbbrevOp::Blob) {
143
0
      if (Expected<uint64_t> MaybeField = readAbbreviatedField(*this, Op))
144
0
        continue;
145
0
      else
146
0
        return MaybeField.takeError();
147
0
    }
148
149
0
    if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
150
      // Array case.  Read the number of elements as a vbr6.
151
0
      Expected<uint32_t> MaybeNum = ReadVBR(6);
152
0
      if (!MaybeNum)
153
0
        return MaybeNum.takeError();
154
0
      unsigned NumElts = MaybeNum.get();
155
156
      // Get the element encoding.
157
0
      assert(i+2 == e && "array op not second to last?");
158
0
      const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
159
160
      // Read all the elements.
161
      // Decode the value as we are commanded.
162
0
      switch (EltEnc.getEncoding()) {
163
0
      default:
164
0
        return error("Array element type can't be an Array or a Blob");
165
0
      case BitCodeAbbrevOp::Fixed:
166
0
        assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
167
0
        if (Error Err =
168
0
                JumpToBit(GetCurrentBitNo() + static_cast<uint64_t>(NumElts) *
169
0
                                                  EltEnc.getEncodingData()))
170
0
          return std::move(Err);
171
0
        break;
172
0
      case BitCodeAbbrevOp::VBR:
173
0
        assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
174
0
        for (; NumElts; --NumElts)
175
0
          if (Expected<uint64_t> Res =
176
0
                  ReadVBR64((unsigned)EltEnc.getEncodingData()))
177
0
            ; // Skip!
178
0
          else
179
0
            return Res.takeError();
180
0
        break;
181
0
      case BitCodeAbbrevOp::Char6:
182
0
        if (Error Err = JumpToBit(GetCurrentBitNo() + NumElts * 6))
183
0
          return std::move(Err);
184
0
        break;
185
0
      }
186
0
      continue;
187
0
    }
188
189
0
    assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
190
    // Blob case.  Read the number of bytes as a vbr6.
191
0
    Expected<uint32_t> MaybeNum = ReadVBR(6);
192
0
    if (!MaybeNum)
193
0
      return MaybeNum.takeError();
194
0
    unsigned NumElts = MaybeNum.get();
195
0
    SkipToFourByteBoundary();  // 32-bit alignment
196
197
    // Figure out where the end of this blob will be including tail padding.
198
0
    const size_t NewEnd = GetCurrentBitNo() + alignTo(NumElts, 4) * 8;
199
200
    // If this would read off the end of the bitcode file, just set the
201
    // record to empty and return.
202
0
    if (!canSkipToPos(NewEnd/8)) {
203
0
      skipToEnd();
204
0
      break;
205
0
    }
206
207
    // Skip over the blob.
208
0
    if (Error Err = JumpToBit(NewEnd))
209
0
      return std::move(Err);
210
0
  }
211
0
  return Code;
212
0
}
213
214
Expected<unsigned> BitstreamCursor::readRecord(unsigned AbbrevID,
215
                                               SmallVectorImpl<uint64_t> &Vals,
216
48.2M
                                               StringRef *Blob) {
217
48.2M
  if (AbbrevID == bitc::UNABBREV_RECORD) {
218
23.0M
    Expected<uint32_t> MaybeCode = ReadVBR(6);
219
23.0M
    if (!MaybeCode)
220
40
      return MaybeCode.takeError();
221
23.0M
    uint32_t Code = MaybeCode.get();
222
23.0M
    Expected<uint32_t> MaybeNumElts = ReadVBR(6);
223
23.0M
    if (!MaybeNumElts)
224
66
      return error(
225
66
          ("Failed to read size: " + toString(MaybeNumElts.takeError()))
226
66
              .c_str());
227
23.0M
    uint32_t NumElts = MaybeNumElts.get();
228
23.0M
    if (!isSizePlausible(NumElts))
229
186
      return error("Size is not plausible");
230
23.0M
    Vals.reserve(Vals.size() + NumElts);
231
232
174M
    for (unsigned i = 0; i != NumElts; ++i)
233
151M
      if (Expected<uint64_t> MaybeVal = ReadVBR64(6))
234
151M
        Vals.push_back(MaybeVal.get());
235
591
      else
236
591
        return MaybeVal.takeError();
237
23.0M
    return Code;
238
23.0M
  }
239
240
25.2M
  Expected<const BitCodeAbbrev *> MaybeAbbv = getAbbrev(AbbrevID);
241
25.2M
  if (!MaybeAbbv)
242
1.40k
    return MaybeAbbv.takeError();
243
25.2M
  const BitCodeAbbrev *Abbv = MaybeAbbv.get();
244
245
  // Read the record code first.
246
25.2M
  assert(Abbv->getNumOperandInfos() != 0 && "no record code in abbreviation?");
247
0
  const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
248
25.2M
  unsigned Code;
249
25.2M
  if (CodeOp.isLiteral())
250
25.2M
    Code = CodeOp.getLiteralValue();
251
23.1k
  else {
252
23.1k
    if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
253
23.1k
        CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
254
19
      return error("Abbreviation starts with an Array or a Blob");
255
23.1k
    if (Expected<uint64_t> MaybeCode = readAbbreviatedField(*this, CodeOp))
256
23.1k
      Code = MaybeCode.get();
257
22
    else
258
22
      return MaybeCode.takeError();
259
23.1k
  }
260
261
81.2M
  for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) {
262
56.0M
    const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
263
56.0M
    if (Op.isLiteral()) {
264
2.50M
      Vals.push_back(Op.getLiteralValue());
265
2.50M
      continue;
266
2.50M
    }
267
268
53.4M
    if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
269
53.4M
        Op.getEncoding() != BitCodeAbbrevOp::Blob) {
270
40.8M
      if (Expected<uint64_t> MaybeVal = readAbbreviatedField(*this, Op))
271
40.8M
        Vals.push_back(MaybeVal.get());
272
34
      else
273
34
        return MaybeVal.takeError();
274
40.8M
      continue;
275
40.8M
    }
276
277
12.6M
    if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
278
      // Array case.  Read the number of elements as a vbr6.
279
12.3M
      Expected<uint32_t> MaybeNumElts = ReadVBR(6);
280
12.3M
      if (!MaybeNumElts)
281
29
        return error(
282
29
            ("Failed to read size: " + toString(MaybeNumElts.takeError()))
283
29
                .c_str());
284
12.3M
      uint32_t NumElts = MaybeNumElts.get();
285
12.3M
      if (!isSizePlausible(NumElts))
286
136
        return error("Size is not plausible");
287
12.3M
      Vals.reserve(Vals.size() + NumElts);
288
289
      // Get the element encoding.
290
12.3M
      if (i + 2 != e)
291
26
        return error("Array op not second to last");
292
12.3M
      const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
293
12.3M
      if (!EltEnc.isEncoding())
294
15
        return error(
295
15
            "Array element type has to be an encoding of a type");
296
297
      // Read all the elements.
298
12.3M
      switch (EltEnc.getEncoding()) {
299
43
      default:
300
43
        return error("Array element type can't be an Array or a Blob");
301
623k
      case BitCodeAbbrevOp::Fixed:
302
7.13M
        for (; NumElts; --NumElts)
303
6.50M
          if (Expected<SimpleBitstreamCursor::word_t> MaybeVal =
304
6.50M
                  Read((unsigned)EltEnc.getEncodingData()))
305
6.50M
            Vals.push_back(MaybeVal.get());
306
77
          else
307
77
            return MaybeVal.takeError();
308
623k
        break;
309
934k
      case BitCodeAbbrevOp::VBR:
310
2.85M
        for (; NumElts; --NumElts)
311
1.92M
          if (Expected<uint64_t> MaybeVal =
312
1.92M
                  ReadVBR64((unsigned)EltEnc.getEncodingData()))
313
1.92M
            Vals.push_back(MaybeVal.get());
314
60
          else
315
60
            return MaybeVal.takeError();
316
934k
        break;
317
10.7M
      case BitCodeAbbrevOp::Char6:
318
45.5M
        for (; NumElts; --NumElts)
319
34.7M
          if (Expected<SimpleBitstreamCursor::word_t> MaybeVal = Read(6))
320
34.7M
            Vals.push_back(BitCodeAbbrevOp::DecodeChar6(MaybeVal.get()));
321
176
          else
322
176
            return MaybeVal.takeError();
323
12.3M
      }
324
12.3M
      continue;
325
12.3M
    }
326
327
362k
    assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
328
    // Blob case.  Read the number of bytes as a vbr6.
329
0
    Expected<uint32_t> MaybeNumElts = ReadVBR(6);
330
362k
    if (!MaybeNumElts)
331
18
      return MaybeNumElts.takeError();
332
362k
    uint32_t NumElts = MaybeNumElts.get();
333
362k
    SkipToFourByteBoundary();  // 32-bit alignment
334
335
    // Figure out where the end of this blob will be including tail padding.
336
362k
    size_t CurBitPos = GetCurrentBitNo();
337
362k
    const size_t NewEnd = CurBitPos + alignTo(NumElts, 4) * 8;
338
339
    // Make sure the bitstream is large enough to contain the blob.
340
362k
    if (!canSkipToPos(NewEnd/8))
341
200
      return error("Blob ends too soon");
342
343
    // Otherwise, inform the streamer that we need these bytes in memory.  Skip
344
    // over tail padding first, in case jumping to NewEnd invalidates the Blob
345
    // pointer.
346
362k
    if (Error Err = JumpToBit(NewEnd))
347
0
      return std::move(Err);
348
362k
    const char *Ptr = (const char *)getPointerToBit(CurBitPos, NumElts);
349
350
    // If we can return a reference to the data, do so to avoid copying it.
351
362k
    if (Blob) {
352
362k
      *Blob = StringRef(Ptr, NumElts);
353
362k
    } else {
354
      // Otherwise, unpack into Vals with zero extension.
355
67
      auto *UPtr = reinterpret_cast<const unsigned char *>(Ptr);
356
67
      Vals.append(UPtr, UPtr + NumElts);
357
67
    }
358
362k
  }
359
360
25.2M
  return Code;
361
25.2M
}
362
363
5.71M
Error BitstreamCursor::ReadAbbrevRecord() {
364
5.71M
  auto Abbv = std::make_shared<BitCodeAbbrev>();
365
5.71M
  Expected<uint32_t> MaybeNumOpInfo = ReadVBR(5);
366
5.71M
  if (!MaybeNumOpInfo)
367
40
    return MaybeNumOpInfo.takeError();
368
5.71M
  unsigned NumOpInfo = MaybeNumOpInfo.get();
369
27.3M
  for (unsigned i = 0; i != NumOpInfo; ++i) {
370
21.5M
    Expected<word_t> MaybeIsLiteral = Read(1);
371
21.5M
    if (!MaybeIsLiteral)
372
83
      return MaybeIsLiteral.takeError();
373
21.5M
    bool IsLiteral = MaybeIsLiteral.get();
374
21.5M
    if (IsLiteral) {
375
5.97M
      Expected<uint64_t> MaybeOp = ReadVBR64(8);
376
5.97M
      if (!MaybeOp)
377
227
        return MaybeOp.takeError();
378
5.97M
      Abbv->Add(BitCodeAbbrevOp(MaybeOp.get()));
379
5.97M
      continue;
380
5.97M
    }
381
382
15.6M
    Expected<word_t> MaybeEncoding = Read(3);
383
15.6M
    if (!MaybeEncoding)
384
131
      return MaybeEncoding.takeError();
385
15.6M
    if (!BitCodeAbbrevOp::isValidEncoding(MaybeEncoding.get()))
386
869
      return error("Invalid encoding");
387
388
15.6M
    BitCodeAbbrevOp::Encoding E =
389
15.6M
        (BitCodeAbbrevOp::Encoding)MaybeEncoding.get();
390
15.6M
    if (BitCodeAbbrevOp::hasEncodingData(E)) {
391
9.20M
      Expected<uint64_t> MaybeData = ReadVBR64(5);
392
9.20M
      if (!MaybeData)
393
28
        return MaybeData.takeError();
394
9.20M
      uint64_t Data = MaybeData.get();
395
396
      // As a special case, handle fixed(0) (i.e., a fixed field with zero bits)
397
      // and vbr(0) as a literal zero.  This is decoded the same way, and avoids
398
      // a slow path in Read() to have to handle reading zero bits.
399
9.20M
      if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
400
9.20M
          Data == 0) {
401
2.69k
        Abbv->Add(BitCodeAbbrevOp(0));
402
2.69k
        continue;
403
2.69k
      }
404
405
9.20M
      if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
406
9.20M
          Data > MaxChunkSize)
407
375
        return error("Fixed or VBR abbrev record with size > MaxChunkData");
408
409
9.20M
      Abbv->Add(BitCodeAbbrevOp(E, Data));
410
9.20M
    } else
411
6.40M
      Abbv->Add(BitCodeAbbrevOp(E));
412
15.6M
  }
413
414
5.71M
  if (Abbv->getNumOperandInfos() == 0)
415
97
    return error("Abbrev record with no operands");
416
5.71M
  CurAbbrevs.push_back(std::move(Abbv));
417
418
5.71M
  return Error::success();
419
5.71M
}
420
421
Expected<std::optional<BitstreamBlockInfo>>
422
159k
BitstreamCursor::ReadBlockInfoBlock(bool ReadBlockInfoNames) {
423
159k
  if (llvm::Error Err = EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID))
424
118
    return std::move(Err);
425
426
159k
  BitstreamBlockInfo NewBlockInfo;
427
428
159k
  SmallVector<uint64_t, 64> Record;
429
159k
  BitstreamBlockInfo::BlockInfo *CurBlockInfo = nullptr;
430
431
  // Read all the records for this module.
432
3.59M
  while (true) {
433
3.59M
    Expected<BitstreamEntry> MaybeEntry =
434
3.59M
        advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs);
435
3.59M
    if (!MaybeEntry)
436
60
      return MaybeEntry.takeError();
437
3.59M
    BitstreamEntry Entry = MaybeEntry.get();
438
439
3.59M
    switch (Entry.Kind) {
440
0
    case llvm::BitstreamEntry::SubBlock: // Handled for us already.
441
5
    case llvm::BitstreamEntry::Error:
442
5
      return std::nullopt;
443
159k
    case llvm::BitstreamEntry::EndBlock:
444
159k
      return std::move(NewBlockInfo);
445
3.43M
    case llvm::BitstreamEntry::Record:
446
      // The interesting case.
447
3.43M
      break;
448
3.59M
    }
449
450
    // Read abbrev records, associate them with CurBID.
451
3.43M
    if (Entry.ID == bitc::DEFINE_ABBREV) {
452
2.95M
      if (!CurBlockInfo)
453
14
        return std::nullopt;
454
2.95M
      if (Error Err = ReadAbbrevRecord())
455
111
        return std::move(Err);
456
457
      // ReadAbbrevRecord installs the abbrev in CurAbbrevs.  Move it to the
458
      // appropriate BlockInfo.
459
2.95M
      CurBlockInfo->Abbrevs.push_back(std::move(CurAbbrevs.back()));
460
2.95M
      CurAbbrevs.pop_back();
461
2.95M
      continue;
462
2.95M
    }
463
464
    // Read a record.
465
477k
    Record.clear();
466
477k
    Expected<unsigned> MaybeBlockInfo = readRecord(Entry.ID, Record);
467
477k
    if (!MaybeBlockInfo)
468
78
      return MaybeBlockInfo.takeError();
469
477k
    switch (MaybeBlockInfo.get()) {
470
210
    default:
471
210
      break; // Default behavior, ignore unknown content.
472
477k
    case bitc::BLOCKINFO_CODE_SETBID:
473
477k
      if (Record.size() < 1)
474
13
        return std::nullopt;
475
477k
      CurBlockInfo = &NewBlockInfo.getOrCreateBlockInfo((unsigned)Record[0]);
476
477k
      break;
477
12
    case bitc::BLOCKINFO_CODE_BLOCKNAME: {
478
12
      if (!CurBlockInfo)
479
5
        return std::nullopt;
480
7
      if (!ReadBlockInfoNames)
481
7
        break; // Ignore name.
482
0
      CurBlockInfo->Name = std::string(Record.begin(), Record.end());
483
0
      break;
484
7
    }
485
15
      case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
486
15
      if (!CurBlockInfo)
487
6
        return std::nullopt;
488
9
      if (!ReadBlockInfoNames)
489
9
        break; // Ignore name.
490
0
      CurBlockInfo->RecordNames.emplace_back(
491
0
          (unsigned)Record[0], std::string(Record.begin() + 1, Record.end()));
492
0
      break;
493
9
      }
494
477k
      }
495
477k
  }
496
159k
}