Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CIR][CodeGen][Bugfix] Fix storage size for bitfields (#462)
This PR fixes a bug caused by `IntType` size limitations in CIR (and by some magic of numbers as well). As you know, we need to create a storage for bit fields that usually contain several of them. There next code fails with `IntType` size check which exceeds 64 bits. ``` typedef struct { uint8_t a; uint8_t b; uint8_t c; int d: 2; int e: 2; int f: 4; int g: 25; int h: 3; int i: 4; int j: 3; int k: 8; int l: 14; } D; void foo() { D d; } ``` Note, if we remove first three fields (or even one) everything will be fine even without this fix, because [this](https://github.com/llvm/clangir/blob/main/clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp#L553) check won't pass. The bug is kind of hard to reproduce and I would say it's a rare case. I mean the problem is not only in the number of bit fields that form together something bigger than 64 bits. Well, while iterating over the bit fields in some struct type, we need to stop accumulating bit fields in one storage and start to do the same in another one. Basically, we operate with `Tail` and `StartBitOffset` where the former is an offset of the next field. And once `Tail - StartBitOffset >= 64` we say that it's not possible to create a storage of such size due to `IntType` size limitation. Sounds reasonable. But it can be a case when we can not afford to take the next field because its `Tail` in turn leads to a storage of the size bigger then 64. Thus, we want to check it as well. From the implementation point of view I added one more check to the `IsBetterAsSingleFieldRun` in order to have all these checks for size in a single place. And the check I mentioned before were saving us from hitting this issue.
- Loading branch information