diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 5316e90847ac5..73be954cefd76 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -247,9 +247,9 @@ builtin_macros_multiple_defaults = multiple declared defaults .suggestion = make `{$ident}` default builtin_macros_naked_functions_testing_attribute = - cannot use `#[naked]` with testing attributes + cannot use `#[unsafe(naked)]` with testing attributes .label = function marked with testing attribute here - .naked_attribute = `#[naked]` is incompatible with testing attributes + .naked_attribute = `#[unsafe(naked)]` is incompatible with testing attributes builtin_macros_no_default_variant = `#[derive(Default)]` on enum with no `#[default]` .label = this enum needs a unit variant marked with `#[default]` diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs index 09d5b73fd3d9d..0b3a7281d5a06 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs @@ -387,11 +387,9 @@ global_asm! { } #[cfg(all(not(jit), target_arch = "x86_64"))] -#[naked] +#[unsafe(naked)] extern "C" fn naked_test() { - unsafe { - naked_asm!("ret"); - } + naked_asm!("ret") } #[repr(C)] diff --git a/compiler/rustc_error_codes/src/error_codes/E0736.md b/compiler/rustc_error_codes/src/error_codes/E0736.md index cb7633b7068a3..66d5fbb80cf29 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0736.md +++ b/compiler/rustc_error_codes/src/error_codes/E0736.md @@ -11,7 +11,7 @@ Erroneous code example: ```compile_fail,E0736 #[inline] -#[naked] +#[unsafe(naked)] fn foo() {} ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0787.md b/compiler/rustc_error_codes/src/error_codes/E0787.md index f5c5faa066b6b..47b56ac17f4f5 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0787.md +++ b/compiler/rustc_error_codes/src/error_codes/E0787.md @@ -5,7 +5,7 @@ Erroneous code example: ```compile_fail,E0787 #![feature(naked_functions)] -#[naked] +#[unsafe(naked)] pub extern "C" fn f() -> u32 { 42 } diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 3b441729d7552..713e460e507f4 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -517,7 +517,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Linking: gated!( - naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, + unsafe naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, naked_functions, experimental!(naked) ), diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 66517c97a687e..d92b4f9c06beb 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -55,8 +55,6 @@ bitflags::bitflags! { const IS_UNSAFE_CELL = 1 << 9; /// Indicates whether the type is `UnsafePinned`. const IS_UNSAFE_PINNED = 1 << 10; - /// Indicates whether the type is anonymous. - const IS_ANONYMOUS = 1 << 11; } } rustc_data_structures::external_bitflags_debug! { AdtFlags } diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index b6a856a6eb4d1..adfce99a9b537 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -564,13 +564,17 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } } ExprKind::InlineAsm(box InlineAsmExpr { - asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm, + asm_macro: asm_macro @ (AsmMacro::Asm | AsmMacro::NakedAsm), ref operands, template: _, options: _, line_spans: _, }) => { - self.requires_unsafe(expr.span, UseOfInlineAssembly); + // The `naked` attribute and the `naked_asm!` block form one atomic unit of + // unsafety, and `naked_asm!` does not itself need to be wrapped in an unsafe block. + if let AsmMacro::Asm = asm_macro { + self.requires_unsafe(expr.span, UseOfInlineAssembly); + } // For inline asm, do not use `walk_expr`, since we want to handle the label block // specially. diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index df44b3cc23c86..71cc814cb500a 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1884,13 +1884,15 @@ impl<'a> Parser<'a> { let mut expr = self.parse_expr_opt()?; if let Some(expr) = &mut expr { if label.is_some() - && matches!( - expr.kind, + && match &expr.kind { ExprKind::While(_, _, None) - | ExprKind::ForLoop { label: None, .. } - | ExprKind::Loop(_, None, _) - | ExprKind::Block(_, None) - ) + | ExprKind::ForLoop { label: None, .. } + | ExprKind::Loop(_, None, _) => true, + ExprKind::Block(block, None) => { + matches!(block.rules, BlockCheckMode::Default) + } + _ => false, + } { self.psess.buffer_lint( BREAK_WITH_LABEL_AND_LOOP, diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index b518fca7a6583..6a1c2af48ed50 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -194,12 +194,6 @@ pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr: } } } else if let Safety::Unsafe(unsafe_span) = attr_item.unsafety { - // Allow (but don't require) `#[unsafe(naked)]` so that compiler-builtins can upgrade to it. - // FIXME(#139797): remove this special case when compiler-builtins has upgraded. - if attr.has_name(sym::naked) { - return; - } - psess.dcx().emit_err(errors::InvalidAttrUnsafe { span: unsafe_span, name: attr_item.path.clone(), diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 99789b74488c9..413726ddd82d3 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -508,7 +508,7 @@ passes_must_use_no_effect = `#[must_use]` has no effect when applied to {$article} {$target} passes_naked_asm_outside_naked_fn = - the `naked_asm!` macro can only be used in functions marked with `#[naked]` + the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` passes_naked_functions_asm_block = naked functions must contain a single `naked_asm!` invocation @@ -516,9 +516,9 @@ passes_naked_functions_asm_block = .label_non_asm = not allowed in naked functions passes_naked_functions_incompatible_attribute = - attribute incompatible with `#[naked]` - .label = the `{$attr}` attribute is incompatible with `#[naked]` - .naked_attribute = function marked with `#[naked]` here + attribute incompatible with `#[unsafe(naked)]` + .label = the `{$attr}` attribute is incompatible with `#[unsafe(naked)]` + .naked_attribute = function marked with `#[unsafe(naked)]` here passes_naked_functions_must_naked_asm = the `asm!` macro is not allowed in naked functions diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs index 233a1c4fd7a54..91ab311109787 100644 --- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs @@ -7,6 +7,12 @@ pub(crate) fn target() -> Target { base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); base.supported_sanitizers = SanitizerSet::ADDRESS; + // On Windows 7 32-bit, the alignment characteristic of the TLS Directory + // don't appear to be respected by the PE Loader, leading to crashes. As + // a result, let's disable has_thread_local to make sure TLS goes through + // the emulation layer. + // See https://github.com/rust-lang/rust/issues/138903 + base.has_thread_local = false; base.add_pre_link_args( LinkerFlavor::Msvc(Lld::No), diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index f6743c6571095..ef8548d24293d 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -1116,7 +1116,7 @@ impl CStr { /// with the corresponding &[str] slice. Otherwise, it will /// replace any invalid UTF-8 sequences with /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a - /// [Cow]::[Owned]\(&[str]) with the result. + /// [Cow]::[Owned]\([String]) with the result. /// /// [str]: prim@str "str" /// [Borrowed]: Cow::Borrowed diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 0854e31c19979..2d869958b85cc 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1739,3 +1739,11 @@ impl PartialOrd for *const T { *self >= *other } } + +#[stable(feature = "raw_ptr_default", since = "CURRENT_RUSTC_VERSION")] +impl Default for *const T { + /// Returns the default value of [`null()`][crate::ptr::null]. + fn default() -> Self { + crate::ptr::null() + } +} diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index e29774963db00..df49eedb35096 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -2156,3 +2156,11 @@ impl PartialOrd for *mut T { *self >= *other } } + +#[stable(feature = "raw_ptr_default", since = "CURRENT_RUSTC_VERSION")] +impl Default for *mut T { + /// Returns the default value of [`null_mut()`][crate::ptr::null_mut]. + fn default() -> Self { + crate::ptr::null_mut() + } +} diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs index cc5f7946863a6..7d6e4eac1e21e 100644 --- a/library/coretests/tests/ptr.rs +++ b/library/coretests/tests/ptr.rs @@ -1020,3 +1020,20 @@ fn test_ptr_swap_nonoverlapping_is_untyped() { ptr_swap_nonoverlapping_is_untyped_inner(); const { ptr_swap_nonoverlapping_is_untyped_inner() }; } + +#[test] +fn test_ptr_default() { + #[derive(Default)] + struct PtrDefaultTest { + ptr: *const u64, + } + let default = PtrDefaultTest::default(); + assert!(default.ptr.is_null()); + + #[derive(Default)] + struct PtrMutDefaultTest { + ptr: *mut u64, + } + let default = PtrMutDefaultTest::default(); + assert!(default.ptr.is_null()); +} diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 687fc322e598d..bc8817bac7044 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -12,10 +12,11 @@ use libc::c_char; all(target_os = "linux", not(target_env = "musl")), target_os = "android", target_os = "fuchsia", - target_os = "hurd" + target_os = "hurd", + target_os = "illumos", ))] use libc::dirfd; -#[cfg(target_os = "fuchsia")] +#[cfg(any(target_os = "fuchsia", target_os = "illumos"))] use libc::fstatat as fstatat64; #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))] use libc::fstatat64; @@ -892,7 +893,8 @@ impl DirEntry { all(target_os = "linux", not(target_env = "musl")), target_os = "android", target_os = "fuchsia", - target_os = "hurd" + target_os = "hurd", + target_os = "illumos", ), not(miri) // no dirfd on Miri ))] @@ -922,6 +924,7 @@ impl DirEntry { target_os = "android", target_os = "fuchsia", target_os = "hurd", + target_os = "illumos", )), miri ))] diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index 2fe219f368b9c..43321d12cafcd 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock @@ -64,12 +64,63 @@ version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +[[package]] +name = "askama" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4744ed2eef2645831b441d8f5459689ade2ab27c854488fbab1fbe94fce1a7" +dependencies = [ + "askama_derive", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d661e0f57be36a5c14c48f78d09011e67e0cb618f269cca9f2fd8d15b68c46ac" +dependencies = [ + "askama_parser", + "basic-toml", + "memchr", + "proc-macro2", + "quote", + "rustc-hash", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "askama_parser" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf315ce6524c857bb129ff794935cf6d42c82a6cff60526fe2a63593de4d0d4f" +dependencies = [ + "memchr", + "serde", + "serde_derive", + "winnow", +] + [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + [[package]] name = "build_helper" version = "0.1.0" @@ -104,6 +155,7 @@ name = "citool" version = "0.1.0" dependencies = [ "anyhow", + "askama", "build_helper", "clap", "csv", @@ -646,6 +698,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "rustls" version = "0.23.23" @@ -1026,6 +1084,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" +dependencies = [ + "memchr", +] + [[package]] name = "write16" version = "1.0.0" diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index f18436a126359..0e2aba3b9e3fc 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] anyhow = "1" +askama = "0.13" clap = { version = "4.5", features = ["derive"] } csv = "1" diff = "0.1" diff --git a/src/ci/citool/src/analysis.rs b/src/ci/citool/src/analysis.rs index 9fc7c309bfbdc..62974be2dbe8c 100644 --- a/src/ci/citool/src/analysis.rs +++ b/src/ci/citool/src/analysis.rs @@ -8,9 +8,9 @@ use build_helper::metrics::{ }; use crate::github::JobInfoResolver; -use crate::metrics; use crate::metrics::{JobMetrics, JobName, get_test_suites}; use crate::utils::{output_details, pluralize}; +use crate::{metrics, utils}; /// Outputs durations of individual bootstrap steps from the gathered bootstrap invocations, /// and also a table with summarized information about executed tests. @@ -394,18 +394,17 @@ fn aggregate_tests(metrics: &JsonRoot) -> TestSuiteData { // Poor man's detection of doctests based on the "(line XYZ)" suffix let is_doctest = matches!(suite.metadata, TestSuiteMetadata::CargoPackage { .. }) && test.name.contains("(line"); - let test_entry = Test { name: generate_test_name(&test.name), stage, is_doctest }; + let test_entry = Test { + name: utils::normalize_path_delimiters(&test.name).to_string(), + stage, + is_doctest, + }; tests.insert(test_entry, test.outcome.clone()); } } TestSuiteData { tests } } -/// Normalizes Windows-style path delimiters to Unix-style paths. -fn generate_test_name(name: &str) -> String { - name.replace('\\', "/") -} - /// Prints test changes in Markdown format to stdout. fn report_test_diffs( diff: AggregatedTestDiffs, diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index a1956da352f5c..f4e671b609fa6 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -4,6 +4,7 @@ mod datadog; mod github; mod jobs; mod metrics; +mod test_dashboard; mod utils; use std::collections::{BTreeMap, HashMap}; @@ -22,7 +23,8 @@ use crate::datadog::upload_datadog_metric; use crate::github::JobInfoResolver; use crate::jobs::RunType; use crate::metrics::{JobMetrics, download_auto_job_metrics, download_job_metrics, load_metrics}; -use crate::utils::load_env_var; +use crate::test_dashboard::generate_test_dashboard; +use crate::utils::{load_env_var, output_details}; const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/.."); const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker"); @@ -180,12 +182,26 @@ fn postprocess_metrics( } fn post_merge_report(db: JobDatabase, current: String, parent: String) -> anyhow::Result<()> { - let metrics = download_auto_job_metrics(&db, &parent, ¤t)?; + let metrics = download_auto_job_metrics(&db, Some(&parent), ¤t)?; println!("\nComparing {parent} (parent) -> {current} (this PR)\n"); let mut job_info_resolver = JobInfoResolver::new(); output_test_diffs(&metrics, &mut job_info_resolver); + + output_details("Test dashboard", || { + println!( + r#"\nRun + +```bash +cargo run --manifest-path src/ci/citool/Cargo.toml -- \ + test-dashboard {current} --output-dir test-dashboard +``` +And then open `test-dashboard/index.html` in your browser to see an overview of all executed tests. +"# + ); + }); + output_largest_duration_changes(&metrics, &mut job_info_resolver); Ok(()) @@ -234,6 +250,14 @@ enum Args { /// Current commit that will be compared to `parent`. current: String, }, + /// Generate a directory containing a HTML dashboard of test results from a CI run. + TestDashboard { + /// Commit SHA that was tested on CI to analyze. + current: String, + /// Output path for the HTML directory. + #[clap(long)] + output_dir: PathBuf, + }, } #[derive(clap::ValueEnum, Clone)] @@ -275,7 +299,11 @@ fn main() -> anyhow::Result<()> { postprocess_metrics(metrics_path, parent, job_name)?; } Args::PostMergeReport { current, parent } => { - post_merge_report(load_db(default_jobs_file)?, current, parent)?; + post_merge_report(load_db(&default_jobs_file)?, current, parent)?; + } + Args::TestDashboard { current, output_dir } => { + let db = load_db(&default_jobs_file)?; + generate_test_dashboard(db, ¤t, &output_dir)?; } } diff --git a/src/ci/citool/src/metrics.rs b/src/ci/citool/src/metrics.rs index a816fb3c4f165..3d8b1ad84cf72 100644 --- a/src/ci/citool/src/metrics.rs +++ b/src/ci/citool/src/metrics.rs @@ -46,24 +46,25 @@ pub struct JobMetrics { /// `parent` and `current` should be commit SHAs. pub fn download_auto_job_metrics( job_db: &JobDatabase, - parent: &str, + parent: Option<&str>, current: &str, ) -> anyhow::Result> { let mut jobs = HashMap::default(); for job in &job_db.auto_jobs { eprintln!("Downloading metrics of job {}", job.name); - let metrics_parent = match download_job_metrics(&job.name, parent) { - Ok(metrics) => Some(metrics), - Err(error) => { - eprintln!( - r#"Did not find metrics for job `{}` at `{parent}`: {error:?}. + let metrics_parent = + parent.and_then(|parent| match download_job_metrics(&job.name, parent) { + Ok(metrics) => Some(metrics), + Err(error) => { + eprintln!( + r#"Did not find metrics for job `{}` at `{parent}`: {error:?}. Maybe it was newly added?"#, - job.name - ); - None - } - }; + job.name + ); + None + } + }); let metrics_current = download_job_metrics(&job.name, current)?; jobs.insert( job.name.clone(), diff --git a/src/ci/citool/src/test_dashboard.rs b/src/ci/citool/src/test_dashboard.rs new file mode 100644 index 0000000000000..8fbd0d3f200d4 --- /dev/null +++ b/src/ci/citool/src/test_dashboard.rs @@ -0,0 +1,216 @@ +use std::collections::{BTreeMap, HashMap}; +use std::fs::File; +use std::io::BufWriter; +use std::path::{Path, PathBuf}; + +use askama::Template; +use build_helper::metrics::{TestOutcome, TestSuiteMetadata}; + +use crate::jobs::JobDatabase; +use crate::metrics::{JobMetrics, JobName, download_auto_job_metrics, get_test_suites}; +use crate::utils::normalize_path_delimiters; + +/// Generate a set of HTML files into a directory that contain a dashboard of test results. +pub fn generate_test_dashboard( + db: JobDatabase, + current: &str, + output_dir: &Path, +) -> anyhow::Result<()> { + let metrics = download_auto_job_metrics(&db, None, current)?; + let suites = gather_test_suites(&metrics); + + std::fs::create_dir_all(output_dir)?; + + let test_count = suites.test_count(); + write_page(output_dir, "index.html", &TestSuitesPage { suites, test_count })?; + + Ok(()) +} + +fn write_page(dir: &Path, name: &str, template: &T) -> anyhow::Result<()> { + let mut file = BufWriter::new(File::create(dir.join(name))?); + Template::write_into(template, &mut file)?; + Ok(()) +} + +fn gather_test_suites(job_metrics: &HashMap) -> TestSuites { + struct CoarseTestSuite<'a> { + tests: BTreeMap>, + } + + let mut suites: HashMap = HashMap::new(); + + // First, gather tests from all jobs, stages and targets, and aggregate them per suite + // Only work with compiletest suites. + for (job, metrics) in job_metrics { + let test_suites = get_test_suites(&metrics.current); + for suite in test_suites { + let (suite_name, stage, target) = match &suite.metadata { + TestSuiteMetadata::CargoPackage { .. } => { + continue; + } + TestSuiteMetadata::Compiletest { suite, stage, target, .. } => { + (suite.clone(), *stage, target) + } + }; + let suite_entry = suites + .entry(suite_name.clone()) + .or_insert_with(|| CoarseTestSuite { tests: Default::default() }); + let test_metadata = TestMetadata { job, stage, target }; + + for test in &suite.tests { + let test_name = normalize_test_name(&test.name, &suite_name); + let (test_name, variant_name) = match test_name.rsplit_once('#') { + Some((name, variant)) => (name.to_string(), variant.to_string()), + None => (test_name, "".to_string()), + }; + let test_entry = suite_entry + .tests + .entry(test_name.clone()) + .or_insert_with(|| Test { revisions: Default::default() }); + let variant_entry = test_entry + .revisions + .entry(variant_name) + .or_insert_with(|| TestResults { passed: vec![], ignored: vec![] }); + + match test.outcome { + TestOutcome::Passed => { + variant_entry.passed.push(test_metadata); + } + TestOutcome::Ignored { ignore_reason: _ } => { + variant_entry.ignored.push(test_metadata); + } + TestOutcome::Failed => { + eprintln!("Warning: failed test {test_name}"); + } + } + } + } + } + + // Then, split the suites per directory + let mut suites = suites.into_iter().collect::>(); + suites.sort_by(|a, b| a.0.cmp(&b.0)); + + let suites = suites + .into_iter() + .map(|(suite_name, suite)| TestSuite { group: build_test_group(&suite_name, suite.tests) }) + .collect(); + + TestSuites { suites } +} + +/// Recursively expand a test group based on filesystem hierarchy. +fn build_test_group<'a>(name: &str, tests: BTreeMap>) -> TestGroup<'a> { + let mut root_tests = vec![]; + let mut subdirs: BTreeMap>> = Default::default(); + + // Split tests into root tests and tests located in subdirectories + for (name, test) in tests { + let mut components = Path::new(&name).components().peekable(); + let subdir = components.next().unwrap(); + + if components.peek().is_none() { + // This is a root test + root_tests.push((name, test)); + } else { + // This is a test in a nested directory + let subdir_tests = + subdirs.entry(subdir.as_os_str().to_str().unwrap().to_string()).or_default(); + let test_name = + components.into_iter().collect::().to_str().unwrap().to_string(); + subdir_tests.insert(test_name, test); + } + } + let dirs = subdirs + .into_iter() + .map(|(name, tests)| { + let group = build_test_group(&name, tests); + (name, group) + }) + .collect(); + + TestGroup { name: name.to_string(), root_tests, groups: dirs } +} + +/// Compiletest tests start with `[suite] tests/[suite]/a/b/c...`. +/// Remove the `[suite] tests/[suite]/` prefix so that we can find the filesystem path. +/// Also normalizes path delimiters. +fn normalize_test_name(name: &str, suite_name: &str) -> String { + let name = normalize_path_delimiters(name); + let name = name.as_ref(); + let name = name.strip_prefix(&format!("[{suite_name}]")).unwrap_or(name).trim(); + let name = name.strip_prefix("tests/").unwrap_or(name); + let name = name.strip_prefix(suite_name).unwrap_or(name); + name.trim_start_matches("/").to_string() +} + +struct TestSuites<'a> { + suites: Vec>, +} + +impl<'a> TestSuites<'a> { + fn test_count(&self) -> u64 { + self.suites.iter().map(|suite| suite.group.test_count()).sum::() + } +} + +struct TestSuite<'a> { + group: TestGroup<'a>, +} + +struct TestResults<'a> { + passed: Vec>, + ignored: Vec>, +} + +struct Test<'a> { + revisions: BTreeMap>, +} + +impl<'a> Test<'a> { + /// If this is a test without revisions, it will have a single entry in `revisions` with + /// an empty string as the revision name. + fn single_test(&self) -> Option<&TestResults<'a>> { + if self.revisions.len() == 1 { + self.revisions.iter().next().take_if(|e| e.0.is_empty()).map(|e| e.1) + } else { + None + } + } +} + +#[derive(Clone, Copy)] +#[allow(dead_code)] +struct TestMetadata<'a> { + job: &'a str, + stage: u32, + target: &'a str, +} + +// We have to use a template for the TestGroup instead of a macro, because +// macros cannot be recursive in askama at the moment. +#[derive(Template)] +#[template(path = "test_group.askama")] +/// Represents a group of tests +struct TestGroup<'a> { + name: String, + /// Tests located directly in this directory + root_tests: Vec<(String, Test<'a>)>, + /// Nested directories with additional tests + groups: Vec<(String, TestGroup<'a>)>, +} + +impl<'a> TestGroup<'a> { + fn test_count(&self) -> u64 { + let root = self.root_tests.len() as u64; + self.groups.iter().map(|(_, group)| group.test_count()).sum::() + root + } +} + +#[derive(Template)] +#[template(path = "test_suites.askama")] +struct TestSuitesPage<'a> { + suites: TestSuites<'a>, + test_count: u64, +} diff --git a/src/ci/citool/src/utils.rs b/src/ci/citool/src/utils.rs index a4c6ff85ef73c..0367d349a1ef4 100644 --- a/src/ci/citool/src/utils.rs +++ b/src/ci/citool/src/utils.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::path::Path; use anyhow::Context; @@ -28,3 +29,8 @@ where func(); println!("\n"); } + +/// Normalizes Windows-style path delimiters to Unix-style paths. +pub fn normalize_path_delimiters(name: &str) -> Cow { + if name.contains("\\") { name.replace('\\', "/").into() } else { name.into() } +} diff --git a/src/ci/citool/templates/layout.askama b/src/ci/citool/templates/layout.askama new file mode 100644 index 0000000000000..3b3b6f23741d4 --- /dev/null +++ b/src/ci/citool/templates/layout.askama @@ -0,0 +1,22 @@ + + + + Rust CI Test Dashboard + + + + +{% block content %}{% endblock %} +{% block scripts %}{% endblock %} + + diff --git a/src/ci/citool/templates/test_group.askama b/src/ci/citool/templates/test_group.askama new file mode 100644 index 0000000000000..95731103f3b9d --- /dev/null +++ b/src/ci/citool/templates/test_group.askama @@ -0,0 +1,42 @@ +{% macro test_result(r) -%} +passed: {{ r.passed.len() }}, ignored: {{ r.ignored.len() }} +{%- endmacro %} + +
  • +
    +{{ name }} ({{ test_count() }} test{{ test_count() | pluralize }}{% if !root_tests.is_empty() && root_tests.len() as u64 != test_count() -%} + , {{ root_tests.len() }} root test{{ root_tests.len() | pluralize }} +{%- endif %}{% if !groups.is_empty() -%} + , {{ groups.len() }} subdir{{ groups.len() | pluralize }} +{%- endif %}) + + +{% if !groups.is_empty() %} +
      + {% for (dir_name, subgroup) in groups %} + {{ subgroup|safe }} + {% endfor %} +
    +{% endif %} + +{% if !root_tests.is_empty() %} +
      + {% for (name, test) in root_tests %} +
    • + {% if let Some(result) = test.single_test() %} + {{ name }} ({% call test_result(result) %}) + {% else %} + {{ name }} ({{ test.revisions.len() }} revision{{ test.revisions.len() | pluralize }}) +
        + {% for (revision, result) in test.revisions %} +
      • #{{ revision }} ({% call test_result(result) %})
      • + {% endfor %} +
      + {% endif %} +
    • + {% endfor %} +
    +{% endif %} + +
    +
  • diff --git a/src/ci/citool/templates/test_suites.askama b/src/ci/citool/templates/test_suites.askama new file mode 100644 index 0000000000000..4997f6a3f1c9a --- /dev/null +++ b/src/ci/citool/templates/test_suites.askama @@ -0,0 +1,108 @@ +{% extends "layout.askama" %} + +{% block content %} +

    Rust CI test dashboard

    +
    +Here's how to interpret the "passed" and "ignored" counts: +the count includes all combinations of "stage" x "target" x "CI job where the test was executed or ignored". +
    +
    +
    +
    +
    Total tests: {{ test_count }}
    +
    + To find tests that haven't been executed anywhere, click on "Open all" and search for "passed: 0". +
    +
    +
    + + +
    +
    + +
      + {% for suite in suites.suites %} + {{ suite.group|safe }} + {% endfor %} +
    +
    +{% endblock %} + +{% block styles %} +h1 { + text-align: center; + color: #333333; + margin-bottom: 30px; +} + +.summary { + display: flex; + justify-content: space-between; +} + +.test-count { + font-size: 1.2em; +} + +.test-suites { + background: white; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + padding: 20px; +} + +ul { + padding-left: 0; +} + +li { + list-style: none; + padding-left: 20px; +} +summary { + margin-bottom: 5px; + padding: 6px; + background-color: #F4F4F4; + border: 1px solid #ddd; + border-radius: 4px; + cursor: pointer; +} +summary:hover { + background-color: #CFCFCF; +} + +/* Style the disclosure triangles */ +details > summary { + list-style: none; + position: relative; +} + +details > summary::before { + content: "▶"; + position: absolute; + left: -15px; + transform: rotate(0); + transition: transform 0.2s; +} + +details[open] > summary::before { + transform: rotate(90deg); +} +{% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index 4679acf0a6a15..f2e1bb80cb263 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -247,34 +247,31 @@ See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details. ```rust,ignore (making doc tests pass cross-platform is hard) #![feature(naked_functions)] -use std::arch::asm; +use std::arch::naked_asm; use std::mem; fn add_one(x: i32) -> i32 { x + 1 } -#[naked] +#[unsafe(naked)] pub extern "C" fn add_two(x: i32) { // x + 2 preceded by a landing pad/nop block - unsafe { - asm!( - " - nop - nop - nop - nop - nop - nop - nop - nop - nop - lea eax, [rdi+2] - ret - ", - options(noreturn) - ); - } + naked_asm!( + " + nop + nop + nop + nop + nop + nop + nop + nop + nop + lea eax, [rdi+2] + ret + " + ); } fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 { diff --git a/src/tools/nix-dev-shell/flake.nix b/src/tools/nix-dev-shell/flake.nix index 1b838bd2f7b37..b8287de5fcf09 100644 --- a/src/tools/nix-dev-shell/flake.nix +++ b/src/tools/nix-dev-shell/flake.nix @@ -1,32 +1,24 @@ { description = "rustc dev shell"; - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - }; + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - outputs = { self, nixpkgs, flake-utils, ... }: - flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { inherit system; }; - x = import ./x { inherit pkgs; }; - in - { - devShells.default = with pkgs; mkShell { - name = "rustc-dev-shell"; - nativeBuildInputs = with pkgs; [ - binutils cmake ninja pkg-config python3 git curl cacert patchelf nix - ]; - buildInputs = with pkgs; [ - openssl glibc.out glibc.static x - ]; - # Avoid creating text files for ICEs. - RUSTC_ICE = "0"; - # Provide `libstdc++.so.6` for the self-contained lld. - # Provide `libz.so.1`. - LD_LIBRARY_PATH = "${with pkgs; lib.makeLibraryPath [stdenv.cc.cc.lib zlib]}"; - }; - } - ); + outputs = + { + self, + nixpkgs, + }: + let + inherit (nixpkgs) lib; + forEachSystem = lib.genAttrs lib.systems.flakeExposed; + in + { + devShells = forEachSystem (system: { + default = nixpkgs.legacyPackages.${system}.callPackage ./shell.nix { }; + }); + + packages = forEachSystem (system: { + default = nixpkgs.legacyPackages.${system}.callPackage ./x { }; + }); + }; } diff --git a/src/tools/nix-dev-shell/shell.nix b/src/tools/nix-dev-shell/shell.nix index a3f5969bd812d..0adbacf7e8d56 100644 --- a/src/tools/nix-dev-shell/shell.nix +++ b/src/tools/nix-dev-shell/shell.nix @@ -1,18 +1,26 @@ -{ pkgs ? import {} }: -let - x = import ./x { inherit pkgs; }; +{ + pkgs ? import { }, +}: +let + inherit (pkgs.lib) lists attrsets; + + x = pkgs.callPackage ./x { }; + inherit (x.passthru) cacert env; in pkgs.mkShell { - name = "rustc"; - nativeBuildInputs = with pkgs; [ - binutils cmake ninja pkg-config python3 git curl cacert patchelf nix - ]; - buildInputs = with pkgs; [ - openssl glibc.out glibc.static x - ]; - # Avoid creating text files for ICEs. - RUSTC_ICE = "0"; - # Provide `libstdc++.so.6` for the self-contained lld. - # Provide `libz.so.1` - LD_LIBRARY_PATH = "${with pkgs; lib.makeLibraryPath [stdenv.cc.cc.lib zlib]}"; + name = "rustc-shell"; + + inputsFrom = [ x ]; + packages = [ + pkgs.git + pkgs.nix + x + # Get the runtime deps of the x wrapper + ] ++ lists.flatten (attrsets.attrValues env); + + env = { + # Avoid creating text files for ICEs. + RUSTC_ICE = 0; + SSL_CERT_FILE = cacert; + }; } diff --git a/src/tools/nix-dev-shell/x/default.nix b/src/tools/nix-dev-shell/x/default.nix index e6dfbad6f19c8..422c1c4a2aed8 100644 --- a/src/tools/nix-dev-shell/x/default.nix +++ b/src/tools/nix-dev-shell/x/default.nix @@ -1,22 +1,83 @@ { - pkgs ? import { }, + pkgs, + lib, + stdenv, + rustc, + python3, + makeBinaryWrapper, + # Bootstrap + curl, + pkg-config, + libiconv, + openssl, + patchelf, + cacert, + zlib, + # LLVM Deps + ninja, + cmake, + glibc, }: -pkgs.stdenv.mkDerivation { - name = "x"; +stdenv.mkDerivation (self: { + strictDeps = true; + name = "x-none"; + + outputs = [ + "out" + "unwrapped" + ]; src = ./x.rs; dontUnpack = true; - nativeBuildInputs = with pkgs; [ rustc ]; + nativeBuildInputs = [ + rustc + makeBinaryWrapper + ]; + env.PYTHON = python3.interpreter; buildPhase = '' - PYTHON=${pkgs.lib.getExe pkgs.python3} rustc -Copt-level=3 --crate-name x $src --out-dir $out/bin + rustc -Copt-level=3 --crate-name x $src --out-dir $unwrapped/bin ''; - meta = with pkgs.lib; { + installPhase = + let + inherit (self.passthru) cacert env; + in + '' + makeWrapper $unwrapped/bin/x $out/bin/x \ + --set-default SSL_CERT_FILE ${cacert} \ + --prefix CPATH ";" "${lib.makeSearchPath "include" env.cpath}" \ + --prefix PATH : ${lib.makeBinPath env.path} \ + --prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath env.ldLib} + ''; + + # For accessing them in the devshell + passthru = { + env = { + cpath = [ libiconv ]; + path = [ + python3 + patchelf + curl + pkg-config + cmake + ninja + stdenv.cc + ]; + ldLib = [ + openssl + zlib + stdenv.cc.cc.lib + ]; + }; + cacert = "${cacert}/etc/ssl/certs/ca-bundle.crt"; + }; + + meta = { description = "Helper for rust-lang/rust x.py"; homepage = "https://github.com/rust-lang/rust/blob/master/src/tools/x"; - license = licenses.mit; + license = lib.licenses.mit; mainProgram = "x"; }; -} +}) diff --git a/tests/assembly/naked-functions/aarch64-naked-fn-no-bti-prolog.rs b/tests/assembly/naked-functions/aarch64-naked-fn-no-bti-prolog.rs index 46e627eaa00bd..46acf7c6501a9 100644 --- a/tests/assembly/naked-functions/aarch64-naked-fn-no-bti-prolog.rs +++ b/tests/assembly/naked-functions/aarch64-naked-fn-no-bti-prolog.rs @@ -13,8 +13,8 @@ use std::arch::naked_asm; // LLVM implements this via making sure of that, even for functions with the naked attribute. // So, we must emit an appropriate instruction instead! #[no_mangle] -#[naked] -pub unsafe extern "C" fn _hlt() -> ! { +#[unsafe(naked)] +pub extern "C" fn _hlt() -> ! { // CHECK-NOT: hint #34 // CHECK: hlt #0x1 naked_asm!("hlt #1") diff --git a/tests/assembly/naked-functions/aix.rs b/tests/assembly/naked-functions/aix.rs index cc0825b37387c..9aa9edc39e78b 100644 --- a/tests/assembly/naked-functions/aix.rs +++ b/tests/assembly/naked-functions/aix.rs @@ -29,7 +29,7 @@ use minicore::*; // CHECK-LABEL: blr: // CHECK: blr #[no_mangle] -#[naked] -unsafe extern "C" fn blr() { +#[unsafe(naked)] +extern "C" fn blr() { naked_asm!("blr") } diff --git a/tests/assembly/naked-functions/wasm32.rs b/tests/assembly/naked-functions/wasm32.rs index 4911a6bd08f68..c114cb385be17 100644 --- a/tests/assembly/naked-functions/wasm32.rs +++ b/tests/assembly/naked-functions/wasm32.rs @@ -22,8 +22,8 @@ use minicore::*; // CHECK-NOT: .size // CHECK: end_function #[no_mangle] -#[naked] -unsafe extern "C" fn nop() { +#[unsafe(naked)] +extern "C" fn nop() { naked_asm!("nop") } @@ -34,11 +34,11 @@ unsafe extern "C" fn nop() { // CHECK-NOT: .size // CHECK: end_function #[no_mangle] -#[naked] +#[unsafe(naked)] #[linkage = "weak"] // wasm functions cannot be aligned, so this has no effect #[repr(align(32))] -unsafe extern "C" fn weak_aligned_nop() { +extern "C" fn weak_aligned_nop() { naked_asm!("nop") } @@ -51,48 +51,48 @@ unsafe extern "C" fn weak_aligned_nop() { // // CHECK-NEXT: end_function #[no_mangle] -#[naked] -unsafe extern "C" fn fn_i8_i8(num: i8) -> i8 { +#[unsafe(naked)] +extern "C" fn fn_i8_i8(num: i8) -> i8 { naked_asm!("local.get 0", "local.get 0", "i32.mul") } // CHECK-LABEL: fn_i8_i8_i8: // CHECK: .functype fn_i8_i8_i8 (i32, i32) -> (i32) #[no_mangle] -#[naked] -unsafe extern "C" fn fn_i8_i8_i8(a: i8, b: i8) -> i8 { +#[unsafe(naked)] +extern "C" fn fn_i8_i8_i8(a: i8, b: i8) -> i8 { naked_asm!("local.get 1", "local.get 0", "i32.mul") } // CHECK-LABEL: fn_unit_i8: // CHECK: .functype fn_unit_i8 () -> (i32) #[no_mangle] -#[naked] -unsafe extern "C" fn fn_unit_i8() -> i8 { +#[unsafe(naked)] +extern "C" fn fn_unit_i8() -> i8 { naked_asm!("i32.const 42") } // CHECK-LABEL: fn_i8_unit: // CHECK: .functype fn_i8_unit (i32) -> () #[no_mangle] -#[naked] -unsafe extern "C" fn fn_i8_unit(_: i8) { +#[unsafe(naked)] +extern "C" fn fn_i8_unit(_: i8) { naked_asm!("nop") } // CHECK-LABEL: fn_i32_i32: // CHECK: .functype fn_i32_i32 (i32) -> (i32) #[no_mangle] -#[naked] -unsafe extern "C" fn fn_i32_i32(num: i32) -> i32 { +#[unsafe(naked)] +extern "C" fn fn_i32_i32(num: i32) -> i32 { naked_asm!("local.get 0", "local.get 0", "i32.mul") } // CHECK-LABEL: fn_i64_i64: // CHECK: .functype fn_i64_i64 (i64) -> (i64) #[no_mangle] -#[naked] -unsafe extern "C" fn fn_i64_i64(num: i64) -> i64 { +#[unsafe(naked)] +extern "C" fn fn_i64_i64(num: i64) -> i64 { naked_asm!("local.get 0", "local.get 0", "i64.mul") } @@ -101,8 +101,8 @@ unsafe extern "C" fn fn_i64_i64(num: i64) -> i64 { // wasm64-unknown: .functype fn_i128_i128 (i64, i64, i64) -> () #[allow(improper_ctypes_definitions)] #[no_mangle] -#[naked] -unsafe extern "C" fn fn_i128_i128(num: i128) -> i128 { +#[unsafe(naked)] +extern "C" fn fn_i128_i128(num: i128) -> i128 { naked_asm!( "local.get 0", "local.get 2", @@ -117,8 +117,8 @@ unsafe extern "C" fn fn_i128_i128(num: i128) -> i128 { // wasm32-wasip1: .functype fn_f128_f128 (i32, i64, i64) -> () // wasm64-unknown: .functype fn_f128_f128 (i64, i64, i64) -> () #[no_mangle] -#[naked] -unsafe extern "C" fn fn_f128_f128(num: f128) -> f128 { +#[unsafe(naked)] +extern "C" fn fn_f128_f128(num: f128) -> f128 { naked_asm!( "local.get 0", "local.get 2", @@ -139,8 +139,8 @@ struct Compound { // wasm32-wasip1: .functype fn_compound_compound (i32, i32) -> () // wasm64-unknown: .functype fn_compound_compound (i64, i64) -> () #[no_mangle] -#[naked] -unsafe extern "C" fn fn_compound_compound(_: Compound) -> Compound { +#[unsafe(naked)] +extern "C" fn fn_compound_compound(_: Compound) -> Compound { // this is the wasm32-wasip1 assembly naked_asm!( "local.get 0", @@ -160,8 +160,8 @@ struct WrapperI32(i32); // CHECK-LABEL: fn_wrapperi32_wrapperi32: // CHECK: .functype fn_wrapperi32_wrapperi32 (i32) -> (i32) #[no_mangle] -#[naked] -unsafe extern "C" fn fn_wrapperi32_wrapperi32(_: WrapperI32) -> WrapperI32 { +#[unsafe(naked)] +extern "C" fn fn_wrapperi32_wrapperi32(_: WrapperI32) -> WrapperI32 { naked_asm!("local.get 0") } @@ -171,8 +171,8 @@ struct WrapperI64(i64); // CHECK-LABEL: fn_wrapperi64_wrapperi64: // CHECK: .functype fn_wrapperi64_wrapperi64 (i64) -> (i64) #[no_mangle] -#[naked] -unsafe extern "C" fn fn_wrapperi64_wrapperi64(_: WrapperI64) -> WrapperI64 { +#[unsafe(naked)] +extern "C" fn fn_wrapperi64_wrapperi64(_: WrapperI64) -> WrapperI64 { naked_asm!("local.get 0") } @@ -182,8 +182,8 @@ struct WrapperF32(f32); // CHECK-LABEL: fn_wrapperf32_wrapperf32: // CHECK: .functype fn_wrapperf32_wrapperf32 (f32) -> (f32) #[no_mangle] -#[naked] -unsafe extern "C" fn fn_wrapperf32_wrapperf32(_: WrapperF32) -> WrapperF32 { +#[unsafe(naked)] +extern "C" fn fn_wrapperf32_wrapperf32(_: WrapperF32) -> WrapperF32 { naked_asm!("local.get 0") } @@ -193,7 +193,7 @@ struct WrapperF64(f64); // CHECK-LABEL: fn_wrapperf64_wrapperf64: // CHECK: .functype fn_wrapperf64_wrapperf64 (f64) -> (f64) #[no_mangle] -#[naked] -unsafe extern "C" fn fn_wrapperf64_wrapperf64(_: WrapperF64) -> WrapperF64 { +#[unsafe(naked)] +extern "C" fn fn_wrapperf64_wrapperf64(_: WrapperF64) -> WrapperF64 { naked_asm!("local.get 0") } diff --git a/tests/assembly/naked-functions/x86_64-naked-fn-no-cet-prolog.rs b/tests/assembly/naked-functions/x86_64-naked-fn-no-cet-prolog.rs index 54e1d93c68bd6..df6a2e91c51ea 100644 --- a/tests/assembly/naked-functions/x86_64-naked-fn-no-cet-prolog.rs +++ b/tests/assembly/naked-functions/x86_64-naked-fn-no-cet-prolog.rs @@ -13,8 +13,8 @@ use std::arch::naked_asm; // works by using an instruction for each possible landing site, // and LLVM implements this via making sure of that. #[no_mangle] -#[naked] -pub unsafe extern "sysv64" fn will_halt() -> ! { +#[unsafe(naked)] +pub extern "sysv64" fn will_halt() -> ! { // CHECK-NOT: endbr{{32|64}} // CHECK: hlt naked_asm!("hlt") diff --git a/tests/codegen/cffi/c-variadic-naked.rs b/tests/codegen/cffi/c-variadic-naked.rs index 24b69c5f59e21..05d48e52dc006 100644 --- a/tests/codegen/cffi/c-variadic-naked.rs +++ b/tests/codegen/cffi/c-variadic-naked.rs @@ -8,11 +8,9 @@ #![feature(naked_functions)] #![no_std] -#[naked] +#[unsafe(naked)] pub unsafe extern "C" fn c_variadic(_: usize, _: ...) { // CHECK-NOT: va_start // CHECK-NOT: alloca - core::arch::naked_asm! { - "ret", - } + core::arch::naked_asm!("ret") } diff --git a/tests/codegen/naked-asan.rs b/tests/codegen/naked-asan.rs index 8efedab6ea55d..52b3e709cd35c 100644 --- a/tests/codegen/naked-asan.rs +++ b/tests/codegen/naked-asan.rs @@ -13,10 +13,10 @@ pub fn caller() { } // CHECK: declare x86_intrcc void @page_fault_handler(ptr {{.*}}, i64{{.*}}){{.*}}#[[ATTRS:[0-9]+]] -#[naked] +#[unsafe(naked)] #[no_mangle] pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) { - unsafe { core::arch::naked_asm!("ud2") }; + core::arch::naked_asm!("ud2") } // CHECK: #[[ATTRS]] = diff --git a/tests/codegen/naked-fn/aligned.rs b/tests/codegen/naked-fn/aligned.rs index d9dcd7f6c3ef7..6183461fedaec 100644 --- a/tests/codegen/naked-fn/aligned.rs +++ b/tests/codegen/naked-fn/aligned.rs @@ -10,8 +10,8 @@ use std::arch::naked_asm; // CHECK-LABEL: naked_empty: #[repr(align(16))] #[no_mangle] -#[naked] -pub unsafe extern "C" fn naked_empty() { +#[unsafe(naked)] +pub extern "C" fn naked_empty() { // CHECK: ret - naked_asm!("ret"); + naked_asm!("ret") } diff --git a/tests/codegen/naked-fn/generics.rs b/tests/codegen/naked-fn/generics.rs index 64998df64ddb6..4427586777168 100644 --- a/tests/codegen/naked-fn/generics.rs +++ b/tests/codegen/naked-fn/generics.rs @@ -28,21 +28,19 @@ fn test(x: u64) { // CHECK: add rax, 1 // CHECK: add rax, 42 -#[naked] +#[unsafe(naked)] pub extern "C" fn using_const_generics(x: u64) -> u64 { const M: u64 = 42; - unsafe { - naked_asm!( - "xor rax, rax", - "add rax, rdi", - "add rax, {}", - "add rax, {}", - "ret", - const N, - const M, - ) - } + naked_asm!( + "xor rax, rax", + "add rax, rdi", + "add rax, {}", + "add rax, {}", + "ret", + const N, + const M, + ) } trait Invert { @@ -60,16 +58,14 @@ impl Invert for i64 { // CHECK: call // CHECK: ret -#[naked] +#[unsafe(naked)] #[no_mangle] pub extern "C" fn generic_function(x: i64) -> i64 { - unsafe { - naked_asm!( - "call {}", - "ret", - sym ::invert, - ) - } + naked_asm!( + "call {}", + "ret", + sym ::invert, + ) } #[derive(Copy, Clone)] @@ -81,10 +77,10 @@ struct Foo(u64); // CHECK: mov rax, rdi impl Foo { - #[naked] + #[unsafe(naked)] #[no_mangle] extern "C" fn method(self) -> u64 { - unsafe { naked_asm!("mov rax, rdi", "ret") } + naked_asm!("mov rax, rdi", "ret") } } @@ -97,10 +93,10 @@ trait Bar { } impl Bar for Foo { - #[naked] + #[unsafe(naked)] #[no_mangle] extern "C" fn trait_method(self) -> u64 { - unsafe { naked_asm!("mov rax, rdi", "ret") } + naked_asm!("mov rax, rdi", "ret") } } @@ -109,7 +105,7 @@ impl Bar for Foo { // CHECK: lea rax, [rdi + rsi] // this previously ICE'd, see https://github.com/rust-lang/rust/issues/124375 -#[naked] +#[unsafe(naked)] #[no_mangle] pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize { naked_asm!("lea rax, [rdi + rsi]", "ret"); diff --git a/tests/codegen/naked-fn/instruction-set.rs b/tests/codegen/naked-fn/instruction-set.rs index a7b4c22a59bfd..2ccd47d645858 100644 --- a/tests/codegen/naked-fn/instruction-set.rs +++ b/tests/codegen/naked-fn/instruction-set.rs @@ -20,8 +20,8 @@ use minicore::*; // arm-mode: .arm // thumb-mode: .thumb #[no_mangle] -#[naked] -unsafe extern "C" fn test_unspecified() { +#[unsafe(naked)] +extern "C" fn test_unspecified() { naked_asm!("bx lr"); } @@ -33,9 +33,9 @@ unsafe extern "C" fn test_unspecified() { // arm-mode: .arm // thumb-mode: .thumb #[no_mangle] -#[naked] +#[unsafe(naked)] #[instruction_set(arm::t32)] -unsafe extern "C" fn test_thumb() { +extern "C" fn test_thumb() { naked_asm!("bx lr"); } @@ -46,8 +46,8 @@ unsafe extern "C" fn test_thumb() { // arm-mode: .arm // thumb-mode: .thumb #[no_mangle] -#[naked] +#[unsafe(naked)] #[instruction_set(arm::a32)] -unsafe extern "C" fn test_arm() { +extern "C" fn test_arm() { naked_asm!("bx lr"); } diff --git a/tests/codegen/naked-fn/min-function-alignment.rs b/tests/codegen/naked-fn/min-function-alignment.rs index 1330d796d397f..4a9142288248b 100644 --- a/tests/codegen/naked-fn/min-function-alignment.rs +++ b/tests/codegen/naked-fn/min-function-alignment.rs @@ -9,24 +9,24 @@ // // CHECK: .balign 16 #[no_mangle] -#[naked] -pub unsafe extern "C" fn naked_no_explicit_align() { +#[unsafe(naked)] +pub extern "C" fn naked_no_explicit_align() { core::arch::naked_asm!("ret") } // CHECK: .balign 16 #[no_mangle] #[repr(align(8))] -#[naked] -pub unsafe extern "C" fn naked_lower_align() { +#[unsafe(naked)] +pub extern "C" fn naked_lower_align() { core::arch::naked_asm!("ret") } // CHECK: .balign 32 #[no_mangle] #[repr(align(32))] -#[naked] -pub unsafe extern "C" fn naked_higher_align() { +#[unsafe(naked)] +pub extern "C" fn naked_higher_align() { core::arch::naked_asm!("ret") } @@ -38,7 +38,7 @@ pub unsafe extern "C" fn naked_higher_align() { // CHECK: .balign 16 #[no_mangle] #[cold] -#[naked] -pub unsafe extern "C" fn no_explicit_align_cold() { +#[unsafe(naked)] +pub extern "C" fn no_explicit_align_cold() { core::arch::naked_asm!("ret") } diff --git a/tests/codegen/naked-fn/naked-functions.rs b/tests/codegen/naked-fn/naked-functions.rs index 3fe795178b702..1bcdd6de373e5 100644 --- a/tests/codegen/naked-fn/naked-functions.rs +++ b/tests/codegen/naked-fn/naked-functions.rs @@ -60,8 +60,8 @@ use minicore::*; // linux,win: .att_syntax #[no_mangle] -#[naked] -pub unsafe extern "C" fn naked_empty() { +#[unsafe(naked)] +pub extern "C" fn naked_empty() { #[cfg(not(all(target_arch = "arm", target_feature = "thumb-mode")))] naked_asm!("ret"); @@ -114,8 +114,8 @@ pub unsafe extern "C" fn naked_empty() { // linux,win: .att_syntax #[no_mangle] -#[naked] -pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize { +#[unsafe(naked)] +pub extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize { #[cfg(any(target_os = "windows", target_os = "linux"))] { naked_asm!("lea rax, [rdi + rsi]", "ret") @@ -138,9 +138,9 @@ pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize // thumb: .pushsection .text.some_different_name,\22ax\22, %progbits // CHECK-LABEL: test_link_section: #[no_mangle] -#[naked] +#[unsafe(naked)] #[link_section = ".text.some_different_name"] -pub unsafe extern "C" fn test_link_section() { +pub extern "C" fn test_link_section() { #[cfg(not(all(target_arch = "arm", target_feature = "thumb-mode")))] naked_asm!("ret"); @@ -159,7 +159,7 @@ pub unsafe extern "C" fn test_link_section() { // win_i686-LABEL: @fastcall_cc@4: #[cfg(target_os = "windows")] #[no_mangle] -#[naked] -pub unsafe extern "fastcall" fn fastcall_cc(x: i32) -> i32 { +#[unsafe(naked)] +pub extern "fastcall" fn fastcall_cc(x: i32) -> i32 { naked_asm!("ret"); } diff --git a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs index f98a2036544c3..ae75519525363 100644 --- a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs +++ b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs @@ -26,9 +26,9 @@ extern "C" fn private_vanilla() -> u32 { 42 } -#[naked] +#[unsafe(naked)] extern "C" fn private_naked() -> u32 { - unsafe { naked_asm!("mov rax, 42", "ret") } + naked_asm!("mov rax, 42", "ret") } #[no_mangle] @@ -36,19 +36,19 @@ pub extern "C" fn public_vanilla() -> u32 { 42 } -#[naked] +#[unsafe(naked)] #[no_mangle] pub extern "C" fn public_naked_nongeneric() -> u32 { - unsafe { naked_asm!("mov rax, 42", "ret") } + naked_asm!("mov rax, 42", "ret") } pub extern "C" fn public_vanilla_generic() -> u32 { T::COUNT } -#[naked] +#[unsafe(naked)] pub extern "C" fn public_naked_generic() -> u32 { - unsafe { naked_asm!("mov rax, {}", "ret", const T::COUNT) } + naked_asm!("mov rax, {}", "ret", const T::COUNT) } #[linkage = "external"] @@ -56,10 +56,10 @@ extern "C" fn vanilla_external_linkage() -> u32 { 42 } -#[naked] +#[unsafe(naked)] #[linkage = "external"] extern "C" fn naked_external_linkage() -> u32 { - unsafe { naked_asm!("mov rax, 42", "ret") } + naked_asm!("mov rax, 42", "ret") } #[cfg(not(windows))] @@ -68,11 +68,11 @@ extern "C" fn vanilla_weak_linkage() -> u32 { 42 } -#[naked] +#[unsafe(naked)] #[cfg(not(windows))] #[linkage = "weak"] extern "C" fn naked_weak_linkage() -> u32 { - unsafe { naked_asm!("mov rax, 42", "ret") } + naked_asm!("mov rax, 42", "ret") } // functions that are declared in an `extern "C"` block are currently not exported diff --git a/tests/ui/asm/naked-asm-outside-naked-fn.rs b/tests/ui/asm/naked-asm-outside-naked-fn.rs index 1696008f3397d..a7680cc63ae03 100644 --- a/tests/ui/asm/naked-asm-outside-naked-fn.rs +++ b/tests/ui/asm/naked-asm-outside-naked-fn.rs @@ -12,24 +12,24 @@ fn main() { test1(); } -#[naked] +#[unsafe(naked)] extern "C" fn test1() { - unsafe { naked_asm!("") } + naked_asm!("") } extern "C" fn test2() { - unsafe { naked_asm!("") } - //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[naked]` + naked_asm!("") + //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` } extern "C" fn test3() { - unsafe { (|| naked_asm!(""))() } - //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[naked]` + (|| naked_asm!(""))() + //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` } fn test4() { async move { - unsafe { naked_asm!("") } ; - //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[naked]` + naked_asm!(""); + //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` }; } diff --git a/tests/ui/asm/naked-asm-outside-naked-fn.stderr b/tests/ui/asm/naked-asm-outside-naked-fn.stderr index 6e91359669ca2..85a50a49fecfc 100644 --- a/tests/ui/asm/naked-asm-outside-naked-fn.stderr +++ b/tests/ui/asm/naked-asm-outside-naked-fn.stderr @@ -1,20 +1,20 @@ -error: the `naked_asm!` macro can only be used in functions marked with `#[naked]` - --> $DIR/naked-asm-outside-naked-fn.rs:21:14 +error: the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` + --> $DIR/naked-asm-outside-naked-fn.rs:21:5 | -LL | unsafe { naked_asm!("") } - | ^^^^^^^^^^^^^^ +LL | naked_asm!("") + | ^^^^^^^^^^^^^^ -error: the `naked_asm!` macro can only be used in functions marked with `#[naked]` - --> $DIR/naked-asm-outside-naked-fn.rs:26:18 +error: the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` + --> $DIR/naked-asm-outside-naked-fn.rs:26:9 | -LL | unsafe { (|| naked_asm!(""))() } - | ^^^^^^^^^^^^^^ +LL | (|| naked_asm!(""))() + | ^^^^^^^^^^^^^^ -error: the `naked_asm!` macro can only be used in functions marked with `#[naked]` - --> $DIR/naked-asm-outside-naked-fn.rs:32:19 +error: the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` + --> $DIR/naked-asm-outside-naked-fn.rs:32:9 | -LL | unsafe { naked_asm!("") } ; - | ^^^^^^^^^^^^^^ +LL | naked_asm!(""); + | ^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/tests/ui/asm/naked-functions-ffi.rs b/tests/ui/asm/naked-functions-ffi.rs index b78d1e6a0d1c6..8fd0da01d72a7 100644 --- a/tests/ui/asm/naked-functions-ffi.rs +++ b/tests/ui/asm/naked-functions-ffi.rs @@ -5,11 +5,9 @@ use std::arch::naked_asm; -#[naked] +#[unsafe(naked)] pub extern "C" fn naked(p: char) -> u128 { //~^ WARN uses type `char` //~| WARN uses type `u128` - unsafe { - naked_asm!(""); - } + naked_asm!("") } diff --git a/tests/ui/asm/naked-functions-inline.rs b/tests/ui/asm/naked-functions-inline.rs index 74049e8ecbc7c..261401be64517 100644 --- a/tests/ui/asm/naked-functions-inline.rs +++ b/tests/ui/asm/naked-functions-inline.rs @@ -4,35 +4,35 @@ use std::arch::naked_asm; -#[naked] -pub unsafe extern "C" fn inline_none() { +#[unsafe(naked)] +pub extern "C" fn inline_none() { naked_asm!(""); } -#[naked] +#[unsafe(naked)] #[inline] //~^ ERROR [E0736] -pub unsafe extern "C" fn inline_hint() { +pub extern "C" fn inline_hint() { naked_asm!(""); } -#[naked] +#[unsafe(naked)] #[inline(always)] //~^ ERROR [E0736] -pub unsafe extern "C" fn inline_always() { +pub extern "C" fn inline_always() { naked_asm!(""); } -#[naked] +#[unsafe(naked)] #[inline(never)] //~^ ERROR [E0736] -pub unsafe extern "C" fn inline_never() { +pub extern "C" fn inline_never() { naked_asm!(""); } -#[naked] +#[unsafe(naked)] #[cfg_attr(all(), inline(never))] //~^ ERROR [E0736] -pub unsafe extern "C" fn conditional_inline_never() { +pub extern "C" fn conditional_inline_never() { naked_asm!(""); } diff --git a/tests/ui/asm/naked-functions-inline.stderr b/tests/ui/asm/naked-functions-inline.stderr index 84a688f6f5382..6df5b08ae8534 100644 --- a/tests/ui/asm/naked-functions-inline.stderr +++ b/tests/ui/asm/naked-functions-inline.stderr @@ -1,34 +1,34 @@ -error[E0736]: attribute incompatible with `#[naked]` +error[E0736]: attribute incompatible with `#[unsafe(naked)]` --> $DIR/naked-functions-inline.rs:13:1 | -LL | #[naked] - | -------- function marked with `#[naked]` here +LL | #[unsafe(naked)] + | ---------------- function marked with `#[unsafe(naked)]` here LL | #[inline] - | ^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]` + | ^^^^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` -error[E0736]: attribute incompatible with `#[naked]` +error[E0736]: attribute incompatible with `#[unsafe(naked)]` --> $DIR/naked-functions-inline.rs:20:1 | -LL | #[naked] - | -------- function marked with `#[naked]` here +LL | #[unsafe(naked)] + | ---------------- function marked with `#[unsafe(naked)]` here LL | #[inline(always)] - | ^^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]` + | ^^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` -error[E0736]: attribute incompatible with `#[naked]` +error[E0736]: attribute incompatible with `#[unsafe(naked)]` --> $DIR/naked-functions-inline.rs:27:1 | -LL | #[naked] - | -------- function marked with `#[naked]` here +LL | #[unsafe(naked)] + | ---------------- function marked with `#[unsafe(naked)]` here LL | #[inline(never)] - | ^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]` + | ^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` -error[E0736]: attribute incompatible with `#[naked]` +error[E0736]: attribute incompatible with `#[unsafe(naked)]` --> $DIR/naked-functions-inline.rs:34:19 | -LL | #[naked] - | -------- function marked with `#[naked]` here +LL | #[unsafe(naked)] + | ---------------- function marked with `#[unsafe(naked)]` here LL | #[cfg_attr(all(), inline(never))] - | ^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]` + | ^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` error: aborting due to 4 previous errors diff --git a/tests/ui/asm/naked-functions-instruction-set.rs b/tests/ui/asm/naked-functions-instruction-set.rs index 28241badf5f87..6fd34b035edd0 100644 --- a/tests/ui/asm/naked-functions-instruction-set.rs +++ b/tests/ui/asm/naked-functions-instruction-set.rs @@ -12,15 +12,15 @@ extern crate minicore; use minicore::*; #[no_mangle] -#[naked] +#[unsafe(naked)] #[instruction_set(arm::t32)] -unsafe extern "C" fn test_thumb() { +extern "C" fn test_thumb() { naked_asm!("bx lr"); } #[no_mangle] -#[naked] +#[unsafe(naked)] #[instruction_set(arm::a32)] -unsafe extern "C" fn test_arm() { +extern "C" fn test_arm() { naked_asm!("bx lr"); } diff --git a/tests/ui/asm/naked-functions-rustic-abi.rs b/tests/ui/asm/naked-functions-rustic-abi.rs index b654d38ccc1a6..99b8d2e19fe40 100644 --- a/tests/ui/asm/naked-functions-rustic-abi.rs +++ b/tests/ui/asm/naked-functions-rustic-abi.rs @@ -11,17 +11,17 @@ use std::arch::{asm, naked_asm}; -#[naked] -pub unsafe fn rust_implicit() { +#[unsafe(naked)] +pub fn rust_implicit() { naked_asm!("ret"); } -#[naked] -pub unsafe extern "Rust" fn rust_explicit() { +#[unsafe(naked)] +pub extern "Rust" fn rust_explicit() { naked_asm!("ret"); } -#[naked] -pub unsafe extern "rust-cold" fn rust_cold() { +#[unsafe(naked)] +pub extern "rust-cold" fn rust_cold() { naked_asm!("ret"); } diff --git a/tests/ui/asm/naked-functions-target-feature.rs b/tests/ui/asm/naked-functions-target-feature.rs index afe1a38914720..d8dc2104c76e1 100644 --- a/tests/ui/asm/naked-functions-target-feature.rs +++ b/tests/ui/asm/naked-functions-target-feature.rs @@ -8,14 +8,14 @@ use std::arch::{asm, naked_asm}; #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] -#[naked] -pub unsafe extern "C" fn compatible_target_feature() { - naked_asm!(""); +#[unsafe(naked)] +pub extern "C" fn compatible_target_feature() { + naked_asm!("ret"); } #[cfg(target_arch = "aarch64")] #[target_feature(enable = "neon")] -#[naked] -pub unsafe extern "C" fn compatible_target_feature() { - naked_asm!(""); +#[unsafe(naked)] +pub extern "C" fn compatible_target_feature() { + naked_asm!("ret"); } diff --git a/tests/ui/asm/naked-functions-testattrs.rs b/tests/ui/asm/naked-functions-testattrs.rs index ad31876a77a59..c8539e8064088 100644 --- a/tests/ui/asm/naked-functions-testattrs.rs +++ b/tests/ui/asm/naked-functions-testattrs.rs @@ -8,31 +8,31 @@ use std::arch::naked_asm; #[test] -#[naked] +#[unsafe(naked)] //~^ ERROR [E0736] extern "C" fn test_naked() { - unsafe { naked_asm!("") }; + naked_asm!("") } #[should_panic] #[test] -#[naked] +#[unsafe(naked)] //~^ ERROR [E0736] extern "C" fn test_naked_should_panic() { - unsafe { naked_asm!("") }; + naked_asm!("") } #[ignore] #[test] -#[naked] +#[unsafe(naked)] //~^ ERROR [E0736] extern "C" fn test_naked_ignore() { - unsafe { naked_asm!("") }; + naked_asm!("") } #[bench] -#[naked] +#[unsafe(naked)] //~^ ERROR [E0736] extern "C" fn bench_naked() { - unsafe { naked_asm!("") }; + naked_asm!("") } diff --git a/tests/ui/asm/naked-functions-testattrs.stderr b/tests/ui/asm/naked-functions-testattrs.stderr index 0f0bb91b95413..ad2041ec118b9 100644 --- a/tests/ui/asm/naked-functions-testattrs.stderr +++ b/tests/ui/asm/naked-functions-testattrs.stderr @@ -1,34 +1,34 @@ -error[E0736]: cannot use `#[naked]` with testing attributes +error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes --> $DIR/naked-functions-testattrs.rs:11:1 | LL | #[test] | ------- function marked with testing attribute here -LL | #[naked] - | ^^^^^^^^ `#[naked]` is incompatible with testing attributes +LL | #[unsafe(naked)] + | ^^^^^^^^^^^^^^^^ `#[unsafe(naked)]` is incompatible with testing attributes -error[E0736]: cannot use `#[naked]` with testing attributes +error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes --> $DIR/naked-functions-testattrs.rs:19:1 | LL | #[test] | ------- function marked with testing attribute here -LL | #[naked] - | ^^^^^^^^ `#[naked]` is incompatible with testing attributes +LL | #[unsafe(naked)] + | ^^^^^^^^^^^^^^^^ `#[unsafe(naked)]` is incompatible with testing attributes -error[E0736]: cannot use `#[naked]` with testing attributes +error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes --> $DIR/naked-functions-testattrs.rs:27:1 | LL | #[test] | ------- function marked with testing attribute here -LL | #[naked] - | ^^^^^^^^ `#[naked]` is incompatible with testing attributes +LL | #[unsafe(naked)] + | ^^^^^^^^^^^^^^^^ `#[unsafe(naked)]` is incompatible with testing attributes -error[E0736]: cannot use `#[naked]` with testing attributes +error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes --> $DIR/naked-functions-testattrs.rs:34:1 | LL | #[bench] | -------- function marked with testing attribute here -LL | #[naked] - | ^^^^^^^^ `#[naked]` is incompatible with testing attributes +LL | #[unsafe(naked)] + | ^^^^^^^^^^^^^^^^ `#[unsafe(naked)]` is incompatible with testing attributes error: aborting due to 4 previous errors diff --git a/tests/ui/asm/naked-functions-unused.rs b/tests/ui/asm/naked-functions-unused.rs index c27037819a44f..67c05984be71c 100644 --- a/tests/ui/asm/naked-functions-unused.rs +++ b/tests/ui/asm/naked-functions-unused.rs @@ -64,44 +64,34 @@ pub mod normal { pub mod naked { use std::arch::naked_asm; - #[naked] + #[unsafe(naked)] pub extern "C" fn function(a: usize, b: usize) -> usize { - unsafe { - naked_asm!(""); - } + naked_asm!("") } pub struct Naked; impl Naked { - #[naked] + #[unsafe(naked)] pub extern "C" fn associated(a: usize, b: usize) -> usize { - unsafe { - naked_asm!(""); - } + naked_asm!("") } - #[naked] + #[unsafe(naked)] pub extern "C" fn method(&self, a: usize, b: usize) -> usize { - unsafe { - naked_asm!(""); - } + naked_asm!("") } } impl super::Trait for Naked { - #[naked] + #[unsafe(naked)] extern "C" fn trait_associated(a: usize, b: usize) -> usize { - unsafe { - naked_asm!(""); - } + naked_asm!("") } - #[naked] + #[unsafe(naked)] extern "C" fn trait_method(&self, a: usize, b: usize) -> usize { - unsafe { - naked_asm!(""); - } + naked_asm!("") } } } diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs index 8ba0eecb7b5c7..b433c1b5389c4 100644 --- a/tests/ui/asm/naked-functions.rs +++ b/tests/ui/asm/naked-functions.rs @@ -9,8 +9,8 @@ use std::arch::{asm, naked_asm}; #[unsafe(naked)] -pub unsafe extern "C" fn inline_asm_macro() { - asm!("", options(raw)); +pub extern "C" fn inline_asm_macro() { + unsafe { asm!("", options(raw)) }; //~^ERROR the `asm!` macro is not allowed in naked functions } @@ -21,7 +21,7 @@ pub struct P { } #[unsafe(naked)] -pub unsafe extern "C" fn patterns( +pub extern "C" fn patterns( mut a: u32, //~^ ERROR patterns not allowed in naked function parameters &b: &i32, @@ -35,7 +35,7 @@ pub unsafe extern "C" fn patterns( } #[unsafe(naked)] -pub unsafe extern "C" fn inc(a: u32) -> u32 { +pub extern "C" fn inc(a: u32) -> u32 { //~^ ERROR naked functions must contain a single `naked_asm!` invocation a + 1 //~^ ERROR referencing function parameters is not allowed in naked functions @@ -43,19 +43,19 @@ pub unsafe extern "C" fn inc(a: u32) -> u32 { #[unsafe(naked)] #[allow(asm_sub_register)] -pub unsafe extern "C" fn inc_asm(a: u32) -> u32 { +pub extern "C" fn inc_asm(a: u32) -> u32 { naked_asm!("/* {0} */", in(reg) a) //~^ ERROR the `in` operand cannot be used with `naked_asm!` } #[unsafe(naked)] -pub unsafe extern "C" fn inc_closure(a: u32) -> u32 { +pub extern "C" fn inc_closure(a: u32) -> u32 { //~^ ERROR naked functions must contain a single `naked_asm!` invocation (|| a + 1)() } #[unsafe(naked)] -pub unsafe extern "C" fn unsupported_operands() { +pub extern "C" fn unsupported_operands() { //~^ ERROR naked functions must contain a single `naked_asm!` invocation let mut a = 0usize; let mut b = 0usize; @@ -84,11 +84,10 @@ pub extern "C" fn missing_assembly() { #[unsafe(naked)] pub extern "C" fn too_many_asm_blocks() { //~^ ERROR naked functions must contain a single `naked_asm!` invocation - unsafe { - naked_asm!("", options(noreturn)); - //~^ ERROR the `noreturn` option cannot be used with `naked_asm!` - naked_asm!(""); - } + + naked_asm!("", options(noreturn)); + //~^ ERROR the `noreturn` option cannot be used with `naked_asm!` + naked_asm!(""); } pub fn outer(x: u32) -> extern "C" fn(usize) -> usize { @@ -124,49 +123,44 @@ unsafe extern "C" fn invalid_may_unwind() { #[unsafe(naked)] pub extern "C" fn valid_a() -> T { - unsafe { - naked_asm!(""); - } + naked_asm!(""); } #[unsafe(naked)] pub extern "C" fn valid_b() { - unsafe { + { { - { - naked_asm!(""); - }; + naked_asm!(""); }; - } + }; } #[unsafe(naked)] -pub unsafe extern "C" fn valid_c() { +pub extern "C" fn valid_c() { naked_asm!(""); } #[cfg(target_arch = "x86_64")] #[unsafe(naked)] -pub unsafe extern "C" fn valid_att_syntax() { +pub extern "C" fn valid_att_syntax() { naked_asm!("", options(att_syntax)); } #[unsafe(naked)] -#[unsafe(naked)] -pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 { +pub extern "C" fn allow_compile_error(a: u32) -> u32 { compile_error!("this is a user specified error") //~^ ERROR this is a user specified error } #[unsafe(naked)] -pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 { +pub extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 { compile_error!("this is a user specified error"); //~^ ERROR this is a user specified error naked_asm!("") } #[unsafe(naked)] -pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 { +pub extern "C" fn invalid_asm_syntax(a: u32) -> u32 { naked_asm!(invalid_syntax) //~^ ERROR asm template must be a string literal } @@ -174,7 +168,7 @@ pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 { #[cfg(target_arch = "x86_64")] #[cfg_attr(target_pointer_width = "64", no_mangle)] #[unsafe(naked)] -pub unsafe extern "C" fn compatible_cfg_attributes() { +pub extern "C" fn compatible_cfg_attributes() { naked_asm!("", options(att_syntax)); } @@ -183,20 +177,20 @@ pub unsafe extern "C" fn compatible_cfg_attributes() { #[deny(dead_code)] #[forbid(dead_code)] #[unsafe(naked)] -pub unsafe extern "C" fn compatible_diagnostic_attributes() { +pub extern "C" fn compatible_diagnostic_attributes() { naked_asm!("", options(raw)); } #[deprecated = "test"] #[unsafe(naked)] -pub unsafe extern "C" fn compatible_deprecated_attributes() { +pub extern "C" fn compatible_deprecated_attributes() { naked_asm!("", options(raw)); } #[cfg(target_arch = "x86_64")] #[must_use] #[unsafe(naked)] -pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 { +pub extern "C" fn compatible_must_use_attributes() -> u64 { naked_asm!( " mov rax, 42 @@ -208,13 +202,13 @@ pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 { #[export_name = "exported_function_name"] #[link_section = ".custom_section"] #[unsafe(naked)] -pub unsafe extern "C" fn compatible_ffi_attributes_1() { +pub extern "C" fn compatible_ffi_attributes_1() { naked_asm!("", options(raw)); } #[cold] #[unsafe(naked)] -pub unsafe extern "C" fn compatible_codegen_attributes() { +pub extern "C" fn compatible_codegen_attributes() { naked_asm!("", options(raw)); } @@ -223,12 +217,12 @@ pub unsafe extern "C" fn compatible_codegen_attributes() { // a normal comment #[doc(alias = "ADocAlias")] #[unsafe(naked)] -pub unsafe extern "C" fn compatible_doc_attributes() { +pub extern "C" fn compatible_doc_attributes() { naked_asm!("", options(raw)); } #[linkage = "external"] #[unsafe(naked)] -pub unsafe extern "C" fn compatible_linkage() { +pub extern "C" fn compatible_linkage() { naked_asm!("", options(raw)); } diff --git a/tests/ui/asm/naked-functions.stderr b/tests/ui/asm/naked-functions.stderr index 0a55bb9cd8370..2b67c3aecd73c 100644 --- a/tests/ui/asm/naked-functions.stderr +++ b/tests/ui/asm/naked-functions.stderr @@ -11,70 +11,70 @@ LL | in(reg) a, | ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it error: the `noreturn` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:88:32 + --> $DIR/naked-functions.rs:88:28 | -LL | naked_asm!("", options(noreturn)); - | ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly +LL | naked_asm!("", options(noreturn)); + | ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly error: the `nomem` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:106:28 + --> $DIR/naked-functions.rs:105:28 | LL | naked_asm!("", options(nomem, preserves_flags)); | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly error: the `preserves_flags` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:106:35 + --> $DIR/naked-functions.rs:105:35 | LL | naked_asm!("", options(nomem, preserves_flags)); | ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly error: the `readonly` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:113:28 + --> $DIR/naked-functions.rs:112:28 | LL | naked_asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly error: the `nostack` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:113:38 + --> $DIR/naked-functions.rs:112:38 | LL | naked_asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly error: the `pure` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:113:56 + --> $DIR/naked-functions.rs:112:56 | LL | naked_asm!("", options(readonly, nostack), options(pure)); | ^^^^ the `pure` option is not meaningful for global-scoped inline assembly error: the `may_unwind` option cannot be used with `naked_asm!` - --> $DIR/naked-functions.rs:121:28 + --> $DIR/naked-functions.rs:120:28 | LL | naked_asm!("", options(may_unwind)); | ^^^^^^^^^^ the `may_unwind` option is not meaningful for global-scoped inline assembly error: this is a user specified error - --> $DIR/naked-functions.rs:157:5 + --> $DIR/naked-functions.rs:151:5 | LL | compile_error!("this is a user specified error") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this is a user specified error - --> $DIR/naked-functions.rs:163:5 + --> $DIR/naked-functions.rs:157:5 | LL | compile_error!("this is a user specified error"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/naked-functions.rs:170:16 + --> $DIR/naked-functions.rs:164:16 | LL | naked_asm!(invalid_syntax) | ^^^^^^^^^^^^^^ error[E0787]: the `asm!` macro is not allowed in naked functions - --> $DIR/naked-functions.rs:13:5 + --> $DIR/naked-functions.rs:13:14 | -LL | asm!("", options(raw)); - | ^^^^^^^^^^^^^^^^^^^^^^ consider using the `naked_asm!` macro instead +LL | unsafe { asm!("", options(raw)) }; + | ^^^^^^^^^^^^^^^^^^^^^^ consider using the `naked_asm!` macro instead error: patterns not allowed in naked function parameters --> $DIR/naked-functions.rs:25:5 @@ -111,8 +111,8 @@ LL | a + 1 error[E0787]: naked functions must contain a single `naked_asm!` invocation --> $DIR/naked-functions.rs:38:1 | -LL | pub unsafe extern "C" fn inc(a: u32) -> u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub extern "C" fn inc(a: u32) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | a + 1 | ----- not allowed in naked functions @@ -120,8 +120,8 @@ LL | a + 1 error[E0787]: naked functions must contain a single `naked_asm!` invocation --> $DIR/naked-functions.rs:52:1 | -LL | pub unsafe extern "C" fn inc_closure(a: u32) -> u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub extern "C" fn inc_closure(a: u32) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | (|| a + 1)() | ------------ not allowed in naked functions @@ -129,8 +129,8 @@ LL | (|| a + 1)() error[E0787]: naked functions must contain a single `naked_asm!` invocation --> $DIR/naked-functions.rs:58:1 | -LL | pub unsafe extern "C" fn unsupported_operands() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub extern "C" fn unsupported_operands() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | let mut a = 0usize; | ------------------- not allowed in naked functions @@ -155,11 +155,11 @@ error[E0787]: naked functions must contain a single `naked_asm!` invocation LL | pub extern "C" fn too_many_asm_blocks() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... -LL | naked_asm!(""); - | -------------- multiple `naked_asm!` invocations are not allowed in naked functions +LL | naked_asm!(""); + | -------------- multiple `naked_asm!` invocations are not allowed in naked functions error: referencing function parameters is not allowed in naked functions - --> $DIR/naked-functions.rs:98:11 + --> $DIR/naked-functions.rs:97:11 | LL | *&y | ^ @@ -167,7 +167,7 @@ LL | *&y = help: follow the calling convention in asm block to use parameters error[E0787]: naked functions must contain a single `naked_asm!` invocation - --> $DIR/naked-functions.rs:96:5 + --> $DIR/naked-functions.rs:95:5 | LL | pub extern "C" fn inner(y: usize) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/naked-invalid-attr.rs b/tests/ui/asm/naked-invalid-attr.rs index 4053c58fb5136..6c5fdbe74d82a 100644 --- a/tests/ui/asm/naked-invalid-attr.rs +++ b/tests/ui/asm/naked-invalid-attr.rs @@ -1,17 +1,17 @@ -// Checks that #[naked] attribute can be placed on function definitions only. +// Checks that #[unsafe(naked)] attribute can be placed on function definitions only. // //@ needs-asm-support #![feature(naked_functions)] -#![naked] //~ ERROR should be applied to a function definition +#![unsafe(naked)] //~ ERROR should be applied to a function definition use std::arch::naked_asm; extern "C" { - #[naked] //~ ERROR should be applied to a function definition + #[unsafe(naked)] //~ ERROR should be applied to a function definition fn f(); } -#[naked] //~ ERROR should be applied to a function definition +#[unsafe(naked)] //~ ERROR should be applied to a function definition #[repr(C)] struct S { a: u32, @@ -19,35 +19,35 @@ struct S { } trait Invoke { - #[naked] //~ ERROR should be applied to a function definition + #[unsafe(naked)] //~ ERROR should be applied to a function definition extern "C" fn invoke(&self); } impl Invoke for S { - #[naked] + #[unsafe(naked)] extern "C" fn invoke(&self) { - unsafe { naked_asm!("") } + naked_asm!("") } } -#[naked] +#[unsafe(naked)] extern "C" fn ok() { - unsafe { naked_asm!("") } + naked_asm!("") } impl S { - #[naked] + #[unsafe(naked)] extern "C" fn g() { - unsafe { naked_asm!("") } + naked_asm!("") } - #[naked] + #[unsafe(naked)] extern "C" fn h(&self) { - unsafe { naked_asm!("") } + naked_asm!("") } } fn main() { - #[naked] //~ ERROR should be applied to a function definition + #[unsafe(naked)] //~ ERROR should be applied to a function definition || {}; } diff --git a/tests/ui/asm/naked-invalid-attr.stderr b/tests/ui/asm/naked-invalid-attr.stderr index 640f9d9510d15..6e2746b568437 100644 --- a/tests/ui/asm/naked-invalid-attr.stderr +++ b/tests/ui/asm/naked-invalid-attr.stderr @@ -1,8 +1,8 @@ error: attribute should be applied to a function definition --> $DIR/naked-invalid-attr.rs:14:1 | -LL | #[naked] - | ^^^^^^^^ +LL | #[unsafe(naked)] + | ^^^^^^^^^^^^^^^^ LL | #[repr(C)] LL | / struct S { LL | | a: u32, @@ -13,32 +13,32 @@ LL | | } error: attribute should be applied to a function definition --> $DIR/naked-invalid-attr.rs:51:5 | -LL | #[naked] - | ^^^^^^^^ +LL | #[unsafe(naked)] + | ^^^^^^^^^^^^^^^^ LL | || {}; | ----- not a function definition error: attribute should be applied to a function definition --> $DIR/naked-invalid-attr.rs:22:5 | -LL | #[naked] - | ^^^^^^^^ +LL | #[unsafe(naked)] + | ^^^^^^^^^^^^^^^^ LL | extern "C" fn invoke(&self); | ---------------------------- not a function definition error: attribute should be applied to a function definition --> $DIR/naked-invalid-attr.rs:10:5 | -LL | #[naked] - | ^^^^^^^^ +LL | #[unsafe(naked)] + | ^^^^^^^^^^^^^^^^ LL | fn f(); | ------- not a function definition error: attribute should be applied to a function definition --> $DIR/naked-invalid-attr.rs:5:1 | -LL | #![naked] - | ^^^^^^^^^ cannot be applied to crates +LL | #![unsafe(naked)] + | ^^^^^^^^^^^^^^^^^ cannot be applied to crates error: aborting due to 5 previous errors diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.rs b/tests/ui/asm/naked-with-invalid-repr-attr.rs index 18b9c1014c3fa..c9f335ea9506a 100644 --- a/tests/ui/asm/naked-with-invalid-repr-attr.rs +++ b/tests/ui/asm/naked-with-invalid-repr-attr.rs @@ -6,43 +6,43 @@ use std::arch::naked_asm; #[repr(C)] //~^ ERROR attribute should be applied to a struct, enum, or union [E0517] -#[naked] +#[unsafe(naked)] extern "C" fn example1() { //~^ NOTE not a struct, enum, or union - unsafe { naked_asm!("") } + naked_asm!("") } #[repr(transparent)] //~^ ERROR attribute should be applied to a struct, enum, or union [E0517] -#[naked] +#[unsafe(naked)] extern "C" fn example2() { //~^ NOTE not a struct, enum, or union - unsafe { naked_asm!("") } + naked_asm!("") } #[repr(align(16), C)] //~^ ERROR attribute should be applied to a struct, enum, or union [E0517] -#[naked] +#[unsafe(naked)] extern "C" fn example3() { //~^ NOTE not a struct, enum, or union - unsafe { naked_asm!("") } + naked_asm!("") } // note: two errors because of packed and C #[repr(C, packed)] //~^ ERROR attribute should be applied to a struct or union [E0517] //~| ERROR attribute should be applied to a struct, enum, or union [E0517] -#[naked] +#[unsafe(naked)] extern "C" fn example4() { //~^ NOTE not a struct, enum, or union //~| NOTE not a struct or union - unsafe { naked_asm!("") } + naked_asm!("") } #[repr(u8)] //~^ ERROR attribute should be applied to an enum [E0517] -#[naked] +#[unsafe(naked)] extern "C" fn example5() { //~^ NOTE not an enum - unsafe { naked_asm!("") } + naked_asm!("") } diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.stderr b/tests/ui/asm/naked-with-invalid-repr-attr.stderr index 8248a8c165791..219e32473beaa 100644 --- a/tests/ui/asm/naked-with-invalid-repr-attr.stderr +++ b/tests/ui/asm/naked-with-invalid-repr-attr.stderr @@ -6,7 +6,7 @@ LL | #[repr(C)] ... LL | / extern "C" fn example1() { LL | | -LL | | unsafe { naked_asm!("") } +LL | | naked_asm!("") LL | | } | |_- not a struct, enum, or union @@ -18,7 +18,7 @@ LL | #[repr(transparent)] ... LL | / extern "C" fn example2() { LL | | -LL | | unsafe { naked_asm!("") } +LL | | naked_asm!("") LL | | } | |_- not a struct, enum, or union @@ -30,7 +30,7 @@ LL | #[repr(align(16), C)] ... LL | / extern "C" fn example3() { LL | | -LL | | unsafe { naked_asm!("") } +LL | | naked_asm!("") LL | | } | |_- not a struct, enum, or union @@ -43,7 +43,7 @@ LL | #[repr(C, packed)] LL | / extern "C" fn example4() { LL | | LL | | -LL | | unsafe { naked_asm!("") } +LL | | naked_asm!("") LL | | } | |_- not a struct, enum, or union @@ -56,7 +56,7 @@ LL | #[repr(C, packed)] LL | / extern "C" fn example4() { LL | | LL | | -LL | | unsafe { naked_asm!("") } +LL | | naked_asm!("") LL | | } | |_- not a struct or union @@ -68,7 +68,7 @@ LL | #[repr(u8)] ... LL | / extern "C" fn example5() { LL | | -LL | | unsafe { naked_asm!("") } +LL | | naked_asm!("") LL | | } | |_- not an enum diff --git a/tests/ui/asm/named-asm-labels.rs b/tests/ui/asm/named-asm-labels.rs index 77831e679ed42..d5c194452d75b 100644 --- a/tests/ui/asm/named-asm-labels.rs +++ b/tests/ui/asm/named-asm-labels.rs @@ -175,9 +175,9 @@ fn main() { // Trigger on naked fns too, even though they can't be inlined, reusing a // label or LTO can cause labels to break -#[naked] +#[unsafe(naked)] pub extern "C" fn foo() -> i32 { - unsafe { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) } + naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) //~^ ERROR avoid using named labels } @@ -188,21 +188,21 @@ pub extern "C" fn bar() { //~^ ERROR avoid using named labels } -#[naked] +#[unsafe(naked)] pub extern "C" fn aaa() { fn _local() {} - unsafe { naked_asm!(".Laaa: nop; ret;") } //~ ERROR avoid using named labels + naked_asm!(".Laaa: nop; ret;") //~ ERROR avoid using named labels } pub fn normal() { fn _local1() {} - #[naked] + #[unsafe(naked)] pub extern "C" fn bbb() { fn _very_local() {} - unsafe { naked_asm!(".Lbbb: nop; ret;") } //~ ERROR avoid using named labels + naked_asm!(".Lbbb: nop; ret;") //~ ERROR avoid using named labels } fn _local2() {} @@ -219,8 +219,8 @@ fn closures() { }; || { - #[naked] - unsafe extern "C" fn _nested() { + #[unsafe(naked)] + extern "C" fn _nested() { naked_asm!("ret;"); } diff --git a/tests/ui/asm/named-asm-labels.stderr b/tests/ui/asm/named-asm-labels.stderr index 44ce358c62bdb..0120d4948d51c 100644 --- a/tests/ui/asm/named-asm-labels.stderr +++ b/tests/ui/asm/named-asm-labels.stderr @@ -475,10 +475,10 @@ LL | #[warn(named_asm_labels)] | ^^^^^^^^^^^^^^^^ error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:180:26 + --> $DIR/named-asm-labels.rs:180:17 | -LL | unsafe { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) } - | ^^^^^ +LL | naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) + | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm = note: see the asm section of Rust By Example for more information @@ -493,19 +493,19 @@ LL | unsafe { asm!(".Lbar: mov rax, {}; ret;", "nop", const 1, options(noret = note: see the asm section of Rust By Example for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:195:26 + --> $DIR/named-asm-labels.rs:195:17 | -LL | unsafe { naked_asm!(".Laaa: nop; ret;") } - | ^^^^^ +LL | naked_asm!(".Laaa: nop; ret;") + | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm = note: see the asm section of Rust By Example for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:205:30 + --> $DIR/named-asm-labels.rs:205:21 | -LL | unsafe { naked_asm!(".Lbbb: nop; ret;") } - | ^^^^^ +LL | naked_asm!(".Lbbb: nop; ret;") + | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm = note: see the asm section of Rust By Example for more information diff --git a/tests/ui/feature-gates/feature-gate-naked_functions.rs b/tests/ui/feature-gates/feature-gate-naked_functions.rs index 77a67e0696eb2..d940decd561e9 100644 --- a/tests/ui/feature-gates/feature-gate-naked_functions.rs +++ b/tests/ui/feature-gates/feature-gate-naked_functions.rs @@ -3,20 +3,18 @@ use std::arch::naked_asm; //~^ ERROR use of unstable library feature `naked_functions` -#[naked] +#[naked] //~ ERROR unsafe attribute used without unsafe //~^ ERROR the `#[naked]` attribute is an experimental feature extern "C" fn naked() { naked_asm!("") //~^ ERROR use of unstable library feature `naked_functions` - //~| ERROR: requires unsafe } -#[naked] +#[naked] //~ ERROR unsafe attribute used without unsafe //~^ ERROR the `#[naked]` attribute is an experimental feature extern "C" fn naked_2() -> isize { naked_asm!("") //~^ ERROR use of unstable library feature `naked_functions` - //~| ERROR: requires unsafe } fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-naked_functions.stderr b/tests/ui/feature-gates/feature-gate-naked_functions.stderr index 9bfb9275bb201..ea765db7d946e 100644 --- a/tests/ui/feature-gates/feature-gate-naked_functions.stderr +++ b/tests/ui/feature-gates/feature-gate-naked_functions.stderr @@ -9,7 +9,7 @@ LL | naked_asm!("") = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `naked_functions` - --> $DIR/feature-gate-naked_functions.rs:17:5 + --> $DIR/feature-gate-naked_functions.rs:16:5 | LL | naked_asm!("") | ^^^^^^^^^ @@ -18,6 +18,28 @@ LL | naked_asm!("") = help: add `#![feature(naked_functions)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error: unsafe attribute used without unsafe + --> $DIR/feature-gate-naked_functions.rs:6:3 + | +LL | #[naked] + | ^^^^^ usage of unsafe attribute + | +help: wrap the attribute in `unsafe(...)` + | +LL | #[unsafe(naked)] + | +++++++ + + +error: unsafe attribute used without unsafe + --> $DIR/feature-gate-naked_functions.rs:13:3 + | +LL | #[naked] + | ^^^^^ usage of unsafe attribute + | +help: wrap the attribute in `unsafe(...)` + | +LL | #[unsafe(naked)] + | +++++++ + + error[E0658]: the `#[naked]` attribute is an experimental feature --> $DIR/feature-gate-naked_functions.rs:6:1 | @@ -29,7 +51,7 @@ LL | #[naked] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the `#[naked]` attribute is an experimental feature - --> $DIR/feature-gate-naked_functions.rs:14:1 + --> $DIR/feature-gate-naked_functions.rs:13:1 | LL | #[naked] | ^^^^^^^^ @@ -48,23 +70,6 @@ LL | use std::arch::naked_asm; = help: add `#![feature(naked_functions)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0133]: use of inline assembly is unsafe and requires unsafe function or block - --> $DIR/feature-gate-naked_functions.rs:9:5 - | -LL | naked_asm!("") - | ^^^^^^^^^^^^^^ use of inline assembly - | - = note: inline assembly is entirely unchecked and can cause undefined behavior - -error[E0133]: use of inline assembly is unsafe and requires unsafe function or block - --> $DIR/feature-gate-naked_functions.rs:17:5 - | -LL | naked_asm!("") - | ^^^^^^^^^^^^^^ use of inline assembly - | - = note: inline assembly is entirely unchecked and can cause undefined behavior - error: aborting due to 7 previous errors -Some errors have detailed explanations: E0133, E0658. -For more information about an error, try `rustc --explain E0133`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs index c91d833994414..cc5b4f0e88b42 100644 --- a/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs +++ b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs @@ -5,19 +5,19 @@ use std::arch::naked_asm; -#[naked] +#[unsafe(naked)] pub unsafe fn rust_implicit() { //~^ ERROR `#[naked]` is currently unstable on `extern "Rust"` functions naked_asm!("ret"); } -#[naked] +#[unsafe(naked)] pub unsafe extern "Rust" fn rust_explicit() { //~^ ERROR `#[naked]` is currently unstable on `extern "Rust"` functions naked_asm!("ret"); } -#[naked] +#[unsafe(naked)] pub unsafe extern "rust-cold" fn rust_cold() { //~^ ERROR `#[naked]` is currently unstable on `extern "rust-cold"` functions naked_asm!("ret"); diff --git a/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs b/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs index 0d3af4c5fe0a4..b2e102f1db4b6 100644 --- a/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs +++ b/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs @@ -5,7 +5,7 @@ use std::arch::naked_asm; -#[naked] +#[unsafe(naked)] #[target_feature(enable = "avx2")] //~^ ERROR: `#[target_feature(/* ... */)]` is currently unstable on `#[naked]` functions extern "C" fn naked() { diff --git a/tests/ui/lint/break-with-label-and-unsafe-block.rs b/tests/ui/lint/break-with-label-and-unsafe-block.rs new file mode 100644 index 0000000000000..a76a576147556 --- /dev/null +++ b/tests/ui/lint/break-with-label-and-unsafe-block.rs @@ -0,0 +1,11 @@ +//@ check-pass + +#![deny(break_with_label_and_loop)] + +unsafe fn foo() -> i32 { 42 } + +fn main () { + 'label: loop { + break 'label unsafe { foo() } + }; +} diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs index 0e85515fd104a..ce6d10bf33cbd 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs +++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs @@ -5,7 +5,7 @@ use std::arch::naked_asm; #[track_caller] //~ ERROR [E0736] //~^ ERROR `#[track_caller]` requires Rust ABI -#[naked] +#[unsafe(naked)] extern "C" fn f() { unsafe { naked_asm!(""); @@ -17,7 +17,7 @@ struct S; impl S { #[track_caller] //~ ERROR [E0736] //~^ ERROR `#[track_caller]` requires Rust ABI - #[naked] + #[unsafe(naked)] extern "C" fn g() { unsafe { naked_asm!(""); diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr index 0625ed1183ba5..f89d94b67d806 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr +++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr @@ -1,20 +1,20 @@ -error[E0736]: attribute incompatible with `#[naked]` +error[E0736]: attribute incompatible with `#[unsafe(naked)]` --> $DIR/error-with-naked.rs:6:1 | LL | #[track_caller] - | ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]` + | ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[unsafe(naked)]` LL | -LL | #[naked] - | -------- function marked with `#[naked]` here +LL | #[unsafe(naked)] + | ---------------- function marked with `#[unsafe(naked)]` here -error[E0736]: attribute incompatible with `#[naked]` +error[E0736]: attribute incompatible with `#[unsafe(naked)]` --> $DIR/error-with-naked.rs:18:5 | LL | #[track_caller] - | ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]` + | ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[unsafe(naked)]` LL | -LL | #[naked] - | -------- function marked with `#[naked]` here +LL | #[unsafe(naked)] + | ---------------- function marked with `#[unsafe(naked)]` here error[E0737]: `#[track_caller]` requires Rust ABI --> $DIR/error-with-naked.rs:6:1