about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2020-11-11 00:00:00 +0000
committerTomasz Miąsko <tomasz.miasko@gmail.com>2020-11-12 20:09:04 +0100
commit79d853eccebf6d9704adeea45f20f11bae0d7396 (patch)
treee878620e902f8d574e8be97a50287f1d0408cf40
parent66cadec1763ac645337c1ac58f06ea48b9b72a26 (diff)
downloadrust-79d853eccebf6d9704adeea45f20f11bae0d7396.tar.gz
rust-79d853eccebf6d9704adeea45f20f11bae0d7396.zip
Never inline C variadic functions
-rw-r--r--compiler/rustc_mir/src/transform/inline.rs5
-rw-r--r--src/test/mir-opt/inline/inline-compatibility.rs18
2 files changed, 23 insertions, 0 deletions
diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs
index 2ccb9b3709f..aae98f5b6d8 100644
--- a/compiler/rustc_mir/src/transform/inline.rs
+++ b/compiler/rustc_mir/src/transform/inline.rs
@@ -206,6 +206,11 @@ impl Inliner<'tcx> {
         debug!("should_inline({:?})", callsite);
         let tcx = self.tcx;
 
+        if callsite.fn_sig.c_variadic() {
+            debug!("callee is variadic - not inlining");
+            return false;
+        }
+
         let codegen_fn_attrs = tcx.codegen_fn_attrs(callsite.callee.def_id());
 
         let self_features = &self.codegen_fn_attrs.target_features;
diff --git a/src/test/mir-opt/inline/inline-compatibility.rs b/src/test/mir-opt/inline/inline-compatibility.rs
index 2e9edf5260f..30aff0a64ef 100644
--- a/src/test/mir-opt/inline/inline-compatibility.rs
+++ b/src/test/mir-opt/inline/inline-compatibility.rs
@@ -5,6 +5,7 @@
 #![crate_type = "lib"]
 #![feature(no_sanitize)]
 #![feature(target_feature_11)]
+#![feature(c_variadic)]
 
 // EMIT_MIR inline_compatibility.inlined_target_feature.Inline.diff
 #[target_feature(enable = "sse2")]
@@ -35,3 +36,20 @@ pub unsafe fn target_feature() {}
 #[inline]
 #[no_sanitize(address)]
 pub unsafe fn no_sanitize() {}
+
+// EMIT_MIR inline_compatibility.not_inlined_c_variadic.Inline.diff
+pub unsafe fn not_inlined_c_variadic() {
+    let s = sum(4u32, 4u32, 30u32, 200u32, 1000u32);
+}
+
+#[no_mangle]
+#[inline(always)]
+unsafe extern "C" fn sum(n: u32, mut vs: ...) -> u32 {
+    let mut s = 0;
+    let mut i = 0;
+    while i != n {
+        s += vs.arg::<u32>();
+        i += 1;
+    }
+    s
+}