From 9139d7252de74c30539afb35dc05e3536456971b Mon Sep 17 00:00:00 2001
From: Guy Shefy <guyshefyb@gmail.com>
Date: Sat, 30 Mar 2024 16:33:18 +0300
Subject: [PATCH] do not add prolog for variadic naked functions

fixes #99858
---
 compiler/rustc_codegen_ssa/src/mir/mod.rs |  7 +++++++
 tests/codegen/cffi/c-variadic-naked.rs    | 19 +++++++++++++++++++
 tests/codegen/naked-fn/naked-functions.rs |  2 +-
 3 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 tests/codegen/cffi/c-variadic-naked.rs

diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 387a5366b209b..dc589a5fd306e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -2,6 +2,7 @@ use crate::base;
 use crate::traits::*;
 use rustc_index::bit_set::BitSet;
 use rustc_index::IndexVec;
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir;
 use rustc_middle::mir::traversal;
 use rustc_middle::mir::UnwindTerminateReason;
@@ -290,6 +291,12 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
     let mut num_untupled = None;
 
+    let codegen_fn_attrs = bx.tcx().codegen_fn_attrs(fx.instance.def_id());
+    let naked = codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED);
+    if naked {
+        return vec![];
+    }
+
     let args = mir
         .args_iter()
         .enumerate()
diff --git a/tests/codegen/cffi/c-variadic-naked.rs b/tests/codegen/cffi/c-variadic-naked.rs
new file mode 100644
index 0000000000000..807873ea3689f
--- /dev/null
+++ b/tests/codegen/cffi/c-variadic-naked.rs
@@ -0,0 +1,19 @@
+//@ needs-asm-support
+//@ only-x86_64
+
+// tests that `va_start` is not injected into naked functions
+
+#![crate_type = "lib"]
+#![feature(c_variadic)]
+#![feature(naked_functions)]
+#![no_std]
+
+#[naked]
+pub unsafe extern "C" fn c_variadic(_: usize, _: ...) {
+    // CHECK-NOT: va_start
+    // CHECK-NOT: alloca
+    core::arch::asm! {
+        "ret",
+        options(noreturn),
+    }
+}
diff --git a/tests/codegen/naked-fn/naked-functions.rs b/tests/codegen/naked-fn/naked-functions.rs
index 755dd15511269..3c426825537b6 100644
--- a/tests/codegen/naked-fn/naked-functions.rs
+++ b/tests/codegen/naked-fn/naked-functions.rs
@@ -19,7 +19,7 @@ pub unsafe extern "C" fn naked_empty() {
 }
 
 // CHECK: Function Attrs: naked
-// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i64 %a, i64 %b)
+// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i64 %0, i64 %1)
 #[no_mangle]
 #[naked]
 pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {