Re: C aggregate passing (Rust kernel policy)

Ralf Jung
2025-02-26T19:23:25Z

Hi all,

>>> But it is much more significant for Rust than for C, at least in
>>> regards to C's "restrict", since "restrict" is rarely used in C, while
>>> aliasing optimizations are pervasive in Rust. For C's "strict aliasing",
>>> I think you have a good point, but "strict aliasing" is still easier to
>>> reason about in my opinion than C's "restrict". Especially if you
>>> never have any type casts of any kind nor union type punning.
>>
>> Is it easier to reason about? At least GCC got it wrong, making no-aliasing
>> assumptions that are not justified by most people's interpretation of the model:
>> https://bugs.llvm.org/show_bug.cgi?id=21725
>> (But yes that does involve unions.)
>
> Did you mean to say LLVM got this wrong? As far as I know,
> the GCC TBBA code is more correct than LLVMs. It gets
> type-changing stores correct that LLVM does not implement.

Oh sorry, yes that is an LLVM bug link. I mixed something up. I could have sworn
there was a GCC bug, but I only found
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57359> which has been fixed.
There was some problem with strong updates, i.e. the standard permits writes
through a `float*` pointer to memory that aliases an `int*`. The C aliasing
model only says it is UB to read data at the wrong type, but does not talk about
writes changing the type of memory.
Martin, maybe you remember better than me what that issue was / whether it is
still a problem?

>>>> So, the situation for Rust here is a lot better than it is in C. Unfortunately,
>>>> running kernel code in Miri is not currently possible; figuring out how to
>>>> improve that could be an interesting collaboration.
>>>
>>> I do not believe that you are correct when you write:
>>>
>>> "Unlike sanitizers, Miri can actually catch everything."
>>>
>>> Critically and very importantly, unless I am mistaken about MIRI, and
>>> similar to sanitizers, MIRI only checks with runtime tests. That means
>>> that MIRI will not catch any undefined behavior that a test does
>>> not encounter. If a project's test coverage is poor, MIRI will not
>>> check a lot of the code when run with those tests. Please do
>>> correct me if I am mistaken about this. I am guessing that you
>>> meant this as well, but I do not get the impression that it is
>>> clear from your post.
>>
>> Okay, I may have misunderstood what you mean by "catch everything". All
>> sanitizers miss some UB that actually occurs in the given execution. This is
>> because they are inserted in the pipeline after a bunch of compiler-specific
>> choices have already been made, potentially masking some UB. I'm not aware of a
>> sanitizer for sequence point violations. I am not aware of a sanitizer for
>> strict aliasing or restrict. I am not aware of a sanitizer that detects UB due
>> to out-of-bounds pointer arithmetic (I am not talking about OOB accesses; just
>> the arithmetic is already UB), or UB due to violations of "pointer lifetime end
>> zapping", or UB due to comparing pointers derived from different allocations. Is
>> there a sanitizer that correctly models what exactly happens when a struct with
>> padding gets copied? The padding must be reset to be considered "uninitialized",
>> even if the entire struct was zero-initialized before. Most compilers implement
>> such a copy as memcpy; a sanitizer would then miss this UB.
>
> Note that reading padding bytes in C is not UB. Regarding
> uninitialized variables, only automatic variables whose address
> is not taken is UB in C.   Although I suspect that compilers
> have compliance isues here.

Hm, now I am wondering how clang is compliant here. To my knowledge, padding is
effectively reset to poison or undef on a copy (due to SROA), and clang marks
most integer types as "noundef", thus making it UB to ever have undef/poison in
such a value.

Kind regards,
Ralf

>
> But yes, it sanitizers are still rather poor.

>
> Martin
>
>>
>> In contrast, Miri checks for all the UB that is used anywhere in the Rust
>> compiler -- everything else would be a critical bug in either Miri or the compiler.
>> But yes, it only does so on the code paths you are actually testing. And yes, it
>> is very slow.
>>
>> Kind regards,
>> Ralf
>>
>