From 444a7eb5aa9772d2d4363956bdfac8315e47d739 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Apr 2025 03:36:04 +0000 Subject: Use return_result_from_ensure_ok a bit more --- compiler/rustc_interface/src/passes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler/rustc_interface/src') diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 93013c8b3f6..747e36b6a1a 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -976,7 +976,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { tcx.par_hir_body_owners(|def_id| { if tcx.is_coroutine(def_id.to_def_id()) { tcx.ensure_ok().mir_coroutine_witnesses(def_id); - tcx.ensure_ok().check_coroutine_obligations( + let _ = tcx.ensure_ok().check_coroutine_obligations( tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(), ); // Eagerly check the unsubstituted layout for cycles. -- cgit 1.4.1-3-g733a5 From 3df2acd31ba14544ddb7fb1b0e73e6235824d4a3 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 21 Mar 2025 05:09:57 +0000 Subject: Allow boolean literals in `check-cfg` --- compiler/rustc_ast/src/attr/mod.rs | 8 ++++++++ compiler/rustc_interface/src/interface.rs | 8 ++++++++ tests/ui/cfg/raw-true-false.rs | 24 ++++++++-------------- .../ui/check-cfg/invalid-arguments.boolean.stderr | 6 ------ .../invalid-arguments.boolean_after_values.stderr | 5 +++++ tests/ui/check-cfg/invalid-arguments.rs | 4 ++-- 6 files changed, 31 insertions(+), 24 deletions(-) delete mode 100644 tests/ui/check-cfg/invalid-arguments.boolean.stderr create mode 100644 tests/ui/check-cfg/invalid-arguments.boolean_after_values.stderr (limited to 'compiler/rustc_interface/src') diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 4d613085d79..0b65246693d 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -570,6 +570,14 @@ impl MetaItemInner { } } + /// Returns the bool if `self` is a boolean `MetaItemInner::Literal`. + pub fn boolean_literal(&self) -> Option { + match self { + MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => Some(*b), + _ => None, + } + } + /// Returns the `MetaItem` if `self` is a `MetaItemInner::MetaItem` or if it's /// `MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(_), .. })`. pub fn meta_item_or_bool(&self) -> Option<&MetaItemInner> { diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 3f87b1a547b..33b4a48b28d 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -204,6 +204,14 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec) -> Ch error!("`cfg()` names cannot be after values"); } names.push(ident); + } else if let Some(boolean) = arg.boolean_literal() { + if values_specified { + error!("`cfg()` names cannot be after values"); + } + names.push(rustc_span::Ident::new( + if boolean { rustc_span::kw::True } else { rustc_span::kw::False }, + arg.span(), + )); } else if arg.has_name(sym::any) && let Some(args) = arg.meta_item_list() { diff --git a/tests/ui/cfg/raw-true-false.rs b/tests/ui/cfg/raw-true-false.rs index 4cb8bb71c92..c92672fc144 100644 --- a/tests/ui/cfg/raw-true-false.rs +++ b/tests/ui/cfg/raw-true-false.rs @@ -1,19 +1,11 @@ //@ check-pass -//@ compile-flags: --cfg false --check-cfg=cfg(r#false) - -#![deny(warnings)] - -#[expect(unexpected_cfgs)] -mod a { - #[cfg(r#true)] - pub fn foo() {} -} - -mod b { - #[cfg(r#false)] - pub fn bar() {} -} - +//@ revisions: r0x0 r0x1 r1x0 r1x1 +//@[r0x0] compile-flags: --cfg false --check-cfg=cfg(false) +//@[r0x1] compile-flags: --cfg false --check-cfg=cfg(r#false) +//@[r1x0] compile-flags: --cfg r#false --check-cfg=cfg(false) +//@[r1x1] compile-flags: --cfg r#false --check-cfg=cfg(r#false) +#![deny(unexpected_cfgs)] fn main() { - b::bar() + #[cfg(not(r#false))] + compile_error!(""); } diff --git a/tests/ui/check-cfg/invalid-arguments.boolean.stderr b/tests/ui/check-cfg/invalid-arguments.boolean.stderr deleted file mode 100644 index 18734de9dac..00000000000 --- a/tests/ui/check-cfg/invalid-arguments.boolean.stderr +++ /dev/null @@ -1,6 +0,0 @@ -error: invalid `--check-cfg` argument: `cfg(true)` - | - = note: `true` is a boolean literal - = note: `cfg()` arguments must be simple identifiers, `any()` or `values(...)` - = note: visit for more details - diff --git a/tests/ui/check-cfg/invalid-arguments.boolean_after_values.stderr b/tests/ui/check-cfg/invalid-arguments.boolean_after_values.stderr new file mode 100644 index 00000000000..3aa2205d3b1 --- /dev/null +++ b/tests/ui/check-cfg/invalid-arguments.boolean_after_values.stderr @@ -0,0 +1,5 @@ +error: invalid `--check-cfg` argument: `cfg(values(),true)` + | + = note: `values()` cannot be specified before the names + = note: visit for more details + diff --git a/tests/ui/check-cfg/invalid-arguments.rs b/tests/ui/check-cfg/invalid-arguments.rs index c6b1218ce27..229fb83c3fc 100644 --- a/tests/ui/check-cfg/invalid-arguments.rs +++ b/tests/ui/check-cfg/invalid-arguments.rs @@ -2,7 +2,7 @@ // //@ check-fail //@ no-auto-check-cfg -//@ revisions: anything_else boolean +//@ revisions: anything_else boolean_after_values //@ revisions: string_for_name_1 string_for_name_2 multiple_any multiple_values //@ revisions: multiple_values_any not_empty_any not_empty_values_any //@ revisions: values_any_missing_values values_any_before_ident ident_in_values_1 @@ -11,7 +11,7 @@ //@ revisions: none_not_empty cfg_none unsafe_attr // //@ [anything_else]compile-flags: --check-cfg=anything_else(...) -//@ [boolean]compile-flags: --check-cfg=cfg(true) +//@ [boolean_after_values]compile-flags: --check-cfg=cfg(values(),true) //@ [string_for_name_1]compile-flags: --check-cfg=cfg("NOT_IDENT") //@ [string_for_name_2]compile-flags: --check-cfg=cfg(foo,"NOT_IDENT",bar) //@ [multiple_any]compile-flags: --check-cfg=cfg(any(),any()) -- cgit 1.4.1-3-g733a5 From a98546b961a7fc707155aecbde094fbcecce81fd Mon Sep 17 00:00:00 2001 From: Ramon de C Valle Date: Tue, 11 Mar 2025 19:04:35 +0000 Subject: KCFI: Add KCFI arity indicator support Adds KCFI arity indicator support to the Rust compiler (see rust-lang/rust#138311, https://github.com/llvm/llvm-project/pull/121070, and https://lore.kernel.org/lkml/CANiq72=3ghFxy8E=AU9p+0imFxKr5iU3sd0hVUXed5BA+KjdNQ@mail.gmail.com/). --- compiler/rustc_codegen_llvm/messages.ftl | 2 + compiler/rustc_codegen_llvm/src/context.rs | 16 ++++++ compiler/rustc_codegen_llvm/src/errors.rs | 4 ++ compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_session/messages.ftl | 2 + compiler/rustc_session/src/errors.rs | 4 ++ compiler/rustc_session/src/options.rs | 2 + compiler/rustc_session/src/session.rs | 9 ++++ .../sanitizer/kcfi/emit-arity-indicator.rs | 61 ++++++++++++++++++++++ .../codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs | 19 +++++++ tests/ui/sanitizer/kcfi-arity-requires-kcfi.rs | 9 ++++ tests/ui/sanitizer/kcfi-arity-requires-kcfi.stderr | 4 ++ .../sanitizer/kcfi-arity-requires-llvm-21-0-0.rs | 11 ++++ .../kcfi-arity-requires-llvm-21-0-0.stderr | 4 ++ 14 files changed, 148 insertions(+) create mode 100644 tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs create mode 100644 tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs create mode 100644 tests/ui/sanitizer/kcfi-arity-requires-kcfi.rs create mode 100644 tests/ui/sanitizer/kcfi-arity-requires-kcfi.stderr create mode 100644 tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs create mode 100644 tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr (limited to 'compiler/rustc_interface/src') diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index 17f2e7ca9f7..41391b096cc 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -56,6 +56,8 @@ codegen_llvm_prepare_thin_lto_module_with_llvm_err = failed to prepare thin LTO codegen_llvm_run_passes = failed to run LLVM passes codegen_llvm_run_passes_with_llvm_err = failed to run LLVM passes: {$llvm_err} +codegen_llvm_sanitizer_kcfi_arity_requires_llvm_21_0_0 = `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later. + codegen_llvm_sanitizer_memtag_requires_mte = `-Zsanitizer=memtag` requires `-Ctarget-feature=+mte` diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index f7b096ff976..ad98e506690 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -327,6 +327,22 @@ pub(crate) unsafe fn create_module<'ll>( pfe.prefix().into(), ); } + + // Add "kcfi-arity" module flag if KCFI arity indicator is enabled. (See + // https://github.com/llvm/llvm-project/pull/117121.) + if sess.is_sanitizer_kcfi_arity_enabled() { + // KCFI arity indicator requires LLVM 21.0.0 or later. + if llvm_version < (21, 0, 0) { + tcx.dcx().emit_err(crate::errors::SanitizerKcfiArityRequiresLLVM2100); + } + + llvm::add_module_flag_u32( + llmod, + llvm::ModuleFlagMergeBehavior::Override, + "kcfi-arity", + 1, + ); + } } // Control Flow Guard is currently only supported by MSVC and LLVM on Windows. diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 4c5a78ca74f..ecf108f988f 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -217,3 +217,7 @@ pub(crate) struct MismatchedDataLayout<'a> { pub(crate) struct FixedX18InvalidArch<'a> { pub arch: &'a str, } + +#[derive(Diagnostic)] +#[diag(codegen_llvm_sanitizer_kcfi_arity_requires_llvm_21_0_0)] +pub(crate) struct SanitizerKcfiArityRequiresLLVM2100; diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 4592e014438..a8e55663257 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -853,6 +853,7 @@ fn test_unstable_options_tracking_hash() { tracked!(sanitizer_cfi_generalize_pointers, Some(true)); tracked!(sanitizer_cfi_normalize_integers, Some(true)); tracked!(sanitizer_dataflow_abilist, vec![String::from("/rustc/abc")]); + tracked!(sanitizer_kcfi_arity, Some(true)); tracked!(sanitizer_memory_track_origins, 2); tracked!(sanitizer_recover, SanitizerSet::ADDRESS); tracked!(saturating_float_casts, Some(true)); diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index 74b8087e077..a0f873f3cf6 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -94,6 +94,8 @@ session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Cli session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1` +session_sanitizer_kcfi_arity_requires_kcfi = `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi` + session_sanitizer_kcfi_requires_panic_abort = `-Z sanitizer=kcfi` requires `-C panic=abort` session_sanitizer_not_supported = {$us} sanitizer is not supported for this target diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 71d8dbe44fe..3979aea70d3 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -147,6 +147,10 @@ pub(crate) struct SanitizerCfiGeneralizePointersRequiresCfi; #[diag(session_sanitizer_cfi_normalize_integers_requires_cfi)] pub(crate) struct SanitizerCfiNormalizeIntegersRequiresCfi; +#[derive(Diagnostic)] +#[diag(session_sanitizer_kcfi_arity_requires_kcfi)] +pub(crate) struct SanitizerKcfiArityRequiresKcfi; + #[derive(Diagnostic)] #[diag(session_sanitizer_kcfi_requires_panic_abort)] pub(crate) struct SanitizerKcfiRequiresPanicAbort; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 4f544d2c16b..720bc3f61e4 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2443,6 +2443,8 @@ written to standard error output)"), "enable normalizing integer types (default: no)"), sanitizer_dataflow_abilist: Vec = (Vec::new(), parse_comma_list, [TRACKED], "additional ABI list files that control how shadow parameters are passed (comma separated)"), + sanitizer_kcfi_arity: Option = (None, parse_opt_bool, [TRACKED], + "enable KCFI arity indicator (default: no)"), sanitizer_memory_track_origins: usize = (0, parse_sanitizer_memory_track_origins, [TRACKED], "enable origins tracking in MemorySanitizer"), sanitizer_recover: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index a87b1961a99..2c6b6eb619b 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -381,6 +381,10 @@ impl Session { self.opts.unstable_opts.sanitizer_cfi_normalize_integers == Some(true) } + pub fn is_sanitizer_kcfi_arity_enabled(&self) -> bool { + self.opts.unstable_opts.sanitizer_kcfi_arity == Some(true) + } + pub fn is_sanitizer_kcfi_enabled(&self) -> bool { self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI) } @@ -1211,6 +1215,11 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } } + // KCFI arity indicator requires KCFI. + if sess.is_sanitizer_kcfi_arity_enabled() && !sess.is_sanitizer_kcfi_enabled() { + sess.dcx().emit_err(errors::SanitizerKcfiArityRequiresKcfi); + } + // LLVM CFI pointer generalization requires CFI or KCFI. if sess.is_sanitizer_cfi_generalize_pointers_enabled() { if !(sess.is_sanitizer_cfi_enabled() || sess.is_sanitizer_kcfi_enabled()) { diff --git a/tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs b/tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs new file mode 100644 index 00000000000..b3b623b509b --- /dev/null +++ b/tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs @@ -0,0 +1,61 @@ +// Verifies that KCFI arity indicator is emitted. +// +//@ add-core-stubs +//@ revisions: x86_64 +//@ assembly-output: emit-asm +//@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu -Cllvm-args=-x86-asm-syntax=intel -Ctarget-feature=-crt-static -Cpanic=abort -Zsanitizer=kcfi -Zsanitizer-kcfi-arity -Copt-level=0 +//@ [x86_64] needs-llvm-components: x86 +//@ min-llvm-version: 21.0.0 + +#![crate_type = "lib"] + +pub fn add_one(x: i32) -> i32 { + // CHECK-LABEL: __cfi__{{.*}}7add_one{{.*}}: + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: mov ecx, 2628068948 + x + 1 +} + +pub fn add_two(x: i32, _y: i32) -> i32 { + // CHECK-LABEL: __cfi__{{.*}}7add_two{{.*}}: + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: mov edx, 2505940310 + x + 2 +} + +pub fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: __cfi__{{.*}}8do_twice{{.*}}: + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: nop + // CHECK-NEXT: mov edx, 653723426 + f(arg) + f(arg) +} diff --git a/tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs b/tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs new file mode 100644 index 00000000000..9a2290901d6 --- /dev/null +++ b/tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs @@ -0,0 +1,19 @@ +// Verifies that "kcfi-arity" module flag is added. +// +//@ add-core-stubs +//@ revisions: x86_64 +//@ [x86_64] compile-flags: --target x86_64-unknown-none +//@ [x86_64] needs-llvm-components: x86 +//@ compile-flags: -Ctarget-feature=-crt-static -Cpanic=abort -Zsanitizer=kcfi -Zsanitizer-kcfi-arity +//@ min-llvm-version: 21.0.0 + +#![feature(no_core, lang_items)] +#![crate_type = "lib"] +#![no_core] + +extern crate minicore; +use minicore::*; + +pub fn foo() {} + +// CHECK: !{{[0-9]+}} = !{i32 4, !"kcfi-arity", i32 1} diff --git a/tests/ui/sanitizer/kcfi-arity-requires-kcfi.rs b/tests/ui/sanitizer/kcfi-arity-requires-kcfi.rs new file mode 100644 index 00000000000..12aabb3b862 --- /dev/null +++ b/tests/ui/sanitizer/kcfi-arity-requires-kcfi.rs @@ -0,0 +1,9 @@ +// Verifies that `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`. +// +//@ needs-sanitizer-kcfi +//@ compile-flags: -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer-kcfi-arity + +//~? ERROR `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi` +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/tests/ui/sanitizer/kcfi-arity-requires-kcfi.stderr b/tests/ui/sanitizer/kcfi-arity-requires-kcfi.stderr new file mode 100644 index 00000000000..4ed1b754fd4 --- /dev/null +++ b/tests/ui/sanitizer/kcfi-arity-requires-kcfi.stderr @@ -0,0 +1,4 @@ +error: `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi` + +error: aborting due to 1 previous error + diff --git a/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs new file mode 100644 index 00000000000..8a724b853e1 --- /dev/null +++ b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs @@ -0,0 +1,11 @@ +// Verifies that `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later. +// +//@ needs-sanitizer-kcfi +//@ compile-flags: -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Cpanic=abort -Zsanitizer=kcfi -Zsanitizer-kcfi-arity +//@ build-fail +//@ max-llvm-major-version: 20 + +//~? ERROR `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later. +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr new file mode 100644 index 00000000000..ac6bd7411fd --- /dev/null +++ b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr @@ -0,0 +1,4 @@ +error: `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later. + +error: aborting due to 1 previous error + -- cgit 1.4.1-3-g733a5