From f02d746fb8b8b46c82dfdeccf77f0324470824a0 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Tue, 3 Jun 2025 19:36:32 +0200 Subject: [PATCH 1/2] Add warning about the safety of extern c-variadic functions --- src/items/external-blocks.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 5e63e7eab..3375c5f01 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -179,9 +179,13 @@ unsafe extern "C" { unsafe fn foo(...); unsafe fn bar(x: i32, ...); unsafe fn with_name(format: *const u8, args: ...); + safe fn ignores_variadic_arguments(x: i32, ...); } ``` +> [!WARNING] +> `safe` should only be used in cases where the function does not look at the variadic arguments at all. Passing an unexpected number of arguments or arguments of an unexpected type to a variadic function is [undefined behavior][undefined]. + r[items.extern.attributes] ## Attributes on extern blocks From c13d2d2dadbe35b42df5db3cfd7aff3f2828924d Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 4 Jun 2025 21:31:49 +0000 Subject: [PATCH 2/2] Revise language of warning about safe variadics Let's adjust this language so that it talks about the guarantees that the function must make, and so that it says what may lead to UB rather than what "is" UB, as the latter implies immediate language UB, when this is actually library UB. Let's also add a `SAFETY` comment to the function in the example. --- src/items/external-blocks.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 3375c5f01..3bed8aaf2 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -179,12 +179,14 @@ unsafe extern "C" { unsafe fn foo(...); unsafe fn bar(x: i32, ...); unsafe fn with_name(format: *const u8, args: ...); + // SAFETY: This function guarantees it will not access + // variadic arguments. safe fn ignores_variadic_arguments(x: i32, ...); } ``` > [!WARNING] -> `safe` should only be used in cases where the function does not look at the variadic arguments at all. Passing an unexpected number of arguments or arguments of an unexpected type to a variadic function is [undefined behavior][undefined]. +> The `safe` qualifier should not be used on a function in an `extern` block unless that function guarantees that it will not access the variadic arguments at all. Passing an unexpected number of arguments or arguments of unexpected type to a variadic function may lead to [undefined behavior][undefined]. r[items.extern.attributes] ## Attributes on extern blocks