mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-30 13:06:28 +03:00
43d2006c25
`c_variadic`: impl `va_copy` and `va_end` as Rust intrinsics tracking issue: https://github.com/rust-lang/rust/issues/44930 Implement `va_copy` as (the rust equivalent of) `memcpy`, which is the behavior of all current LLVM targets. By providing our own implementation, we can guarantee its behavior. These guarantees are important for implementing c-variadics in e.g. const-eval. Discussed in [#t-compiler/const-eval > c-variadics in const-eval](https://rust-lang.zulipchat.com/#narrow/channel/146212-t-compiler.2Fconst-eval/topic/c-variadics.20in.20const-eval/with/565509704). I've also updated the comment for `Drop` a bit. The background here is that the C standard requires that `va_end` is used in the same function (and really, in the same scope) as the corresponding `va_start` or `va_copy`. That is because historically `va_start` would start a scope, which `va_end` would then close. e.g. https://softwarepreservation.computerhistory.org/c_plus_plus/cfront/release_3.0.3/source/incl-master/proto-headers/stdarg.sol ```c #define va_start(ap, parmN) {\ va_buf _va;\ _vastart(ap = (va_list)_va, (char *)&parmN + sizeof parmN) #define va_end(ap) } #define va_arg(ap, mode) *((mode *)_vaarg(ap, sizeof (mode))) ``` The C standard still has to consider such implementations, but for Rust they are irrelevant. Hence we can use `Clone` for `va_copy` and `Drop` for `va_end`.
The codegen crate contains the code to convert from MIR into LLVM IR,
and then from LLVM IR into machine code. In general it contains code
that runs towards the end of the compilation process.
For more information about how codegen works, see the rustc dev guide.