You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[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.
### Several details
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.
0 commit comments