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
This PR fixes two run time bugs in the calling convention pass. These
bugs were found with `csmith`.
Case #1. Return value from a function.
Before this PR the returned value were stored in a bit casted memory
location.
But for the next example it's not safe: the size of a memory slot is
less than the size of return value. And the store operation cause a
segfault!
```
#pragma pack(push)
#pragma pack(1)
typedef struct {
int f0 : 18;
int f1 : 31;
int f2 : 5;
int f3 : 29;
int f4 : 24;
} PackedS;
#pragma pack(pop)
```
CIR type for this struct is `!ty_PackedS1_ = !cir.struct<struct
"PackedS1" {!cir.array<!u8i x 14>}>`, i.e. it occupies 14 bytes.
Before this PR the next code
```
PackedS foo(void) {
PackedS s;
return s;
}
void check(void) {
PackedS y = foo();
}
```
produced the next CIR:
```
%0 = cir.alloca !ty_PackedS1_, !cir.ptr<!ty_PackedS1_>, ["y", init] {alignment = 1 : i64}
%1 = cir.call @foo() : () -> !cir.array<!u64i x 2>
%2 = cir.cast(bitcast, %0 : !cir.ptr<!ty_PackedS1_>), !cir.ptr<!cir.array<!u64i x 2>>
cir.store %1, %2 : !cir.array<!u64i x 2>, !cir.ptr<!cir.array<!u64i x 2>>
```
As one cat see, `%1` is an array of two 64-bit integers and the memory
was allocated for 14 bytes only (size of struct). Hence the segfault!
This PR fixes such cases and now we have a coercion through memory,
which is even with the OG.
Case #2. Passing an argument from a pointer deref.
Previously for the struct types passed by value we tried to find alloca
instruction in order to use it as a source for memcpy operation. But if
we have pointer dereference, (in other words if we have a `<!cir.ptr <
!cir.ptr ... > >` as alloca result) we don't need to search for the
address of the location where this pointer stored - instead we're
interested in the pointer itself. And it's a general approach - instead
of trying to find an alloca instruction we need to find a first pointer
on the way - that will be an address we meed to use for the memcpy
source.
I combined these two cases into a single PR since there are only few
changes actually. But I can split in two if you'd prefer
0 commit comments