about summary refs log tree commit diff
path: root/compiler/rustc_codegen_gcc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-01-21 19:46:20 +0000
committerbors <bors@rust-lang.org>2025-01-21 19:46:20 +0000
commited43cbcb882e7c06870abdd9305dc1f17eb9bab9 (patch)
tree436c680b2714e0300cdbbef3e2ecd321a049794e /compiler/rustc_codegen_gcc
parentcd805f09ffbfa3896c8f50a619de9b67e1d9f3c3 (diff)
parent56c90dc31e86bbaf486826a21a33d7c56e8f742f (diff)
downloadrust-ed43cbcb882e7c06870abdd9305dc1f17eb9bab9.tar.gz
rust-ed43cbcb882e7c06870abdd9305dc1f17eb9bab9.zip
Auto merge of #134299 - RalfJung:remove-start, r=compiler-errors
remove support for the (unstable) #[start] attribute

As explained by `@Noratrieb:`
`#[start]` should be deleted. It's nothing but an accidentally leaked implementation detail that's a not very useful mix between "portable" entrypoint logic and bad abstraction.

I think the way the stable user-facing entrypoint should work (and works today on stable) is pretty simple:
- `std`-using cross-platform programs should use `fn main()`. the compiler, together with `std`, will then ensure that code ends up at `main` (by having a platform-specific entrypoint that gets directed through `lang_start` in `std` to `main` - but that's just an implementation detail)
- `no_std` platform-specific programs should use `#![no_main]` and define their own platform-specific entrypoint symbol with `#[no_mangle]`, like `main`, `_start`, `WinMain` or `my_embedded_platform_wants_to_start_here`. most of them only support a single platform anyways, and need cfg for the different platform's ways of passing arguments or other things *anyways*

`#[start]` is in a super weird position of being neither of those two. It tries to pretend that it's cross-platform, but its signature is  a total lie. Those arguments are just stubbed out to zero on ~~Windows~~ wasm, for example. It also only handles the platform-specific entrypoints for a few platforms that are supported by `std`, like Windows or Unix-likes. `my_embedded_platform_wants_to_start_here` can't use it, and neither could a libc-less Linux program.
So we have an attribute that only works in some cases anyways, that has a signature that's a total lie (and a signature that, as I might want to add, has changed recently, and that I definitely would not be comfortable giving *any* stability guarantees on), and where there's a pretty easy way to get things working without it in the first place.

Note that this feature has **not** been RFCed in the first place.

*This comment was posted [in May](https://github.com/rust-lang/rust/issues/29633#issuecomment-2088596042) and so far nobody spoke up in that issue with a usecase that would require keeping the attribute.*

Closes https://github.com/rust-lang/rust/issues/29633

try-job: x86_64-gnu-nopt
try-job: x86_64-msvc-1
try-job: x86_64-msvc-2
try-job: test-various
Diffstat (limited to 'compiler/rustc_codegen_gcc')
-rw-r--r--compiler/rustc_codegen_gcc/build_system/src/test.rs26
-rw-r--r--compiler/rustc_codegen_gcc/example/alloc_example.rs7
-rw-r--r--compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs2
-rw-r--r--compiler/rustc_codegen_gcc/example/mod_bench.rs36
-rw-r--r--compiler/rustc_codegen_gcc/src/context.rs1
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/abort1.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/abort2.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/array.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/assign.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/closure.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/condition.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/empty_main.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/exit.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/exit_code.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/mut_ref.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/operations.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/return-tuple.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/slice.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/static.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/structs.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/tuple.rs7
23 files changed, 77 insertions, 121 deletions
diff --git a/compiler/rustc_codegen_gcc/build_system/src/test.rs b/compiler/rustc_codegen_gcc/build_system/src/test.rs
index 7cc7336612c..0e790a4befc 100644
--- a/compiler/rustc_codegen_gcc/build_system/src/test.rs
+++ b/compiler/rustc_codegen_gcc/build_system/src/test.rs
@@ -426,19 +426,6 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> {
     run_command_with_env(&command, None, Some(env))?;
     maybe_run_command_in_vm(&[&cargo_target_dir.join("track-caller-attribute")], env, args)?;
 
-    // FIXME: create a function "display_if_not_quiet" or something along the line.
-    println!("[AOT] mod_bench");
-    let mut command = args.config_info.rustc_command_vec();
-    command.extend_from_slice(&[
-        &"example/mod_bench.rs",
-        &"--crate-type",
-        &"bin",
-        &"--target",
-        &args.config_info.target_triple,
-    ]);
-    run_command_with_env(&command, None, Some(env))?;
-    // FIXME: the compiled binary is not run.
-
     Ok(())
 }
 
@@ -696,19 +683,6 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> {
     Ok(())
 }
 
-// echo "[BENCH COMPILE] mod_bench"
-//
-// COMPILE_MOD_BENCH_INLINE="$RUSTC example/mod_bench.rs --crate-type bin -Zmir-opt-level=3 -O --crate-name mod_bench_inline"
-// COMPILE_MOD_BENCH_LLVM_0="rustc example/mod_bench.rs --crate-type bin -Copt-level=0 -o $cargo_target_dir/mod_bench_llvm_0 -Cpanic=abort"
-// COMPILE_MOD_BENCH_LLVM_1="rustc example/mod_bench.rs --crate-type bin -Copt-level=1 -o $cargo_target_dir/mod_bench_llvm_1 -Cpanic=abort"
-// COMPILE_MOD_BENCH_LLVM_2="rustc example/mod_bench.rs --crate-type bin -Copt-level=2 -o $cargo_target_dir/mod_bench_llvm_2 -Cpanic=abort"
-// COMPILE_MOD_BENCH_LLVM_3="rustc example/mod_bench.rs --crate-type bin -Copt-level=3 -o $cargo_target_dir/mod_bench_llvm_3 -Cpanic=abort"
-//
-// Use 100 runs, because a single compilations doesn't take more than ~150ms, so it isn't very slow
-// hyperfine --runs ${COMPILE_RUNS:-100} "$COMPILE_MOD_BENCH_INLINE" "$COMPILE_MOD_BENCH_LLVM_0" "$COMPILE_MOD_BENCH_LLVM_1" "$COMPILE_MOD_BENCH_LLVM_2" "$COMPILE_MOD_BENCH_LLVM_3"
-// echo "[BENCH RUN] mod_bench"
-// hyperfine --runs ${RUN_RUNS:-10} $cargo_target_dir/mod_bench{,_inline} $cargo_target_dir/mod_bench_llvm_*
-
 fn extended_rand_tests(env: &Env, args: &TestArg) -> Result<(), String> {
     if !args.is_using_gcc_master_branch() {
         println!("Not using GCC master branch. Skipping `extended_rand_tests`.");
diff --git a/compiler/rustc_codegen_gcc/example/alloc_example.rs b/compiler/rustc_codegen_gcc/example/alloc_example.rs
index 6ed8b9157f2..9a0b46d5b22 100644
--- a/compiler/rustc_codegen_gcc/example/alloc_example.rs
+++ b/compiler/rustc_codegen_gcc/example/alloc_example.rs
@@ -1,5 +1,6 @@
-#![feature(start, core_intrinsics, alloc_error_handler, lang_items)]
+#![feature(core_intrinsics, alloc_error_handler, lang_items)]
 #![no_std]
+#![no_main]
 #![allow(internal_features)]
 
 extern crate alloc;
@@ -37,8 +38,8 @@ unsafe extern "C" fn _Unwind_Resume() {
     core::intrinsics::unreachable();
 }
 
-#[start]
-fn main(_argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
     let world: Box<&str> = Box::new("Hello World!\0");
     unsafe {
         puts(*world as *const str as *const u8);
diff --git a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
index 1d51e0a1856..4cbe66c5e4c 100644
--- a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
@@ -1,7 +1,7 @@
 // Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
 
 #![feature(
-    no_core, unboxed_closures, start, lang_items, never_type, linkage,
+    no_core, unboxed_closures, lang_items, never_type, linkage,
     extern_types, thread_local
 )]
 #![no_core]
diff --git a/compiler/rustc_codegen_gcc/example/mod_bench.rs b/compiler/rustc_codegen_gcc/example/mod_bench.rs
deleted file mode 100644
index e8a9cade747..00000000000
--- a/compiler/rustc_codegen_gcc/example/mod_bench.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-#![feature(start, core_intrinsics, lang_items)]
-#![no_std]
-#![allow(internal_features)]
-
-#[link(name = "c")]
-extern "C" {}
-
-#[panic_handler]
-fn panic_handler(_: &core::panic::PanicInfo<'_>) -> ! {
-    core::intrinsics::abort();
-}
-
-#[lang="eh_personality"]
-fn eh_personality(){}
-
-// Required for rustc_codegen_llvm
-#[no_mangle]
-unsafe extern "C" fn _Unwind_Resume() {
-    core::intrinsics::unreachable();
-}
-
-#[start]
-fn main(_argc: isize, _argv: *const *const u8) -> isize {
-    for i in 2..100_000_000 {
-        black_box((i + 1) % i);
-    }
-
-    0
-}
-
-#[inline(never)]
-fn black_box(i: u32) {
-    if i != 1 {
-        core::intrinsics::abort();
-    }
-}
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index c81c53359fd..30732c74eb3 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -513,7 +513,6 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         } else {
             // If the symbol already exists, it is an error: for example, the user wrote
             // #[no_mangle] extern "C" fn main(..) {..}
-            // instead of #[start]
             None
         }
     }
diff --git a/compiler/rustc_codegen_gcc/tests/run/abort1.rs b/compiler/rustc_codegen_gcc/tests/run/abort1.rs
index 696197d7377..385e41a6881 100644
--- a/compiler/rustc_codegen_gcc/tests/run/abort1.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/abort1.rs
@@ -3,11 +3,12 @@
 // Run-time:
 //   status: signal
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -49,7 +50,7 @@ fn test_fail() -> ! {
     unsafe { intrinsics::abort() };
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     test_fail();
 }
diff --git a/compiler/rustc_codegen_gcc/tests/run/abort2.rs b/compiler/rustc_codegen_gcc/tests/run/abort2.rs
index 714cd6c0f38..6c66a930e07 100644
--- a/compiler/rustc_codegen_gcc/tests/run/abort2.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/abort2.rs
@@ -3,11 +3,12 @@
 // Run-time:
 //   status: signal
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -50,8 +51,8 @@ fn fail() -> i32 {
     0
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     fail();
     0
 }
diff --git a/compiler/rustc_codegen_gcc/tests/run/array.rs b/compiler/rustc_codegen_gcc/tests/run/array.rs
index c3c08c29c6d..e18a4ced6bc 100644
--- a/compiler/rustc_codegen_gcc/tests/run/array.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/array.rs
@@ -7,10 +7,11 @@
 //     5
 //     10
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -28,8 +29,8 @@ fn make_array() -> [u8; 3] {
     [42, 10, 5]
 }
 
-#[start]
-fn main(argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let array = [42, 7, 5];
     let array2 = make_array();
     unsafe {
diff --git a/compiler/rustc_codegen_gcc/tests/run/assign.rs b/compiler/rustc_codegen_gcc/tests/run/assign.rs
index 2a47f0c2966..4d414c577a6 100644
--- a/compiler/rustc_codegen_gcc/tests/run/assign.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/assign.rs
@@ -6,10 +6,11 @@
 //     10
 
 #![allow(internal_features, unused_attributes)]
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -142,8 +143,8 @@ fn inc(num: isize) -> isize {
 }
 
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     argc = inc(argc);
     unsafe {
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc);
diff --git a/compiler/rustc_codegen_gcc/tests/run/closure.rs b/compiler/rustc_codegen_gcc/tests/run/closure.rs
index 46c47bc54ed..c7a236f74f9 100644
--- a/compiler/rustc_codegen_gcc/tests/run/closure.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/closure.rs
@@ -8,10 +8,11 @@
 //     Int argument: 2
 //     Both args: 11
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -22,8 +23,8 @@ mod libc {
     }
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let string = "Arg: %d\n\0";
     let mut closure = || {
         unsafe {
diff --git a/compiler/rustc_codegen_gcc/tests/run/condition.rs b/compiler/rustc_codegen_gcc/tests/run/condition.rs
index 039ef94eaa7..b02359702ed 100644
--- a/compiler/rustc_codegen_gcc/tests/run/condition.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/condition.rs
@@ -5,10 +5,11 @@
 //   stdout: true
 //     1
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -19,8 +20,8 @@ mod libc {
     }
 }
 
-#[start]
-fn main(argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     unsafe {
         if argc == 1 {
             libc::printf(b"true\n\0" as *const u8 as *const i8);
diff --git a/compiler/rustc_codegen_gcc/tests/run/empty_main.rs b/compiler/rustc_codegen_gcc/tests/run/empty_main.rs
index e66a859ad69..042e44080c5 100644
--- a/compiler/rustc_codegen_gcc/tests/run/empty_main.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/empty_main.rs
@@ -3,11 +3,12 @@
 // Run-time:
 //   status: 0
 
-#![feature(auto_traits, lang_items, no_core, start)]
+#![feature(auto_traits, lang_items, no_core)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -34,7 +35,7 @@ pub(crate) unsafe auto trait Freeze {}
  * Code
  */
 
-#[start]
-fn main(_argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     0
 }
diff --git a/compiler/rustc_codegen_gcc/tests/run/exit.rs b/compiler/rustc_codegen_gcc/tests/run/exit.rs
index bf1cbeef302..9a7c91c0adb 100644
--- a/compiler/rustc_codegen_gcc/tests/run/exit.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/exit.rs
@@ -3,11 +3,12 @@
 // Run-time:
 //   status: 2
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![feature(auto_traits, lang_items, no_core, intrinsics)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 mod libc {
     #[link(name = "c")]
@@ -41,8 +42,8 @@ pub(crate) unsafe auto trait Freeze {}
  * Code
  */
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     unsafe {
         libc::exit(2);
     }
diff --git a/compiler/rustc_codegen_gcc/tests/run/exit_code.rs b/compiler/rustc_codegen_gcc/tests/run/exit_code.rs
index be7a233efda..c50d2b0d710 100644
--- a/compiler/rustc_codegen_gcc/tests/run/exit_code.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/exit_code.rs
@@ -3,11 +3,12 @@
 // Run-time:
 //   status: 1
 
-#![feature(auto_traits, lang_items, no_core, start)]
+#![feature(auto_traits, lang_items, no_core)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -34,7 +35,7 @@ pub(crate) unsafe auto trait Freeze {}
  * Code
  */
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     1
 }
diff --git a/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
index ed1bf72bb27..98b351e5044 100644
--- a/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
@@ -4,10 +4,11 @@
 //   status: 0
 //   stdout: 1
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -26,8 +27,8 @@ fn call_func(func: fn(i16) -> i8, param: i16) -> i8 {
     func(param)
 }
 
-#[start]
-fn main(argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     unsafe {
         let result = call_func(i16_as_i8, argc as i16) as isize;
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, result);
diff --git a/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs
index 3ae79338216..9be64f991ee 100644
--- a/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs
@@ -8,10 +8,11 @@
 //     11
 
 #![allow(internal_features, unused_attributes)]
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -148,8 +149,8 @@ fn update_num(num: &mut isize) {
     *num = *num + 5;
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let mut test = test(argc);
     unsafe {
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field);
diff --git a/compiler/rustc_codegen_gcc/tests/run/operations.rs b/compiler/rustc_codegen_gcc/tests/run/operations.rs
index 0e44fc580b8..c92d3cc0b8f 100644
--- a/compiler/rustc_codegen_gcc/tests/run/operations.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/operations.rs
@@ -6,10 +6,11 @@
 //     10
 
 #![allow(internal_features, unused_attributes)]
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, arbitrary_self_types, rustc_attrs)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, arbitrary_self_types, rustc_attrs)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -231,8 +232,8 @@ pub fn panic_const_mul_overflow() -> ! {
  * Code
  */
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     unsafe {
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 + argc);
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 - argc);
diff --git a/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
index 2b8812ad51c..0ba49e7187f 100644
--- a/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
@@ -4,10 +4,11 @@
 //   status: 0
 //   stdout: 1
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -24,8 +25,8 @@ fn make_array() -> [u8; 3] {
     [42, 10, 5]
 }
 
-#[start]
-fn main(argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     unsafe {
         let ptr = ONE as *mut usize;
         let value = ptr as usize;
diff --git a/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs
index f2a5a2e4384..3cc1e274001 100644
--- a/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs
@@ -6,11 +6,12 @@
 //     10
 //     42
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![feature(auto_traits, lang_items, no_core, intrinsics)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 #[lang = "copy"]
 pub unsafe trait Copy {}
@@ -61,8 +62,8 @@ fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u3
     )
 }
 
-#[start]
-fn main(argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let (a, b, c, d, e, f, g, h, i, j) = int_cast(10, 42);
     unsafe {
         libc::printf(b"%d\n\0" as *const u8 as *const i8, c);
diff --git a/compiler/rustc_codegen_gcc/tests/run/slice.rs b/compiler/rustc_codegen_gcc/tests/run/slice.rs
index fba93fc1554..825fcb8a081 100644
--- a/compiler/rustc_codegen_gcc/tests/run/slice.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/slice.rs
@@ -4,10 +4,11 @@
 //   status: 0
 //   stdout: 5
 
-#![feature(no_core, start)]
+#![feature(no_core)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 extern crate mini_core;
 
@@ -26,8 +27,8 @@ fn index_slice(s: &[u32]) -> u32 {
     }
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let array = [42, 7, 5];
     unsafe {
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, index_slice(&array));
diff --git a/compiler/rustc_codegen_gcc/tests/run/static.rs b/compiler/rustc_codegen_gcc/tests/run/static.rs
index a17ea2a4893..80c8782c4b1 100644
--- a/compiler/rustc_codegen_gcc/tests/run/static.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/static.rs
@@ -9,11 +9,12 @@
 //      12
 //      1
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
+#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -98,8 +99,8 @@ static mut WITH_REF: WithRef = WithRef {
     refe: unsafe { &TEST },
 };
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     unsafe {
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, CONSTANT);
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST2.field);
diff --git a/compiler/rustc_codegen_gcc/tests/run/structs.rs b/compiler/rustc_codegen_gcc/tests/run/structs.rs
index d6455667400..59b8f358863 100644
--- a/compiler/rustc_codegen_gcc/tests/run/structs.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/structs.rs
@@ -5,11 +5,12 @@
 //   stdout: 1
 //     2
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![feature(auto_traits, lang_items, no_core, intrinsics)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -55,8 +56,8 @@ fn one() -> isize {
     1
 }
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let test = Test {
         field: one(),
     };
diff --git a/compiler/rustc_codegen_gcc/tests/run/tuple.rs b/compiler/rustc_codegen_gcc/tests/run/tuple.rs
index 8a7d85ae867..ed60a56a68c 100644
--- a/compiler/rustc_codegen_gcc/tests/run/tuple.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/tuple.rs
@@ -4,11 +4,12 @@
 //   status: 0
 //   stdout: 3
 
-#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![feature(auto_traits, lang_items, no_core, intrinsics)]
 #![allow(internal_features)]
 
 #![no_std]
 #![no_core]
+#![no_main]
 
 /*
  * Core
@@ -42,8 +43,8 @@ mod libc {
  * Code
  */
 
-#[start]
-fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+#[no_mangle]
+extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
     let test: (isize, isize, isize) = (3, 1, 4);
     unsafe {
         libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.0);