diff options
Diffstat (limited to 'compiler/rustc_codegen_gcc/tests')
38 files changed, 2567 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_gcc/tests/failing-ice-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-ice-tests.txt new file mode 100644 index 00000000000..ff1b6f14894 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/failing-ice-tests.txt @@ -0,0 +1,40 @@ +tests/ui/treat-err-as-bug/span_delayed_bug.rs +tests/ui/treat-err-as-bug/err.rs +tests/ui/simd/not-out-of-bounds.rs +tests/ui/simd/monomorphize-shuffle-index.rs +tests/ui/simd/masked-load-store-build-fail.rs +tests/ui/simd/intrinsic/generic-shuffle.rs +tests/ui/simd/intrinsic/generic-elements.rs +tests/ui/simd/intrinsic/generic-cast.rs +tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs +tests/ui/simd/intrinsic/generic-arithmetic-2.rs +tests/ui/panics/default-backtrace-ice.rs +tests/ui/mir/lint/storage-live.rs +tests/ui/layout/valid_range_oob.rs +tests/ui/higher-ranked/trait-bounds/future.rs +tests/ui/consts/const-eval/const-eval-query-stack.rs +tests/ui/simd/masked-load-store.rs +tests/ui/simd/issue-39720.rs +tests/ui/simd/intrinsic/ptr-cast.rs +tests/ui/sepcomp/sepcomp-statics.rs +tests/ui/sepcomp/sepcomp-fns.rs +tests/ui/sepcomp/sepcomp-fns-backwards.rs +tests/ui/sepcomp/sepcomp-extern.rs +tests/ui/sepcomp/sepcomp-cci.rs +tests/ui/lto/thin-lto-inlines2.rs +tests/ui/lto/weak-works.rs +tests/ui/lto/thin-lto-inlines.rs +tests/ui/lto/thin-lto-global-allocator.rs +tests/ui/lto/msvc-imp-present.rs +tests/ui/lto/dylib-works.rs +tests/ui/lto/all-crates.rs +tests/ui/issues/issue-47364.rs +tests/ui/functions-closures/parallel-codegen-closures.rs +tests/ui/sepcomp/sepcomp-unwind.rs +tests/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs +tests/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs +tests/ui/unwind-no-uwtable.rs +tests/ui/delegation/fn-header.rs +tests/ui/simd/intrinsic/generic-arithmetic-pass.rs +tests/ui/simd/masked-load-store.rs +tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs diff --git a/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt new file mode 100644 index 00000000000..b9126fb73a7 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt @@ -0,0 +1,33 @@ +tests/ui/lint/unsafe_code/forge_unsafe_block.rs +tests/ui/lint/unused-qualification-in-derive-expansion.rs +tests/ui/macros/macro-quote-test.rs +tests/ui/macros/proc_macro.rs +tests/ui/panic-runtime/lto-unwind.rs +tests/ui/resolve/derive-macro-1.rs +tests/ui/resolve/derive-macro-2.rs +tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-pretty.rs +tests/ui/rfcs/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs +tests/ui/rfcs/rfc-3348-c-string-literals/edition-spans.rs +tests/ui/rust-2018/suggestions-not-always-applicable.rs +tests/ui/rust-2021/reserved-prefixes-via-macro.rs +tests/ui/underscore-imports/duplicate.rs +tests/ui/async-await/issues/issue-60674.rs +tests/ui/attributes/main-removed-2/main.rs +tests/ui/cfg/assume-incomplete-release/assume-incomplete.rs +tests/ui/crate-loading/cross-compiled-proc-macro.rs +tests/ui/derives/derive-marker-tricky.rs +tests/ui/diagnostic_namespace/existing_proc_macros.rs +tests/ui/fmt/format-args-capture-issue-106408.rs +tests/ui/fmt/indoc-issue-106408.rs +tests/ui/hygiene/issue-77523-def-site-async-await.rs +tests/ui/inherent-impls-overlap-check/no-overlap.rs +tests/ui/enum-discriminant/issue-46519.rs +tests/ui/issues/issue-45731.rs +tests/ui/lint/test-allow-dead-extern-static-no-warning.rs +tests/ui/macros/macro-comma-behavior-rpass.rs +tests/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs +tests/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs +tests/ui/macros/stringify.rs +tests/ui/reexport-test-harness-main.rs +tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-in-test.rs +tests/ui/binding/fn-arg-incomplete-pattern-drop-order.rs diff --git a/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt new file mode 100644 index 00000000000..842533cd3c6 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt @@ -0,0 +1,42 @@ +tests/run-make/a-b-a-linker-guard/ +tests/run-make/CURRENT_RUSTC_VERSION/ +tests/run-make/cross-lang-lto/ +tests/run-make/cross-lang-lto-upstream-rlibs/ +tests/run-make/doctests-keep-binaries/ +tests/run-make/doctests-runtool/ +tests/run-make/emit-shared-files/ +tests/run-make/exit-code/ +tests/run-make/issue-22131/ +tests/run-make/issue-64153/ +tests/run-make/llvm-ident/ +tests/run-make/native-link-modifier-bundle/ +tests/run-make/remap-path-prefix-dwarf/ +tests/run-make/repr128-dwarf/ +tests/run-make/rlib-format-packed-bundled-libs/ +tests/run-make/rlib-format-packed-bundled-libs-2/ +tests/run-make/rustdoc-determinism/ +tests/run-make/rustdoc-error-lines/ +tests/run-make/rustdoc-map-file/ +tests/run-make/rustdoc-output-path/ +tests/run-make/rustdoc-scrape-examples-invalid-expr/ +tests/run-make/rustdoc-scrape-examples-multiple/ +tests/run-make/rustdoc-scrape-examples-ordering/ +tests/run-make/rustdoc-scrape-examples-remap/ +tests/run-make/rustdoc-scrape-examples-test/ +tests/run-make/rustdoc-scrape-examples-whitespace/ +tests/run-make/rustdoc-scrape-examples-macros/ +tests/run-make/rustdoc-with-out-dir-option/ +tests/run-make/rustdoc-verify-output-files/ +tests/run-make/rustdoc-themes/ +tests/run-make/rustdoc-with-short-out-dir-option/ +tests/run-make/rustdoc-with-output-option/ +tests/run-make/arguments-non-c-like-enum/ +tests/run-make/c-link-to-rust-staticlib/ +tests/run-make/foreign-double-unwind/ +tests/run-make/foreign-exceptions/ +tests/run-make/glibc-staticlib-args/ +tests/run-make/issue-36710/ +tests/run-make/issue-68794-textrel-on-minimal-lib/ +tests/run-make/lto-smoke-c/ +tests/run-make/return-non-c-like-enum/ + diff --git a/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt new file mode 100644 index 00000000000..082958bfe1f --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt @@ -0,0 +1,124 @@ +tests/ui/allocator/no_std-alloc-error-handler-custom.rs +tests/ui/allocator/no_std-alloc-error-handler-default.rs +tests/ui/asm/may_unwind.rs +tests/ui/asm/x86_64/multiple-clobber-abi.rs +tests/ui/functions-closures/parallel-codegen-closures.rs +tests/ui/linkage-attr/linkage1.rs +tests/ui/lto/dylib-works.rs +tests/ui/numbers-arithmetic/saturating-float-casts.rs +tests/ui/sepcomp/sepcomp-cci.rs +tests/ui/sepcomp/sepcomp-extern.rs +tests/ui/sepcomp/sepcomp-fns-backwards.rs +tests/ui/sepcomp/sepcomp-fns.rs +tests/ui/sepcomp/sepcomp-statics.rs +tests/ui/asm/x86_64/may_unwind.rs +tests/ui/catch-unwind-bang.rs +tests/ui/drop/dynamic-drop-async.rs +tests/ui/cfg/cfg-panic-abort.rs +tests/ui/drop/repeat-drop.rs +tests/ui/coroutine/panic-drops-resume.rs +tests/ui/fmt/format-args-capture.rs +tests/ui/coroutine/panic-drops.rs +tests/ui/intrinsics/panic-uninitialized-zeroed.rs +tests/ui/iterators/iter-sum-overflow-debug.rs +tests/ui/iterators/iter-sum-overflow-overflow-checks.rs +tests/ui/mir/mir_calls_to_shims.rs +tests/ui/mir/mir_drop_order.rs +tests/ui/mir/mir_let_chains_drop_order.rs +tests/ui/oom_unwind.rs +tests/ui/panic-runtime/abort-link-to-unwinding-crates.rs +tests/ui/panic-runtime/abort.rs +tests/ui/panic-runtime/link-to-abort.rs +tests/ui/unwind-no-uwtable.rs +tests/ui/parser/unclosed-delimiter-in-dep.rs +tests/ui/consts/missing_span_in_backtrace.rs +tests/ui/drop/dynamic-drop.rs +tests/ui/issues/issue-40883.rs +tests/ui/issues/issue-43853.rs +tests/ui/issues/issue-47364.rs +tests/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs +tests/ui/rfcs/rfc-1857-stabilize-drop-order/drop-order.rs +tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.rs +tests/ui/simd/issue-17170.rs +tests/ui/simd/issue-39720.rs +tests/ui/alloc-error/default-alloc-error-hook.rs +tests/ui/coroutine/panic-safe.rs +tests/ui/issues/issue-14875.rs +tests/ui/issues/issue-29948.rs +tests/ui/panics/nested_panic_caught.rs +tests/ui/process/println-with-broken-pipe.rs +tests/ui/lto/thin-lto-inlines2.rs +tests/ui/lto/weak-works.rs +tests/ui/panic-runtime/lto-abort.rs +tests/ui/lto/thin-lto-inlines.rs +tests/ui/lto/thin-lto-global-allocator.rs +tests/ui/lto/msvc-imp-present.rs +tests/ui/lto/lto-thin-rustc-loads-linker-plugin.rs +tests/ui/lto/all-crates.rs +tests/ui/async-await/deep-futures-are-freeze.rs +tests/ui/coroutine/resume-after-return.rs +tests/ui/simd/masked-load-store.rs +tests/ui/simd/repr_packed.rs +tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs +tests/ui/consts/try-operator.rs +tests/ui/coroutine/unwind-abort-mix.rs +tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs +tests/ui/impl-trait/equality-in-canonical-query.rs +tests/ui/consts/issue-miri-1910.rs +tests/ui/mir/mir_heavy_promoted.rs +tests/ui/consts/const_cmp_type_id.rs +tests/ui/consts/issue-73976-monomorphic.rs +tests/ui/consts/issue-94675.rs +tests/ui/traits/const-traits/const-drop-fail.rs +tests/ui/traits/const-traits/const-drop.rs +tests/ui/runtime/on-broken-pipe/child-processes.rs +tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs +tests/ui/sanitizer/cfi/async-closures.rs +tests/ui/sanitizer/cfi/closures.rs +tests/ui/sanitizer/cfi/complex-receiver.rs +tests/ui/sanitizer/cfi/coroutine.rs +tests/ui/sanitizer/cfi/drop-in-place.rs +tests/ui/sanitizer/cfi/drop-no-principal.rs +tests/ui/sanitizer/cfi/fn-ptr.rs +tests/ui/sanitizer/cfi/self-ref.rs +tests/ui/sanitizer/cfi/supertraits.rs +tests/ui/sanitizer/cfi/virtual-auto.rs +tests/ui/sanitizer/cfi/sized-associated-ty.rs +tests/ui/sanitizer/cfi/can-reveal-opaques.rs +tests/ui/sanitizer/kcfi-mangling.rs +tests/ui/statics/const_generics.rs +tests/ui/backtrace/dylib-dep.rs +tests/ui/errors/pic-linker.rs +tests/ui/delegation/fn-header.rs +tests/ui/consts/zst_no_llvm_alloc.rs +tests/ui/consts/const-eval/parse_ints.rs +tests/ui/simd/intrinsic/generic-arithmetic-pass.rs +tests/ui/simd/intrinsic/generic-as.rs +tests/ui/backtrace/backtrace.rs +tests/ui/lifetimes/tail-expr-lock-poisoning.rs +tests/ui/runtime/rt-explody-panic-payloads.rs +tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs +tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs +tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.rs +tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs +tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs +tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs +tests/ui/codegen/equal-pointers-unequal/as-cast/segfault.rs +tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs +tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs +tests/ui/codegen/equal-pointers-unequal/as-cast/zero.rs +tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs +tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs +tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs +tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs +tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs +tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs +tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs +tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs +tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs +tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs +tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs +tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs +tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs +tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs +tests/ui/simd/simd-bitmask-notpow2.rs diff --git a/compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt b/compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt new file mode 100644 index 00000000000..b10d4bc82aa --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt @@ -0,0 +1,47 @@ +tests/ui/asm/x86_64/issue-96797.rs +tests/ui/intrinsics/const-eval-select-x86_64.rs +tests/ui/packed/packed-struct-drop-aligned.rs +tests/ui/packed/packed-struct-generic-layout.rs +tests/ui/packed/packed-struct-layout.rs +tests/ui/packed/packed-struct-optimized-enum.rs +tests/ui/packed/packed-struct-size.rs +tests/ui/packed/packed-struct-vec.rs +tests/ui/packed/packed-tuple-struct-layout.rs +tests/ui/simd/array-type.rs +tests/ui/simd/intrinsic/float-minmax-pass.rs +tests/ui/simd/intrinsic/generic-arithmetic-pass.rs +tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs +tests/ui/simd/intrinsic/generic-cast-pass.rs +tests/ui/simd/intrinsic/generic-cast-pointer-width.rs +tests/ui/simd/intrinsic/generic-comparison-pass.rs +tests/ui/simd/intrinsic/generic-elements-pass.rs +tests/ui/simd/intrinsic/generic-reduction-pass.rs +tests/ui/simd/intrinsic/generic-select-pass.rs +tests/ui/simd/intrinsic/inlining-issue67557-ice.rs +tests/ui/simd/intrinsic/inlining-issue67557.rs +tests/ui/simd/shuffle.rs +tests/ui/simd/simd-bitmask.rs +tests/ui/iterators/iter-step-overflow-debug.rs +tests/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs +tests/ui/privacy/reachable-unnameable-items.rs +tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-in-test.rs +tests/ui/async-await/async-fn-size-moved-locals.rs +tests/ui/async-await/async-fn-size-uninit-locals.rs +tests/ui/cfg/cfg-panic.rs +tests/ui/coroutine/size-moved-locals.rs +tests/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs +tests/ui/simd/intrinsic/generic-gather-pass.rs +tests/ui/simd/issue-85915-simd-ptrs.rs +tests/ui/simd/issue-89193.rs +tests/ui/issues/issue-68010-large-zst-consts.rs +tests/ui/rust-2018/proc-macro-crate-in-paths.rs +tests/ui/target-feature/missing-plusminus.rs +tests/ui/sse2.rs +tests/ui/codegen/issue-79865-llvm-miscompile.rs +tests/ui/std-backtrace.rs +tests/ui/mir/alignment/packed.rs +tests/ui/intrinsics/intrinsics-integer.rs +tests/ui/asm/x86_64/evex512-implicit-feature.rs +tests/ui/packed/dyn-trait.rs +tests/ui/packed/issue-118537-field-offset-ice.rs +tests/ui/stable-mir-print/basic_function.rs diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.lock b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.lock new file mode 100644 index 00000000000..fe252db4425 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.lock @@ -0,0 +1,14 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "hello_world" +version = "0.0.0" +dependencies = [ + "mylib", +] + +[[package]] +name = "mylib" +version = "0.1.0" diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml new file mode 100644 index 00000000000..c6e22f642f6 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "hello_world" +edition = "2024" + +[dependencies] +mylib = { path = "mylib" } + +[profile.dev] +lto = "thin" + +[profile.release] +lto = "fat" diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.lock b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.lock new file mode 100644 index 00000000000..c8a0bfc6354 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "mylib" +version = "0.1.0" diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.toml b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.toml new file mode 100644 index 00000000000..d15f62bfb6d --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "mylib" +version = "0.1.0" +authors = ["Antoni Boucher <bouanto@zoho.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/mylib/src/lib.rs b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/src/lib.rs new file mode 100644 index 00000000000..8d3d111bd19 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/src/lib.rs @@ -0,0 +1,7 @@ +pub fn my_func(a: i32, b: i32) -> i32 { + let mut res = a; + for i in a..b { + res += i; + } + res +} diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs b/compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs new file mode 100644 index 00000000000..71c78d364ac --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs @@ -0,0 +1,5 @@ +use mylib::my_func; + +fn main() { + println!("{}", my_func(5, 10)); +} diff --git a/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs b/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs new file mode 100644 index 00000000000..fafb7be55ce --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs @@ -0,0 +1,148 @@ +//! The common code for `tests/lang_tests_*.rs` + +use std::{ + env::{self, current_dir}, + path::{Path, PathBuf}, + process::Command, +}; + +use boml::Toml; +use lang_tester::LangTester; +use tempfile::TempDir; + +/// Controls the compile options (e.g., optimization level) used to compile +/// test code. +#[allow(dead_code)] // Each test crate picks one variant +pub enum Profile { + Debug, + Release, +} + +pub fn main_inner(profile: Profile) { + let tempdir = TempDir::new().expect("temp dir"); + let current_dir = current_dir().expect("current dir"); + let current_dir = current_dir.to_str().expect("current dir").to_string(); + + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + + let gcc_path = std::fs::read_to_string(manifest_dir.join("config.toml")) + .ok() + .and_then(|v| { + let toml = Toml::parse(&v).expect("Failed to parse `config.toml`"); + toml.get_string("gcc-path").map(PathBuf::from).ok() + }) + .unwrap_or_else(|| { + // then we try to retrieve it from the `target` folder. + let commit = include_str!("../libgccjit.version").trim(); + Path::new("build/libgccjit").join(commit) + }); + + let gcc_path = Path::new(&gcc_path) + .canonicalize() + .expect("failed to get absolute path of `gcc-path`") + .display() + .to_string(); + env::set_var("LD_LIBRARY_PATH", gcc_path); + + fn rust_filter(path: &Path) -> bool { + path.is_file() && path.extension().expect("extension").to_str().expect("to_str") == "rs" + } + + #[cfg(feature = "master")] + fn filter(filename: &Path) -> bool { + rust_filter(filename) + } + + #[cfg(not(feature = "master"))] + fn filter(filename: &Path) -> bool { + if let Some(filename) = filename.to_str() { + if filename.ends_with("gep.rs") { + return false; + } + } + rust_filter(filename) + } + + LangTester::new() + .test_dir("tests/run") + .test_path_filter(filter) + .test_extract(|path| { + let lines = std::fs::read_to_string(path) + .expect("read file") + .lines() + .skip_while(|l| !l.starts_with("//")) + .take_while(|l| l.starts_with("//")) + .map(|l| &l[2..]) + .collect::<Vec<_>>() + .join("\n"); + lines + }) + .test_cmds(move |path| { + // Test command 1: Compile `x.rs` into `tempdir/x`. + let mut exe = PathBuf::new(); + exe.push(&tempdir); + exe.push(path.file_stem().expect("file_stem")); + let mut compiler = Command::new("rustc"); + compiler.args([ + &format!("-Zcodegen-backend={}/target/debug/librustc_codegen_gcc.so", current_dir), + "--sysroot", + &format!("{}/build/build_sysroot/sysroot/", current_dir), + "-C", + "link-arg=-lc", + "--extern", + "mini_core=target/out/libmini_core.rlib", + "-o", + exe.to_str().expect("to_str"), + path.to_str().expect("to_str"), + ]); + + // TODO(antoyo): find a way to send this via a cli argument. + let test_target = std::env::var("CG_GCC_TEST_TARGET"); + if let Ok(ref target) = test_target { + compiler.args(["--target", target]); + let linker = format!("{}-gcc", target); + compiler.args(&[format!("-Clinker={}", linker)]); + let mut env_path = std::env::var("PATH").unwrap_or_default(); + // TODO(antoyo): find a better way to add the PATH necessary locally. + env_path = format!("/opt/m68k-unknown-linux-gnu/bin:{}", env_path); + compiler.env("PATH", env_path); + } + + if let Some(flags) = option_env!("TEST_FLAGS") { + for flag in flags.split_whitespace() { + compiler.arg(flag); + } + } + match profile { + Profile::Debug => {} + Profile::Release => { + compiler.args(["-C", "opt-level=3", "-C", "lto=no"]); + } + } + // Test command 2: run `tempdir/x`. + if test_target.is_ok() { + let vm_parent_dir = std::env::var("CG_GCC_VM_DIR") + .map(PathBuf::from) + .unwrap_or_else(|_| std::env::current_dir().unwrap()); + let vm_dir = "vm"; + let exe_filename = exe.file_name().unwrap(); + let vm_home_dir = vm_parent_dir.join(vm_dir).join("home"); + let vm_exe_path = vm_home_dir.join(exe_filename); + // FIXME(antoyo): panicking here makes the test pass. + let inside_vm_exe_path = PathBuf::from("/home").join(exe_filename); + let mut copy = Command::new("sudo"); + copy.arg("cp"); + copy.args([&exe, &vm_exe_path]); + + let mut runtime = Command::new("sudo"); + runtime.args(["chroot", vm_dir, "qemu-m68k-static"]); + runtime.arg(inside_vm_exe_path); + runtime.current_dir(vm_parent_dir); + vec![("Compiler", compiler), ("Copy", copy), ("Run-time", runtime)] + } else { + let runtime = Command::new(exe); + vec![("Compiler", compiler), ("Run-time", runtime)] + } + }) + .run(); +} diff --git a/compiler/rustc_codegen_gcc/tests/lang_tests_debug.rs b/compiler/rustc_codegen_gcc/tests/lang_tests_debug.rs new file mode 100644 index 00000000000..96bd74883ff --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/lang_tests_debug.rs @@ -0,0 +1,5 @@ +mod lang_tests_common; + +fn main() { + lang_tests_common::main_inner(lang_tests_common::Profile::Debug); +} diff --git a/compiler/rustc_codegen_gcc/tests/lang_tests_release.rs b/compiler/rustc_codegen_gcc/tests/lang_tests_release.rs new file mode 100644 index 00000000000..35d5d60c33e --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/lang_tests_release.rs @@ -0,0 +1,5 @@ +mod lang_tests_common; + +fn main() { + lang_tests_common::main_inner(lang_tests_common::Profile::Release); +} diff --git a/compiler/rustc_codegen_gcc/tests/run/abort1.rs b/compiler/rustc_codegen_gcc/tests/run/abort1.rs new file mode 100644 index 00000000000..696197d7377 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/abort1.rs @@ -0,0 +1,55 @@ +// Compiler: +// +// Run-time: +// status: signal + +#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] +#![allow(internal_features)] + +#![no_std] +#![no_core] + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "copy"] +trait Copy { +} + +impl Copy for isize {} + +#[lang = "receiver"] +trait Receiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +mod intrinsics { + use super::Sized; + + #[rustc_nounwind] + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + pub fn abort() -> ! { + loop {} + } +} + +/* + * Code + */ + +fn test_fail() -> ! { + unsafe { intrinsics::abort() }; +} + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + test_fail(); +} diff --git a/compiler/rustc_codegen_gcc/tests/run/abort2.rs b/compiler/rustc_codegen_gcc/tests/run/abort2.rs new file mode 100644 index 00000000000..714cd6c0f38 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/abort2.rs @@ -0,0 +1,57 @@ +// Compiler: +// +// Run-time: +// status: signal + +#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] +#![allow(internal_features)] + +#![no_std] +#![no_core] + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "copy"] +trait Copy { +} + +impl Copy for isize {} + +#[lang = "receiver"] +trait Receiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +mod intrinsics { + use super::Sized; + + #[rustc_nounwind] + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + pub fn abort() -> ! { + loop {} + } +} + +/* + * Code + */ + +fn fail() -> i32 { + unsafe { intrinsics::abort() }; + 0 +} + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + fail(); + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/array.rs b/compiler/rustc_codegen_gcc/tests/run/array.rs new file mode 100644 index 00000000000..c3c08c29c6d --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/array.rs @@ -0,0 +1,43 @@ +// Compiler: +// +// Run-time: +// status: 0 +// stdout: 42 +// 7 +// 5 +// 10 + +#![feature(no_core, start)] + +#![no_std] +#![no_core] + +extern crate mini_core; + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn printf(format: *const i8, ...) -> i32; + pub fn puts(s: *const u8) -> i32; + } +} + +static mut ONE: usize = 1; + +fn make_array() -> [u8; 3] { + [42, 10, 5] +} + +#[start] +fn main(argc: isize, _argv: *const *const u8) -> isize { + let array = [42, 7, 5]; + let array2 = make_array(); + unsafe { + libc::printf(b"%ld\n\0" as *const u8 as *const i8, array[ONE - 1]); + libc::printf(b"%ld\n\0" as *const u8 as *const i8, array[ONE]); + libc::printf(b"%ld\n\0" as *const u8 as *const i8, array[ONE + 1]); + + libc::printf(b"%d\n\0" as *const u8 as *const i8, array2[argc as usize] as u32); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/asm.rs b/compiler/rustc_codegen_gcc/tests/run/asm.rs new file mode 100644 index 00000000000..4e05d026868 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/asm.rs @@ -0,0 +1,184 @@ +// Compiler: +// +// Run-time: +// status: 0 + +#[cfg(target_arch = "x86_64")] +use std::arch::{asm, global_asm}; + +#[cfg(target_arch = "x86_64")] +global_asm!( + " + .global add_asm +add_asm: + mov rax, rdi + add rax, rsi + ret" +); + +extern "C" { + fn add_asm(a: i64, b: i64) -> i64; +} + +#[cfg(target_arch = "x86_64")] +pub unsafe fn mem_cpy(dst: *mut u8, src: *const u8, len: usize) { + asm!( + "rep movsb", + inout("rdi") dst => _, + inout("rsi") src => _, + inout("rcx") len => _, + options(preserves_flags, nostack) + ); +} + +#[cfg(target_arch = "x86_64")] +fn asm() { + unsafe { + asm!("nop"); + } + + let x: u64; + unsafe { + asm!("mov $5, {}", + out(reg) x, + options(att_syntax) + ); + } + assert_eq!(x, 5); + + let x: u64; + let input: u64 = 42; + unsafe { + asm!("mov {input}, {output}", + "add $1, {output}", + input = in(reg) input, + output = out(reg) x, + options(att_syntax) + ); + } + assert_eq!(x, 43); + + let x: u64; + unsafe { + asm!("mov {}, 6", + out(reg) x, + ); + } + assert_eq!(x, 6); + + let x: u64; + let input: u64 = 42; + unsafe { + asm!("mov {output}, {input}", + "add {output}, 1", + input = in(reg) input, + output = out(reg) x, + ); + } + assert_eq!(x, 43); + + // check inout(reg_class) x + let mut x: u64 = 42; + unsafe { + asm!("add {0}, {0}", + inout(reg) x + ); + } + assert_eq!(x, 84); + + // check inout("reg") x + let mut x: u64 = 42; + unsafe { + asm!("add r11, r11", + inout("r11") x + ); + } + assert_eq!(x, 84); + + // check a mix of + // in("reg") + // inout(class) x => y + // inout (class) x + let x: u64 = 702; + let y: u64 = 100; + let res: u64; + let mut rem: u64 = 0; + unsafe { + asm!("div r11", + in("r11") y, + inout("eax") x => res, + inout("edx") rem, + ); + } + assert_eq!(res, 7); + assert_eq!(rem, 2); + + // check const + let mut x: u64 = 42; + unsafe { + asm!("add {}, {}", + inout(reg) x, + const 1 + ); + } + assert_eq!(x, 43); + + // check const (ATT syntax) + let mut x: u64 = 42; + unsafe { + asm!("add ${}, {}", + const 1, + inout(reg) x, + options(att_syntax) + ); + } + assert_eq!(x, 43); + + // check sym fn + extern "C" fn foo() -> u64 { + 42 + } + let x: u64; + unsafe { + asm!("call {}", sym foo, lateout("rax") x); + } + assert_eq!(x, 42); + + // check sym fn (ATT syntax) + let x: u64; + unsafe { + asm!("call {}", sym foo, lateout("rax") x, options(att_syntax)); + } + assert_eq!(x, 42); + + // check sym static + static FOO: u64 = 42; + let x: u64; + unsafe { + asm!("mov {1}, qword ptr [rip + {0}]", sym FOO, lateout(reg) x); + } + assert_eq!(x, 42); + + // check sym static (ATT syntax) + let x: u64; + unsafe { + asm!("movq {0}(%rip), {1}", sym FOO, lateout(reg) x, options(att_syntax)); + } + assert_eq!(x, 42); + + assert_eq!(unsafe { add_asm(40, 2) }, 42); + + let array1 = [1u8, 2, 3]; + let mut array2 = [0u8, 0, 0]; + unsafe { + mem_cpy(array2.as_mut_ptr(), array1.as_ptr(), 3); + } + assert_eq!(array1, array2); +} + +#[cfg(not(target_arch = "x86_64"))] +fn asm() {} + +fn main() { + asm(); +} diff --git a/compiler/rustc_codegen_gcc/tests/run/assign.rs b/compiler/rustc_codegen_gcc/tests/run/assign.rs new file mode 100644 index 00000000000..2a47f0c2966 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/assign.rs @@ -0,0 +1,162 @@ +// Compiler: +// +// Run-time: +// stdout: 2 +// 7 8 +// 10 + +#![allow(internal_features, unused_attributes)] +#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)] + +#![no_std] +#![no_core] + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "copy"] +trait Copy { +} + +impl Copy for isize {} +impl Copy for *mut i32 {} +impl Copy for usize {} +impl Copy for u8 {} +impl Copy for i8 {} +impl Copy for i32 {} + +#[lang = "receiver"] +trait Receiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +#[lang = "panic_location"] +struct PanicLocation { + file: &'static str, + line: u32, + column: u32, +} + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn puts(s: *const u8) -> i32; + pub fn fflush(stream: *mut i32) -> i32; + pub fn printf(format: *const i8, ...) -> i32; + + pub static stdout: *mut i32; + } +} + +mod intrinsics { + #[rustc_nounwind] + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + pub fn abort() -> ! { + loop {} + } +} + +#[lang = "panic"] +#[track_caller] +#[no_mangle] +pub fn panic(_msg: &'static str) -> ! { + unsafe { + libc::puts("Panicking\0" as *const str as *const u8); + libc::fflush(libc::stdout); + intrinsics::abort(); + } +} + +#[lang = "add"] +trait Add<RHS = Self> { + type Output; + + fn add(self, rhs: RHS) -> Self::Output; +} + +impl Add for u8 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for i8 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for i32 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for usize { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for isize { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +#[track_caller] +#[lang = "panic_const_add_overflow"] +pub fn panic_const_add_overflow() -> ! { + panic("attempt to add with overflow"); +} + +/* + * Code + */ + +fn inc_ref(num: &mut isize) -> isize { + *num = *num + 5; + *num + 1 +} + +fn inc(num: isize) -> isize { + num + 1 +} + + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + argc = inc(argc); + unsafe { + libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc); + } + + let b = inc_ref(&mut argc); + unsafe { + libc::printf(b"%ld %ld\n\0" as *const u8 as *const i8, argc, b); + } + + argc = 10; + unsafe { + libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/closure.rs b/compiler/rustc_codegen_gcc/tests/run/closure.rs new file mode 100644 index 00000000000..46c47bc54ed --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/closure.rs @@ -0,0 +1,64 @@ +// Compiler: +// +// Run-time: +// status: 0 +// stdout: Arg: 1 +// Argument: 1 +// String arg: 1 +// Int argument: 2 +// Both args: 11 + +#![feature(no_core, start)] + +#![no_std] +#![no_core] + +extern crate mini_core; + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn printf(format: *const i8, ...) -> i32; + } +} + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + let string = "Arg: %d\n\0"; + let mut closure = || { + unsafe { + libc::printf(string as *const str as *const i8, argc); + } + }; + closure(); + + let mut closure = || { + unsafe { + libc::printf("Argument: %d\n\0" as *const str as *const i8, argc); + } + }; + closure(); + + let mut closure = |string| { + unsafe { + libc::printf(string as *const str as *const i8, argc); + } + }; + closure("String arg: %d\n\0"); + + let mut closure = |arg: isize| { + unsafe { + libc::printf("Int argument: %d\n\0" as *const str as *const i8, arg); + } + }; + closure(argc + 1); + + let mut closure = |string, arg: isize| { + unsafe { + libc::printf(string as *const str as *const i8, arg); + } + }; + closure("Both args: %d\n\0", argc + 10); + + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/condition.rs b/compiler/rustc_codegen_gcc/tests/run/condition.rs new file mode 100644 index 00000000000..039ef94eaa7 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/condition.rs @@ -0,0 +1,41 @@ +// Compiler: +// +// Run-time: +// status: 0 +// stdout: true +// 1 + +#![feature(no_core, start)] + +#![no_std] +#![no_core] + +extern crate mini_core; + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn printf(format: *const i8, ...) -> i32; + } +} + +#[start] +fn main(argc: isize, _argv: *const *const u8) -> isize { + unsafe { + if argc == 1 { + libc::printf(b"true\n\0" as *const u8 as *const i8); + } + + let string = + match argc { + 1 => b"1\n\0", + 2 => b"2\n\0", + 3 => b"3\n\0", + 4 => b"4\n\0", + 5 => b"5\n\0", + _ => b"_\n\0", + }; + libc::printf(string as *const u8 as *const i8); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/empty_main.rs b/compiler/rustc_codegen_gcc/tests/run/empty_main.rs new file mode 100644 index 00000000000..e66a859ad69 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/empty_main.rs @@ -0,0 +1,40 @@ +// Compiler: +// +// Run-time: +// status: 0 + +#![feature(auto_traits, lang_items, no_core, start)] +#![allow(internal_features)] + +#![no_std] +#![no_core] + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "copy"] +trait Copy { +} + +impl Copy for isize {} + +#[lang = "receiver"] +trait Receiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +/* + * Code + */ + +#[start] +fn main(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/exit.rs b/compiler/rustc_codegen_gcc/tests/run/exit.rs new file mode 100644 index 00000000000..bf1cbeef302 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/exit.rs @@ -0,0 +1,50 @@ +// Compiler: +// +// Run-time: +// status: 2 + +#![feature(auto_traits, lang_items, no_core, start, intrinsics)] +#![allow(internal_features)] + +#![no_std] +#![no_core] + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn exit(status: i32); + } +} + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "copy"] +trait Copy { +} + +impl Copy for isize {} + +#[lang = "receiver"] +trait Receiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +/* + * Code + */ + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + unsafe { + libc::exit(2); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/exit_code.rs b/compiler/rustc_codegen_gcc/tests/run/exit_code.rs new file mode 100644 index 00000000000..be7a233efda --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/exit_code.rs @@ -0,0 +1,40 @@ +// Compiler: +// +// Run-time: +// status: 1 + +#![feature(auto_traits, lang_items, no_core, start)] +#![allow(internal_features)] + +#![no_std] +#![no_core] + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "copy"] +trait Copy { +} + +impl Copy for isize {} + +#[lang = "receiver"] +trait Receiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +/* + * Code + */ + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + 1 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs new file mode 100644 index 00000000000..ed1bf72bb27 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs @@ -0,0 +1,36 @@ +// Compiler: +// +// Run-time: +// status: 0 +// stdout: 1 + +#![feature(no_core, start)] + +#![no_std] +#![no_core] + +extern crate mini_core; + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn printf(format: *const i8, ...) -> i32; + } +} + +fn i16_as_i8(a: i16) -> i8 { + a as i8 +} + +fn call_func(func: fn(i16) -> i8, param: i16) -> i8 { + func(param) +} + +#[start] +fn main(argc: isize, _argv: *const *const u8) -> isize { + 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); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/gep.rs b/compiler/rustc_codegen_gcc/tests/run/gep.rs new file mode 100644 index 00000000000..c3d1672cff5 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/gep.rs @@ -0,0 +1,10 @@ +// Compiler: +// +// Run-time: +// status: 0 + +fn main() { + let mut value = (1, 1); + let ptr = &mut value as *mut (i32, i32); + println!("{:?}", ptr.wrapping_offset(10)); +} diff --git a/compiler/rustc_codegen_gcc/tests/run/int.rs b/compiler/rustc_codegen_gcc/tests/run/int.rs new file mode 100644 index 00000000000..bfe73c38435 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/int.rs @@ -0,0 +1,330 @@ +// Compiler: +// +// Run-time: +// status: 0 + +#![feature(const_black_box)] + +/* + * Code + */ + +fn main() { + use std::hint::black_box; + + macro_rules! check { + ($ty:ty, $expr:expr) => { + { + const EXPECTED: $ty = $expr; + assert_eq!($expr, EXPECTED); + } + }; + } + + check!(u32, (2220326408_u32 + black_box(1)) >> (32 - 6)); + + /// Generate `check!` tests for integer types at least as wide as 128 bits. + macro_rules! check_ops128 { + () => { + check_ops64!(); + + // Shifts. + check!(T, VAL1 << black_box(64)); + check!(T, VAL1 << black_box(81)); + check!(T, VAL3 << black_box(63)); + check!(T, VAL3 << black_box(64)); + + check!(T, VAL1 >> black_box(64)); + check!(T, VAL2 >> black_box(64)); + check!(T, VAL3 >> black_box(64)); + check!(T, VAL3 >> black_box(81)); + }; + } + + /// Generate `check!` tests for integer types at least as wide as 64 bits. + macro_rules! check_ops64 { + () => { + check_ops32!(); + + // Shifts. + check!(T, VAL2 << black_box(33)); + check!(T, VAL2 << black_box(49)); + check!(T, VAL2 << black_box(61)); + check!(T, VAL2 << black_box(63)); + + check!(T, VAL3 << black_box(33)); + check!(T, VAL3 << black_box(49)); + check!(T, VAL3 << black_box(61)); + + check!(T, VAL1 >> black_box(33)); + check!(T, VAL1 >> black_box(49)); + check!(T, VAL1 >> black_box(61)); + check!(T, VAL1 >> black_box(63)); + + check!(T, VAL2 >> black_box(33)); + check!(T, VAL2 >> black_box(49)); + check!(T, VAL2 >> black_box(61)); + check!(T, VAL2 >> black_box(63)); + + check!(T, VAL3 >> black_box(33)); + check!(T, VAL3 >> black_box(49)); + check!(T, VAL3 >> black_box(61)); + check!(T, VAL3 >> black_box(63)); + }; + } + + /// Generate `check!` tests for integer types at least as wide as 32 bits. + macro_rules! check_ops32 { + () => { + // Shifts. + check!(T, VAL2 << black_box(1)); + check!(T, VAL2 << black_box(0)); + + check!(T, VAL3 << black_box(1)); + check!(T, VAL3 << black_box(0)); + + check!(T, VAL1.wrapping_shl(black_box(0))); + check!(T, VAL1.wrapping_shl(black_box(1))); + check!(T, VAL1.wrapping_shl(black_box(33))); + check!(T, VAL1.wrapping_shl(black_box(49))); + check!(T, VAL1.wrapping_shl(black_box(61))); + check!(T, VAL1.wrapping_shl(black_box(63))); + check!(T, VAL1.wrapping_shl(black_box(64))); + check!(T, VAL1.wrapping_shl(black_box(81))); + + check!(Option<T>, VAL1.checked_shl(black_box(0))); + check!(Option<T>, VAL1.checked_shl(black_box(1))); + check!(Option<T>, VAL1.checked_shl(black_box(33))); + check!(Option<T>, VAL1.checked_shl(black_box(49))); + check!(Option<T>, VAL1.checked_shl(black_box(61))); + check!(Option<T>, VAL1.checked_shl(black_box(63))); + check!(Option<T>, VAL1.checked_shl(black_box(64))); + check!(Option<T>, VAL1.checked_shl(black_box(81))); + + check!(T, VAL1 >> black_box(0)); + check!(T, VAL1 >> black_box(1)); + + check!(T, VAL2 >> black_box(1)); + check!(T, VAL2 >> black_box(0)); + + check!(T, VAL3 >> black_box(0)); + check!(T, VAL3 >> black_box(1)); + + check!(T, VAL1.wrapping_shr(black_box(0))); + check!(T, VAL1.wrapping_shr(black_box(1))); + check!(T, VAL1.wrapping_shr(black_box(33))); + check!(T, VAL1.wrapping_shr(black_box(49))); + check!(T, VAL1.wrapping_shr(black_box(61))); + check!(T, VAL1.wrapping_shr(black_box(63))); + check!(T, VAL1.wrapping_shr(black_box(64))); + check!(T, VAL1.wrapping_shr(black_box(81))); + + check!(Option<T>, VAL1.checked_shr(black_box(0))); + check!(Option<T>, VAL1.checked_shr(black_box(1))); + check!(Option<T>, VAL1.checked_shr(black_box(33))); + check!(Option<T>, VAL1.checked_shr(black_box(49))); + check!(Option<T>, VAL1.checked_shr(black_box(61))); + check!(Option<T>, VAL1.checked_shr(black_box(63))); + check!(Option<T>, VAL1.checked_shr(black_box(64))); + check!(Option<T>, VAL1.checked_shr(black_box(81))); + + // Casts + check!(u64, (VAL1 >> black_box(1)) as u64); + + // Addition. + check!(T, VAL1 + black_box(1)); + check!(T, VAL2 + black_box(1)); + check!(T, VAL2 + (VAL2 + black_box(1))); + check!(T, VAL3 + black_box(1)); + + check!(Option<T>, VAL1.checked_add(black_box(1))); + check!(Option<T>, VAL2.checked_add(black_box(1))); + check!(Option<T>, VAL2.checked_add(VAL2 + black_box(1))); + check!(Option<T>, VAL3.checked_add(T::MAX)); + check!(Option<T>, VAL3.checked_add(T::MIN)); + + check!(T, VAL1.wrapping_add(black_box(1))); + check!(T, VAL2.wrapping_add(black_box(1))); + check!(T, VAL2.wrapping_add(VAL2 + black_box(1))); + check!(T, VAL3.wrapping_add(T::MAX)); + check!(T, VAL3.wrapping_add(T::MIN)); + + check!((T, bool), VAL1.overflowing_add(black_box(1))); + check!((T, bool), VAL2.overflowing_add(black_box(1))); + check!((T, bool), VAL2.overflowing_add(VAL2 + black_box(1))); + check!((T, bool), VAL3.overflowing_add(T::MAX)); + check!((T, bool), VAL3.overflowing_add(T::MIN)); + + check!(T, VAL1.saturating_add(black_box(1))); + check!(T, VAL2.saturating_add(black_box(1))); + check!(T, VAL2.saturating_add(VAL2 + black_box(1))); + check!(T, VAL3.saturating_add(T::MAX)); + check!(T, VAL3.saturating_add(T::MIN)); + + // Subtraction + check!(T, VAL1 - black_box(1)); + check!(T, VAL2 - black_box(1)); + check!(T, VAL3 - black_box(1)); + + check!(Option<T>, VAL1.checked_sub(black_box(1))); + check!(Option<T>, VAL2.checked_sub(black_box(1))); + check!(Option<T>, VAL2.checked_sub(VAL2 + black_box(1))); + check!(Option<T>, VAL3.checked_sub(T::MAX)); + check!(Option<T>, VAL3.checked_sub(T::MIN)); + + check!(T, VAL1.wrapping_sub(black_box(1))); + check!(T, VAL2.wrapping_sub(black_box(1))); + check!(T, VAL2.wrapping_sub(VAL2 + black_box(1))); + check!(T, VAL3.wrapping_sub(T::MAX)); + check!(T, VAL3.wrapping_sub(T::MIN)); + + check!((T, bool), VAL1.overflowing_sub(black_box(1))); + check!((T, bool), VAL2.overflowing_sub(black_box(1))); + check!((T, bool), VAL2.overflowing_sub(VAL2 + black_box(1))); + check!((T, bool), VAL3.overflowing_sub(T::MAX)); + check!((T, bool), VAL3.overflowing_sub(T::MIN)); + + check!(T, VAL1.saturating_sub(black_box(1))); + check!(T, VAL2.saturating_sub(black_box(1))); + check!(T, VAL2.saturating_sub(VAL2 + black_box(1))); + check!(T, VAL3.saturating_sub(T::MAX)); + check!(T, VAL3.saturating_sub(T::MIN)); + + // Multiplication + check!(T, VAL1 * black_box(2)); + check!(T, VAL1 * (black_box(1) + VAL2)); + check!(T, VAL2 * black_box(2)); + check!(T, VAL2 * (black_box(1) + VAL2)); + check!(T, VAL3 * black_box(1)); + check!(T, VAL4 * black_box(2)); + check!(T, VAL5 * black_box(2)); + + check!(Option<T>, VAL1.checked_mul(black_box(2))); + check!(Option<T>, VAL1.checked_mul(black_box(1) + VAL2)); + check!(Option<T>, VAL3.checked_mul(VAL3)); + check!(Option<T>, VAL4.checked_mul(black_box(2))); + check!(Option<T>, VAL5.checked_mul(black_box(2))); + + check!(T, VAL1.wrapping_mul(black_box(2))); + check!(T, VAL1.wrapping_mul((black_box(1) + VAL2))); + check!(T, VAL3.wrapping_mul(VAL3)); + check!(T, VAL4.wrapping_mul(black_box(2))); + check!(T, VAL5.wrapping_mul(black_box(2))); + + check!((T, bool), VAL1.overflowing_mul(black_box(2))); + check!((T, bool), VAL1.overflowing_mul(black_box(1) + VAL2)); + check!((T, bool), VAL3.overflowing_mul(VAL3)); + check!((T, bool), VAL4.overflowing_mul(black_box(2))); + check!((T, bool), VAL5.overflowing_mul(black_box(2))); + + check!(T, VAL1.saturating_mul(black_box(2))); + check!(T, VAL1.saturating_mul(black_box(1) + VAL2)); + check!(T, VAL3.saturating_mul(VAL3)); + check!(T, VAL4.saturating_mul(black_box(2))); + check!(T, VAL5.saturating_mul(black_box(2))); + + // Division. + check!(T, VAL1 / black_box(2)); + check!(T, VAL1 / black_box(3)); + + check!(T, VAL2 / black_box(2)); + check!(T, VAL2 / black_box(3)); + + check!(T, VAL3 / black_box(2)); + check!(T, VAL3 / black_box(3)); + check!(T, VAL3 / (black_box(1) + VAL4)); + check!(T, VAL3 / (black_box(1) + VAL2)); + + check!(T, VAL4 / black_box(2)); + check!(T, VAL4 / black_box(3)); + + check!(Option<T>, VAL1.checked_div(black_box(2))); + check!(Option<T>, VAL1.checked_div(black_box(1) + VAL2)); + check!(Option<T>, VAL3.checked_div(VAL3)); + check!(Option<T>, VAL4.checked_div(black_box(2))); + check!(Option<T>, VAL5.checked_div(black_box(2))); + check!(Option<T>, (T::MIN).checked_div(black_box(0 as T).wrapping_sub(1))); + check!(Option<T>, VAL5.checked_div(black_box(0))); // var5 / 0 + + check!(T, VAL1.wrapping_div(black_box(2))); + check!(T, VAL1.wrapping_div(black_box(1) + VAL2)); + check!(T, VAL3.wrapping_div(VAL3)); + check!(T, VAL4.wrapping_div(black_box(2))); + check!(T, VAL5.wrapping_div(black_box(2))); + check!(T, (T::MIN).wrapping_div(black_box(0 as T).wrapping_sub(1))); + + check!((T, bool), VAL1.overflowing_div(black_box(2))); + check!((T, bool), VAL1.overflowing_div(black_box(1) + VAL2)); + check!((T, bool), VAL3.overflowing_div(VAL3)); + check!((T, bool), VAL4.overflowing_div(black_box(2))); + check!((T, bool), VAL5.overflowing_div(black_box(2))); + check!((T, bool), (T::MIN).overflowing_div(black_box(0 as T).wrapping_sub(1))); + + check!(T, VAL1.saturating_div(black_box(2))); + check!(T, VAL1.saturating_div((black_box(1) + VAL2))); + check!(T, VAL3.saturating_div(VAL3)); + check!(T, VAL4.saturating_div(black_box(2))); + check!(T, VAL5.saturating_div(black_box(2))); + check!(T, (T::MIN).saturating_div((0 as T).wrapping_sub(black_box(1)))); + }; + } + + { + type T = u32; + const VAL1: T = 14162_u32; + const VAL2: T = 14556_u32; + const VAL3: T = 323656954_u32; + const VAL4: T = 2023651954_u32; + const VAL5: T = 1323651954_u32; + check_ops32!(); + } + + { + type T = i32; + const VAL1: T = 13456_i32; + const VAL2: T = 10475_i32; + const VAL3: T = 923653954_i32; + const VAL4: T = 993198738_i32; + const VAL5: T = 1023653954_i32; + check_ops32!(); + } + + { + type T = u64; + const VAL1: T = 134217856_u64; + const VAL2: T = 104753732_u64; + const VAL3: T = 12323651988970863954_u64; + const VAL4: T = 7323651988970863954_u64; + const VAL5: T = 8323651988970863954_u64; + check_ops64!(); + } + + { + type T = i64; + const VAL1: T = 134217856_i64; + const VAL2: T = 104753732_i64; + const VAL3: T = 6323651988970863954_i64; + const VAL4: T = 2323651988970863954_i64; + const VAL5: T = 3323651988970863954_i64; + check_ops64!(); + } + + { + type T = u128; + const VAL1: T = 134217856_u128; + const VAL2: T = 10475372733397991552_u128; + const VAL3: T = 193236519889708027473620326106273939584_u128; + const VAL4: T = 123236519889708027473620326106273939584_u128; + const VAL5: T = 153236519889708027473620326106273939584_u128; + check_ops128!(); + } + { + type T = i128; + const VAL1: T = 134217856_i128; + const VAL2: T = 10475372733397991552_i128; + const VAL3: T = 83236519889708027473620326106273939584_i128; + const VAL4: T = 63236519889708027473620326106273939584_i128; + const VAL5: T = 73236519889708027473620326106273939584_i128; + check_ops128!(); + } +} diff --git a/compiler/rustc_codegen_gcc/tests/run/int_overflow.rs b/compiler/rustc_codegen_gcc/tests/run/int_overflow.rs new file mode 100644 index 00000000000..78872159f62 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/int_overflow.rs @@ -0,0 +1,23 @@ +// Compiler: +// +// Run-time: +// stdout: Success +// status: signal + +fn main() { + std::panic::set_hook(Box::new(|_| { + println!("Success"); + std::process::abort(); + })); + + let arg_count = std::env::args().count(); + let int = isize::MAX; + let _int = int + arg_count as isize; // overflow + + // If overflow checking is disabled, we should reach here. + #[cfg(not(debug_assertions))] + unsafe { + println!("Success"); + std::process::abort(); + } +} diff --git a/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs new file mode 100644 index 00000000000..3ae79338216 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs @@ -0,0 +1,174 @@ + +// Compiler: +// +// Run-time: +// stdout: 2 +// 7 +// 6 +// 11 + +#![allow(internal_features, unused_attributes)] +#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)] + +#![no_std] +#![no_core] + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "copy"] +trait Copy { +} + +impl Copy for isize {} +impl Copy for *mut i32 {} +impl Copy for usize {} +impl Copy for u8 {} +impl Copy for i8 {} +impl Copy for i32 {} + +#[lang = "receiver"] +trait Receiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +#[lang = "panic_location"] +struct PanicLocation { + file: &'static str, + line: u32, + column: u32, +} + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn puts(s: *const u8) -> i32; + pub fn fflush(stream: *mut i32) -> i32; + pub fn printf(format: *const i8, ...) -> i32; + + pub static stdout: *mut i32; + } +} + +mod intrinsics { + #[rustc_nounwind] + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + pub fn abort() -> ! { + loop {} + } +} + +#[lang = "panic"] +#[track_caller] +#[no_mangle] +pub fn panic(_msg: &'static str) -> ! { + unsafe { + libc::puts("Panicking\0" as *const str as *const u8); + libc::fflush(libc::stdout); + intrinsics::abort(); + } +} + +#[lang = "add"] +trait Add<RHS = Self> { + type Output; + + fn add(self, rhs: RHS) -> Self::Output; +} + +impl Add for u8 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for i8 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for i32 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for usize { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for isize { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +#[track_caller] +#[lang = "panic_const_add_overflow"] +pub fn panic_const_add_overflow() -> ! { + panic("attempt to add with overflow"); +} + +/* + * Code + */ + +struct Test { + field: isize, +} + +fn test(num: isize) -> Test { + Test { + field: num + 1, + } +} + +fn update_num(num: &mut isize) { + *num = *num + 5; +} + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + let mut test = test(argc); + unsafe { + libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field); + } + update_num(&mut test.field); + unsafe { + libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field); + } + + update_num(&mut argc); + unsafe { + libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc); + } + + let refe = &mut argc; + *refe = *refe + 5; + unsafe { + libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc); + } + + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/operations.rs b/compiler/rustc_codegen_gcc/tests/run/operations.rs new file mode 100644 index 00000000000..0e44fc580b8 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/operations.rs @@ -0,0 +1,242 @@ +// Compiler: +// +// Run-time: +// stdout: 41 +// 39 +// 10 + +#![allow(internal_features, unused_attributes)] +#![feature(auto_traits, lang_items, no_core, start, intrinsics, arbitrary_self_types, rustc_attrs)] + +#![no_std] +#![no_core] + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "copy"] +trait Copy { +} + +impl Copy for isize {} +impl Copy for *mut i32 {} +impl Copy for usize {} +impl Copy for u8 {} +impl Copy for i8 {} +impl Copy for i16 {} +impl Copy for i32 {} + +#[lang = "deref"] +pub trait Deref { + type Target: ?Sized; + + fn deref(&self) -> &Self::Target; +} + +#[lang = "legacy_receiver"] +trait LegacyReceiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +#[lang = "panic_location"] +struct PanicLocation { + file: &'static str, + line: u32, + column: u32, +} + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn printf(format: *const i8, ...) -> i32; + pub fn puts(s: *const u8) -> i32; + pub fn fflush(stream: *mut i32) -> i32; + + pub static stdout: *mut i32; + } +} + +mod intrinsics { + #[rustc_nounwind] + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + pub fn abort() -> ! { + loop {} + } +} + +#[lang = "panic"] +#[track_caller] +#[no_mangle] +pub fn panic(_msg: &'static str) -> ! { + unsafe { + libc::puts("Panicking\0" as *const str as *const u8); + libc::fflush(libc::stdout); + intrinsics::abort(); + } +} + +#[lang = "add"] +trait Add<RHS = Self> { + type Output; + + fn add(self, rhs: RHS) -> Self::Output; +} + +impl Add for u8 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for i8 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for i32 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for usize { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Add for isize { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +#[lang = "sub"] +pub trait Sub<RHS = Self> { + type Output; + + fn sub(self, rhs: RHS) -> Self::Output; +} + +impl Sub for usize { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + +impl Sub for isize { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + +impl Sub for u8 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + +impl Sub for i8 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + +impl Sub for i16 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + self - rhs + } +} + +#[lang = "mul"] +pub trait Mul<RHS = Self> { + type Output; + + #[must_use] + fn mul(self, rhs: RHS) -> Self::Output; +} + +impl Mul for u8 { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + self * rhs + } +} + +impl Mul for usize { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + self * rhs + } +} + +impl Mul for isize { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + self * rhs + } +} + +#[track_caller] +#[lang = "panic_const_add_overflow"] +pub fn panic_const_add_overflow() -> ! { + panic("attempt to add with overflow"); +} + +#[track_caller] +#[lang = "panic_const_sub_overflow"] +pub fn panic_const_sub_overflow() -> ! { + panic("attempt to subtract with overflow"); +} + +#[track_caller] +#[lang = "panic_const_mul_overflow"] +pub fn panic_const_mul_overflow() -> ! { + panic("attempt to multiply with overflow"); +} + +/* + * Code + */ + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + 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); + libc::printf(b"%ld\n\0" as *const u8 as *const i8, 10 * argc); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs new file mode 100644 index 00000000000..2b8812ad51c --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs @@ -0,0 +1,35 @@ +// Compiler: +// +// Run-time: +// status: 0 +// stdout: 1 + +#![feature(no_core, start)] + +#![no_std] +#![no_core] + +extern crate mini_core; + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn printf(format: *const i8, ...) -> i32; + } +} + +static mut ONE: usize = 1; + +fn make_array() -> [u8; 3] { + [42, 10, 5] +} + +#[start] +fn main(argc: isize, _argv: *const *const u8) -> isize { + unsafe { + let ptr = ONE as *mut usize; + let value = ptr as usize; + libc::printf(b"%ld\n\0" as *const u8 as *const i8, value); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs new file mode 100644 index 00000000000..f2a5a2e4384 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs @@ -0,0 +1,73 @@ +// Compiler: +// +// Run-time: +// status: 0 +// stdout: 10 +// 10 +// 42 + +#![feature(auto_traits, lang_items, no_core, start, intrinsics)] +#![allow(internal_features)] + +#![no_std] +#![no_core] + +#[lang = "copy"] +pub unsafe trait Copy {} + +impl Copy for bool {} +impl Copy for u8 {} +impl Copy for u16 {} +impl Copy for u32 {} +impl Copy for u64 {} +impl Copy for usize {} +impl Copy for i8 {} +impl Copy for i16 {} +impl Copy for i32 {} +impl Copy for isize {} +impl Copy for f32 {} +impl Copy for char {} + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn printf(format: *const i8, ...) -> i32; + } +} + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "legacy_receiver"] +trait LegacyReceiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +/* + * Code + */ + +fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) { + ( + a as u8, a as u16, a as u32, a as usize, a as i8, a as i16, a as i32, a as isize, b as u8, + b as u32, + ) +} + +#[start] +fn main(argc: isize, _argv: *const *const u8) -> isize { + 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); + libc::printf(b"%ld\n\0" as *const u8 as *const i8, d); + libc::printf(b"%ld\n\0" as *const u8 as *const i8, j); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/slice.rs b/compiler/rustc_codegen_gcc/tests/run/slice.rs new file mode 100644 index 00000000000..fba93fc1554 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/slice.rs @@ -0,0 +1,36 @@ +// Compiler: +// +// Run-time: +// status: 0 +// stdout: 5 + +#![feature(no_core, start)] + +#![no_std] +#![no_core] + +extern crate mini_core; + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn printf(format: *const i8, ...) -> i32; + } +} + +static mut TWO: usize = 2; + +fn index_slice(s: &[u32]) -> u32 { + unsafe { + s[TWO] + } +} + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + let array = [42, 7, 5]; + unsafe { + libc::printf(b"%ld\n\0" as *const u8 as *const i8, index_slice(&array)); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/static.rs b/compiler/rustc_codegen_gcc/tests/run/static.rs new file mode 100644 index 00000000000..a17ea2a4893 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/static.rs @@ -0,0 +1,114 @@ +// Compiler: +// +// Run-time: +// status: 0 +// stdout: 10 +// 14 +// 1 +// 12 +// 12 +// 1 + +#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] +#![allow(internal_features)] + +#![no_std] +#![no_core] + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "destruct"] +pub trait Destruct {} + +#[lang = "drop"] +pub trait Drop {} + +#[lang = "copy"] +trait Copy { +} + +impl Copy for isize {} +impl<T: ?Sized> Copy for *mut T {} + +#[lang = "receiver"] +trait Receiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +mod intrinsics { + use super::Sized; + + #[rustc_nounwind] + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + pub fn abort() -> ! { + loop {} + } +} + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn printf(format: *const i8, ...) -> i32; + } +} + +#[lang = "structural_peq"] +pub trait StructuralPartialEq {} + +#[lang = "drop_in_place"] +#[allow(unconditional_recursion)] +pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { + // Code here does not matter - this is replaced by the + // real drop glue by the compiler. + drop_in_place(to_drop); +} + +/* + * Code + */ + +struct Test { + field: isize, +} + +struct WithRef { + refe: &'static Test, +} + +static mut CONSTANT: isize = 10; + +static mut TEST: Test = Test { + field: 12, +}; + +static mut TEST2: Test = Test { + field: 14, +}; + +static mut WITH_REF: WithRef = WithRef { + refe: unsafe { &TEST }, +}; + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + 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); + TEST2.field = argc; + libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST2.field); + libc::printf(b"%ld\n\0" as *const u8 as *const i8, WITH_REF.refe.field); + WITH_REF.refe = &TEST2; + libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST.field); + libc::printf(b"%ld\n\0" as *const u8 as *const i8, WITH_REF.refe.field); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/structs.rs b/compiler/rustc_codegen_gcc/tests/run/structs.rs new file mode 100644 index 00000000000..d6455667400 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/structs.rs @@ -0,0 +1,71 @@ +// Compiler: +// +// Run-time: +// status: 0 +// stdout: 1 +// 2 + +#![feature(auto_traits, lang_items, no_core, start, intrinsics)] +#![allow(internal_features)] + +#![no_std] +#![no_core] + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "copy"] +trait Copy { +} + +impl Copy for isize {} + +#[lang = "receiver"] +trait Receiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn printf(format: *const i8, ...) -> i32; + } +} + +/* + * Code + */ + +struct Test { + field: isize, +} + +struct Two { + two: isize, +} + +fn one() -> isize { + 1 +} + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + let test = Test { + field: one(), + }; + let two = Two { + two: 2, + }; + unsafe { + libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field); + libc::printf(b"%ld\n\0" as *const u8 as *const i8, two.two); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/tuple.rs b/compiler/rustc_codegen_gcc/tests/run/tuple.rs new file mode 100644 index 00000000000..8a7d85ae867 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/tuple.rs @@ -0,0 +1,52 @@ +// Compiler: +// +// Run-time: +// status: 0 +// stdout: 3 + +#![feature(auto_traits, lang_items, no_core, start, intrinsics)] +#![allow(internal_features)] + +#![no_std] +#![no_core] + +/* + * Core + */ + +// Because we don't have core yet. +#[lang = "sized"] +pub trait Sized {} + +#[lang = "copy"] +trait Copy { +} + +impl Copy for isize {} + +#[lang = "receiver"] +trait Receiver { +} + +#[lang = "freeze"] +pub(crate) unsafe auto trait Freeze {} + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn printf(format: *const i8, ...) -> i32; + } +} + +/* + * Code + */ + +#[start] +fn main(mut argc: isize, _argv: *const *const u8) -> isize { + let test: (isize, isize, isize) = (3, 1, 4); + unsafe { + libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.0); + } + 0 +} diff --git a/compiler/rustc_codegen_gcc/tests/run/volatile.rs b/compiler/rustc_codegen_gcc/tests/run/volatile.rs new file mode 100644 index 00000000000..8b043312593 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/volatile.rs @@ -0,0 +1,26 @@ +// Compiler: +// +// Run-time: +// status: 0 + +use std::mem::MaybeUninit; + +#[derive(Debug)] +struct Struct { + pointer: *const (), + func: unsafe fn(*const ()), +} + +fn func(ptr: *const ()) { +} + +fn main() { + let mut x = MaybeUninit::<&Struct>::uninit(); + x.write(&Struct { + pointer: std::ptr::null(), + func, + }); + let x = unsafe { x.assume_init() }; + let value = unsafe { (x as *const Struct).read_volatile() }; + println!("{:?}", value); +} diff --git a/compiler/rustc_codegen_gcc/tests/run/volatile2.rs b/compiler/rustc_codegen_gcc/tests/run/volatile2.rs new file mode 100644 index 00000000000..a177b817ab3 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/volatile2.rs @@ -0,0 +1,113 @@ +// Compiler: +// +// Run-time: +// status: 0 + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn puts(s: *const u8) -> i32; + + pub fn sigaction(signum: i32, act: *const sigaction, oldact: *mut sigaction) -> i32; + pub fn mmap(addr: *mut (), len: usize, prot: i32, flags: i32, fd: i32, offset: i64) -> *mut (); + pub fn mprotect(addr: *mut (), len: usize, prot: i32) -> i32; + } + + pub const PROT_READ: i32 = 1; + pub const PROT_WRITE: i32 = 2; + pub const MAP_PRIVATE: i32 = 0x0002; + pub const MAP_ANONYMOUS: i32 = 0x0020; + pub const MAP_FAILED: *mut u8 = !0 as *mut u8; + + /// glibc sigaction + #[repr(C)] + pub struct sigaction { + pub sa_sigaction: Option<unsafe extern "C" fn(i32, *mut (), *mut ())>, + pub sa_mask: [u32; 32], + pub sa_flags: i32, + pub sa_restorer: Option<unsafe extern "C" fn()>, + } + + pub const SA_SIGINFO: i32 = 0x00000004; + pub const SIGSEGV: i32 = 11; +} + +static mut COUNT: u32 = 0; +static mut STORAGE: *mut u8 = core::ptr::null_mut(); +const PAGE_SIZE: usize = 1 << 15; + +fn main() { + unsafe { + // Register a segfault handler + libc::sigaction( + libc::SIGSEGV, + &libc::sigaction { + sa_sigaction: Some(segv_handler), + sa_flags: libc::SA_SIGINFO, + ..core::mem::zeroed() + }, + core::ptr::null_mut(), + ); + + STORAGE = libc::mmap( + core::ptr::null_mut(), + PAGE_SIZE * 2, + 0, + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + 0, + ).cast(); + if STORAGE == libc::MAP_FAILED { + panic!("error: mmap failed"); + } + + let p_count = (&mut COUNT) as *mut u32; + p_count.write_volatile(0); + + // Trigger segfaults + STORAGE.add(0).write_volatile(1); + STORAGE.add(PAGE_SIZE).write_volatile(1); + STORAGE.add(0).write_volatile(1); + STORAGE.add(PAGE_SIZE).write_volatile(1); + STORAGE.add(0).write_volatile(1); + STORAGE.add(PAGE_SIZE).write_volatile(1); + STORAGE.add(0).read_volatile(); + STORAGE.add(PAGE_SIZE).read_volatile(); + STORAGE.add(0).read_volatile(); + STORAGE.add(PAGE_SIZE).read_volatile(); + STORAGE.add(0).read_volatile(); + STORAGE.add(PAGE_SIZE).read_volatile(); + STORAGE.add(0).write_volatile(1); + STORAGE.add(PAGE_SIZE).write_volatile(1); + + // The segfault handler should have been called for every `write_volatile` and + // `read_volatile` in `STORAGE`. If the compiler ignores volatility, some of these writes + // will be combined, causing a different number of segfaults. + // + // This `p_count` read is done by a volatile read. If the compiler + // ignores volatility, the compiler will speculate that `*p_count` is + // unchanged and remove this check, failing the test. + if p_count.read_volatile() != 14 { + panic!("error: segfault count mismatch: {}", p_count.read_volatile()); + } + } +} + +unsafe extern "C" fn segv_handler(_: i32, _: *mut (), _: *mut ()) { + let p_count = (&mut COUNT) as *mut u32; + p_count.write_volatile(p_count.read_volatile() + 1); + let count = p_count.read_volatile(); + + // Toggle the protected page so that the handler will be called for + // each `write_volatile` + libc::mprotect( + STORAGE.cast(), + PAGE_SIZE, + if count % 2 == 1 { libc::PROT_READ | libc::PROT_WRITE } else { 0 }, + ); + libc::mprotect( + STORAGE.add(PAGE_SIZE).cast(), + PAGE_SIZE, + if count % 2 == 0 { libc::PROT_READ | libc::PROT_WRITE } else { 0 }, + ); +} |
