Skip to content

Commit 6011fa6

Browse files
folkertdevRalfJung
andcommitted
Fix comments
- apply suggestions from code review - include note about backends no overriding `va_end` and `va_copy` in the doc comment. - link to where `va_copy` is lowered to `memcpy` Co-authored-by: Ralf Jung <post@ralfj.de>
1 parent 98fd424 commit 6011fa6

2 files changed

Lines changed: 28 additions & 9 deletions

File tree

library/core/src/ffi/va_list.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ use crate::marker::PhantomCovariantLifetime;
3434
//
3535
// The Clang `BuiltinVaListKind` enumerates the `va_list` variations that Clang supports,
3636
// and we mirror these here.
37+
//
38+
// For all current LLVM targets, `va_copy` lowers to `memcpy`. Hence the inner structs below all
39+
// derive `Copy`. However, in the future we might want to support a target where `va_copy`
40+
// allocates, or otherwise violates the requirements of `Copy`. Therefore `VaList` is only `Clone`.
3741
crate::cfg_select! {
3842
all(
3943
target_arch = "aarch64",
@@ -45,6 +49,8 @@ crate::cfg_select! {
4549
///
4650
/// See the [AArch64 Procedure Call Standard] for more details.
4751
///
52+
/// `va_copy` is `memcpy`: <https://github.com/llvm/llvm-project/blob/5aee01a3df011e660f26660bc30a8c94a1651d8e/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp#L12682-L12700>
53+
///
4854
/// [AArch64 Procedure Call Standard]:
4955
/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
5056
#[repr(C)]
@@ -62,6 +68,8 @@ crate::cfg_select! {
6268
///
6369
/// See the [LLVM source] and [GCC header] for more details.
6470
///
71+
/// `va_copy` is `memcpy`: <https://github.com/llvm/llvm-project/blob/5aee01a3df011e660f26660bc30a8c94a1651d8e/llvm/lib/Target/PowerPC/PPCISelLowering.cpp#L3755-L3764>
72+
///
6573
/// [LLVM source]:
6674
/// https://github.com/llvm/llvm-project/blob/af9a4263a1a209953a1d339ef781a954e31268ff/llvm/lib/Target/PowerPC/PPCISelLowering.cpp#L4089-L4111
6775
/// [GCC header]: https://web.mit.edu/darwin/src/modules/gcc/gcc/ginclude/va-ppc.h
@@ -81,6 +89,8 @@ crate::cfg_select! {
8189
///
8290
/// See the [S/390x ELF Application Binary Interface Supplement] for more details.
8391
///
92+
/// `va_copy` is `memcpy`: <https://github.com/llvm/llvm-project/blob/5aee01a3df011e660f26660bc30a8c94a1651d8e/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp#L4457-L4472>
93+
///
8494
/// [S/390x ELF Application Binary Interface Supplement]:
8595
/// https://docs.google.com/gview?embedded=true&url=https://github.com/IBM/s390x-abi/releases/download/v1.7/lzsabi_s390x.pdf
8696
#[repr(C)]
@@ -98,6 +108,9 @@ crate::cfg_select! {
98108
///
99109
/// See the [System V AMD64 ABI] for more details.
100110
///
111+
/// `va_copy` is `memcpy`: <https://github.com/llvm/llvm-project/blob/5aee01a3df011e660f26660bc30a8c94a1651d8e/llvm/lib/Target/X86/X86ISelLowering.cpp#26319>
112+
/// (github won't render that file, look for `SDValue LowerVACOPY`)
113+
///
101114
/// [System V AMD64 ABI]:
102115
/// https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf
103116
#[repr(C)]
@@ -115,6 +128,8 @@ crate::cfg_select! {
115128
///
116129
/// See the [LLVM source] for more details.
117130
///
131+
/// `va_copy` is `memcpy`: <https://github.com/llvm/llvm-project/blob/5aee01a3df011e660f26660bc30a8c94a1651d8e/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp#L1260>
132+
///
118133
/// [LLVM source]:
119134
/// https://github.com/llvm/llvm-project/blob/af9a4263a1a209953a1d339ef781a954e31268ff/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp#L1211-L1215
120135
#[repr(C)]
@@ -132,6 +147,8 @@ crate::cfg_select! {
132147
///
133148
/// See the [LLVM source] for more details. On bare metal Hexagon uses an opaque pointer.
134149
///
150+
/// `va_copy` is `memcpy`: <https://github.com/llvm/llvm-project/blob/5aee01a3df011e660f26660bc30a8c94a1651d8e/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp#L1087-L1102>
151+
///
135152
/// [LLVM source]:
136153
/// https://github.com/llvm/llvm-project/blob/0cdc1b6dd4a870fc41d4b15ad97e0001882aba58/clang/lib/CodeGen/Targets/Hexagon.cpp#L407-L417
137154
#[repr(C)]
@@ -156,6 +173,8 @@ crate::cfg_select! {
156173
// That pointer is probably just the next variadic argument on the caller's stack.
157174
_ => {
158175
/// Basic implementation of a `va_list`.
176+
///
177+
/// `va_copy` is `memcpy`: <https://github.com/llvm/llvm-project/blob/87e8e7d8f0db53060ef2f6ef4ab612fc0f2b4490/llvm/lib/Transforms/IPO/ExpandVariadics.cpp#L127-L129>
159178
#[repr(transparent)]
160179
#[derive(Debug, Clone, Copy)]
161180
struct VaListInner {
@@ -190,12 +209,9 @@ impl Clone for VaList<'_> {
190209
#[inline]
191210
fn clone(&self) -> Self {
192211
// We only implement Clone and not Copy because some future target might not be able to
193-
// implement Copy (e.g. because it allocates).
194-
195-
// We still use a `va_copy` intrinsic to provide a hook for const evaluation. The hook is
196-
// used to report UB when a variable argument list is duplicated with a manual `memcpy`.
197-
// While that works in practice for all current targets, we want to be able to support
198-
// targets in the future where that is not the case.
212+
// implement Copy (e.g. because it allocates). For the same reason we use an intrinsic
213+
// to do the copying: the fact that on all current targets, this is just `memcpy`, is an implementation
214+
// detail. The intrinsic lets Miri catch UB from code incorrectly relying on that implementation detail.
199215
va_copy(self)
200216
}
201217
}

library/core/src/intrinsics/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3471,12 +3471,15 @@ pub unsafe fn va_arg<T: VaArgSafe>(ap: &mut VaList<'_>) -> T;
34713471

34723472
/// Duplicates a variable argument list. The returned list is initially at the same position as
34733473
/// the one in `src`, but can be advanced independently.
3474+
///
3475+
/// Codegen backends should not have custom behavior for this intrinsic, they should always use
3476+
/// this fallback implementation. This intrinsic *does not* map to the LLVM `va_copy` intrinsic.
3477+
///
3478+
/// This intrinsic exists only as a hook for Miri and constant evaluation, and is used to detect UB
3479+
/// when a variable argument list is used incorrectly.
34743480
#[rustc_intrinsic]
34753481
#[rustc_nounwind]
34763482
pub fn va_copy<'f>(src: &VaList<'f>) -> VaList<'f> {
3477-
// NOTE: this intrinsic exists only as a hook for constant evaluation, and is used to detect UB
3478-
// when `VaList` is used incorrectly. Codegen backends should not have custom behavior for this
3479-
// intrinsic, they should always use this fallback implementation.
34803483
src.duplicate()
34813484
}
34823485

0 commit comments

Comments
 (0)