Skip to content

Commit 98fd424

Browse files
committed
c-variadic: make VaList::drop call the rust va_end
1 parent e77375c commit 98fd424

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
@@ -200,15 +200,10 @@ impl Clone for VaList<'_> {
200200
}
201201
}
202202

203-
impl Drop for VaList<'_> {
203+
impl<'f> Drop for VaList<'f> {
204204
fn drop(&mut self) {
205-
// For all current LLVM targets `va_end` is a no-op.
206-
//
207-
// We implement `Drop` here because some future target might need to actually run
208-
// destructors (e.g. to deallocate).
209-
//
210-
// Rust requires that not calling `va_end` on a `va_list` does not cause undefined
211-
// behaviour: it is safe to leak values.
205+
// SAFETY: this variable argument list is being dropped, so won't be read from again.
206+
unsafe { va_end(self) }
212207
}
213208
}
214209

library/core/src/intrinsics/mod.rs

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

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

0 commit comments

Comments
 (0)