Skip to content

Commit 922057c

Browse files
committed
c-variadic: make VaList::drop call the rust va_end
1 parent dd9241d commit 922057c

2 files changed

Lines changed: 15 additions & 11 deletions

File tree

library/core/src/ffi/va_list.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#[cfg(not(target_arch = "xtensa"))]
66
use crate::ffi::c_void;
77
use crate::fmt;
8-
use crate::intrinsics::{va_arg, va_copy};
8+
use crate::intrinsics::{va_arg, va_copy, va_end};
99
use crate::marker::PhantomCovariantLifetime;
1010

1111
// There are currently three flavors of how a C `va_list` is implemented for
@@ -216,15 +216,10 @@ impl Clone for VaList<'_> {
216216
}
217217
}
218218

219-
impl Drop for VaList<'_> {
219+
impl<'f> Drop for VaList<'f> {
220220
fn drop(&mut self) {
221-
// For all current LLVM targets `va_end` is a no-op.
222-
//
223-
// We implement `Drop` here because some future target might need to actually run
224-
// destructors (e.g. to deallocate).
225-
//
226-
// Rust requires that not calling `va_end` on a `va_list` does not cause undefined
227-
// behaviour: it is safe to leak values.
221+
// SAFETY: this variable argument list is being dropped, so won't be read from again.
222+
unsafe { va_end(self) }
228223
}
229224
}
230225

library/core/src/intrinsics/mod.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3483,12 +3483,21 @@ pub fn va_copy<'f>(src: &VaList<'f>) -> VaList<'f> {
34833483
src.duplicate()
34843484
}
34853485

3486-
/// Destroy the arglist `ap` after initialization with `va_start` or `va_copy`.
3486+
/// Destroy the variable argument list `ap` after initialization with `va_start` (part of the
3487+
/// desugaring of `...`) or `va_copy`.
3488+
///
3489+
/// Code generation backends should not provide a custom implementation for this intrinsic. This
3490+
/// intrinsic *does not* map to the LLVM `va_end` intrinsic.
3491+
///
3492+
/// This function is a no-op on all current targets, but used as a hook for const evaluation to
3493+
/// detect UB when a variable argument list is used incorrectly.
34873494
///
34883495
/// # Safety
34893496
///
34903497
/// `ap` must not be used to access variable arguments after this call.
34913498
///
34923499
#[rustc_intrinsic]
34933500
#[rustc_nounwind]
3494-
pub unsafe fn va_end(ap: &mut VaList<'_>);
3501+
pub unsafe fn va_end(ap: &mut VaList<'_>) {
3502+
/* deliberately does nothing */
3503+
}

0 commit comments

Comments
 (0)