diff --git a/Cargo.lock b/Cargo.lock index 5f35ce252b78e..99c2914ff343d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3440,7 +3440,6 @@ name = "replace-version-placeholder" version = "0.1.0" dependencies = [ "tidy", - "walkdir", ] [[package]] diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index abc71f450a515..7fa079a01a6b1 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -2065,17 +2065,24 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { let is_diag = self.tcx.sess.opts.unstable_opts.sanitizer_cfi_diag.unwrap_or(false); let is_recover = self.tcx.sess.opts.unstable_opts.sanitizer_cfi_recover.unwrap_or(false); + let is_minimal = + self.tcx.sess.opts.unstable_opts.sanitizer_cfi_minimal_runtime.unwrap_or(false); if is_diag || is_recover { - let fty = self.cx.type_func( - &[self.cx.type_ptr(), self.cx.type_isize(), self.cx.type_isize()], - self.cx.type_void(), - ); + let fty = if is_minimal { + self.cx.type_func(&[], self.cx.type_void()) + } else { + self.cx.type_func( + &[self.cx.type_ptr(), self.cx.type_isize(), self.cx.type_isize()], + self.cx.type_void(), + ) + }; let ubsan_handler = self.declare_cfn( - if is_recover { - "__ubsan_handle_cfi_check_fail" - } else { - "__ubsan_handle_cfi_check_fail_abort" + match (is_minimal, is_recover) { + (true, true) => "__ubsan_handle_cfi_check_fail_minimal", + (true, false) => "__ubsan_handle_cfi_check_fail_minimal_abort", + (false, true) => "__ubsan_handle_cfi_check_fail", + (false, false) => "__ubsan_handle_cfi_check_fail_abort", }, llvm::UnnamedAddr::Global, fty, @@ -2101,13 +2108,18 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { self.generate_ubsan_cfi_diag_data(self.span, expected_ty, check_kind); let function_address = self.ptrtoint(llfn, self.cx.type_isize()); + let arguments: &[_] = if is_minimal { + &[] + } else { + &[diag_data, function_address, self.const_usize(0)] + }; self.call( fty, None, None, ubsan_handler, ReturnSlot::Direct, - &[diag_data, function_address, self.const_usize(0)], + arguments, None, None, ); diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 2a02df05f26f5..8408e2eefb13e 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -1061,15 +1061,28 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( let stability = target.supports_c_variadic_definitions(); match target.arch { - Arch::X86 => emit_ptr_va_arg( - bx, - addr, - layout, - PassMode::Direct, - SlotSize::Bytes4, - if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes }, - ForceRightAdjust::No, - ), + Arch::X86 => { + // A small deviation from clang to get the right behavior for f128. + // + // Note that i64 and f64 have an alignment of only 4 on this architecture. + // We need to be careful when adding future types with an alignment bigger + // than 4 (e.g. i128), clang has a bunch of custom logic for them. + let allow_higher_align = if layout.ty == bx.tcx().types.f128 { + AllowHigherAlign::Yes + } else { + AllowHigherAlign::No + }; + + emit_ptr_va_arg( + bx, + addr, + layout, + PassMode::Direct, + SlotSize::Bytes4, + allow_higher_align, + ForceRightAdjust::No, + ) + } Arch::Arm64EC => emit_ptr_va_arg( bx, addr, diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 221998abf6128..45ab9b8bc3b30 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1776,7 +1776,11 @@ fn add_sanitizer_libraries( && (sess.opts.unstable_opts.sanitizer_cfi_diag.unwrap_or(false) || sess.opts.unstable_opts.sanitizer_cfi_recover.unwrap_or(false)) { - link_sanitizer_runtime(sess, flavor, linker, "ubsan"); + if sess.is_sanitizer_cfi_minimal_runtime_enabled() { + link_sanitizer_runtime(sess, flavor, linker, "ubsan_minimal"); + } else { + link_sanitizer_runtime(sess, flavor, linker, "ubsan"); + } } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 7397d43a48a00..c74871d57ced6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -638,12 +638,119 @@ where source: GoalSource, goal: Goal, ) -> Result, NoSolutionOrRerunNonErased> { - let (normalization_nested_goals, goal_evaluation) = - self.evaluate_goal_raw(source, goal, LowerAvailableDepth::Yes)?; + let (normalization_nested_goals, goal_evaluation) = self.evaluate_goal_raw(source, goal)?; assert!(normalization_nested_goals.is_empty()); Ok(goal_evaluation) } + fn evaluate_in_search_graph( + &mut self, + canonical_goal: I::CanonicalInput, + step_kind: PathKind, + ) -> (Result, NoSolution>, AccessedOpaques) { + let increase_depth_for_nested = + match canonical_goal.canonical.value.goal.predicate.kind().skip_binder() { + // We don't lower the available depth for the `NormalizesTo` goal, as evaluating + // it is an extra step only exists in the new solver that behaves like a function + // call rather than an independent nested goal evaluation. So, decreasing the + // available depth may end up regressions which hit the recursion limits for crates + // compiled well with the old solver. + ty::PredicateKind::NormalizesTo(_) => LowerAvailableDepth::No, + // We also don't lower depth for witness and rigid opaque when proving auto traits. + // This is to mitigate the overflow FCW warnings in deeply nested async calls. + // See #159228. + // + // We're eventually going to remove the witness type so it's okay to ignore the + // depth. + // For rigid opaques, revealing hidden types can be viewed as normalization so it's + // consistent with the `NormalizesTo` reasoning above. + ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => { + if self.cx().trait_is_auto(pred.trait_ref.def_id) { + match pred.self_ty().kind() { + ty::CoroutineWitness(..) => LowerAvailableDepth::No, + ty::Alias( + ty::IsRigid::Yes, + ty::AliasTy { kind: ty::Opaque { def_id, .. }, .. }, + ) => { + // We only want to skip lowering depth when the proving is done via + // auto trait leakage. If the goal can be proved via item bounds, + // we should lower depth faithfully. + // + // FIXME: We can have param env candidates via TAIT or RTN. + // Ideally we'd instead lower the depth for the nested goal instead. + // Implementing this is a bit harder. + if self + .cx() + .item_self_bounds(def_id.into()) + .skip_binder() + .into_iter() + .any(|bound| { + bound + .as_trait_clause() + .is_some_and(|b| b.def_id() == pred.def_id()) + }) + { + LowerAvailableDepth::Yes + } else { + LowerAvailableDepth::No + } + } + ty::Bool + | ty::Char + | ty::Int(..) + | ty::Uint(..) + | ty::Float(..) + | ty::Str + | ty::Pat(..) + | ty::FnPtr(..) + | ty::Array(..) + | ty::Slice(..) + | ty::RawPtr(..) + | ty::Never + | ty::Tuple(..) + | ty::UnsafeBinder(_) + | ty::Param(..) + | ty::Placeholder(..) + | ty::Bound(..) + | ty::Infer(..) + | ty::Alias(_, _) + | ty::Ref(_, _, _) + | ty::Adt(_, _) + | ty::Foreign(_) + | ty::Dynamic(..) + | ty::Error(_) + | ty::FnDef(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Coroutine(..) => LowerAvailableDepth::Yes, + } + } else { + LowerAvailableDepth::Yes + } + } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(_)) + | ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) + | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(_)) + | ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(_)) + | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(_, _)) + | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_)) + | ty::PredicateKind::Subtype(_) + | ty::PredicateKind::Coerce(_) + | ty::PredicateKind::DynCompatible(_) + | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) + | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(_)) + | ty::PredicateKind::ConstEquate(_, _) + | ty::PredicateKind::Ambiguous => LowerAvailableDepth::Yes, + }; + self.search_graph.evaluate_goal( + self.cx(), + canonical_goal, + step_kind, + increase_depth_for_nested, + &mut inspect::ProofTreeBuilder::new_noop(), + ) + } + /// Recursively evaluates `goal`, returning the nested goals in case /// the nested goal is a `NormalizesTo` goal. /// @@ -655,7 +762,6 @@ where &mut self, source: GoalSource, goal: Goal, - increase_depth_for_nested: LowerAvailableDepth, ) -> Result<(NestedNormalizationGoals, GoalEvaluation), NoSolutionOrRerunNonErased> { // We only care about one entry per `OpaqueTypeKey` here, // so we only canonicalize the lookup table and ignore @@ -723,13 +829,8 @@ where TypingMode::ErasedNotCoherence(MayBeErased), ); - let (canonical_result, accessed_opaques) = self.search_graph.evaluate_goal( - self.cx(), - canonical_goal, - step_kind, - increase_depth_for_nested, - &mut inspect::ProofTreeBuilder::new_noop(), - ); + let (canonical_result, accessed_opaques) = + self.evaluate_in_search_graph(canonical_goal, step_kind); let should_rerun = should_rerun_after_erased_canonicalization( accessed_opaques, @@ -763,13 +864,8 @@ where let (orig_values, canonical_goal) = canonicalize_goal(self.delegate, goal, &opaque_types, typing_mode); - let (canonical_result, accessed_opaques) = self.search_graph.evaluate_goal( - self.cx(), - canonical_goal, - step_kind, - increase_depth_for_nested, - &mut inspect::ProofTreeBuilder::new_noop(), - ); + let (canonical_result, accessed_opaques) = + self.evaluate_in_search_graph(canonical_goal, step_kind); assert!( !accessed_opaques.might_rerun(), "we run without TypingMode::ErasedNotCoherence, so opaques are available, and we don't retry if the outer typing mode is ErasedNotCoherence: {accessed_opaques:?} after {goal:?}" diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs index db326e6d736a4..9d6b8875071ba 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs @@ -3,7 +3,6 @@ mod free_alias; mod inherent; mod opaque_types; -use rustc_type_ir::search_graph::LowerAvailableDepth; use rustc_type_ir::solve::QueryResultOrRerunNonErased; use rustc_type_ir::{self as ty, Interner, ProjectionClause}; use tracing::{instrument, trace}; @@ -70,16 +69,7 @@ where let ( NestedNormalizationGoals(nested_goals), GoalEvaluation { goal: _, certainty, stalled_on: _, has_changed: _ }, - ) = self.evaluate_goal_raw( - GoalSource::TypeRelating, - normalizes_to, - // We don't lower thr available depth for this `NormalizesTo` goal, as evaluating - // it is an extra step only exists in the new solver that behaves like a function - // call rather than an independent nested goal evaluation. So, decreasing the - // available depth may end up regressions which hit the recursion limits for crates - // compiled well with the old solver. - LowerAvailableDepth::No, - )?; + ) = self.evaluate_goal_raw(GoalSource::TypeRelating, normalizes_to)?; trace!(?nested_goals); diff --git a/compiler/rustc_session/src/diagnostics.rs b/compiler/rustc_session/src/diagnostics.rs index 4ec8ca42edbee..e673435dae396 100644 --- a/compiler/rustc_session/src/diagnostics.rs +++ b/compiler/rustc_session/src/diagnostics.rs @@ -340,6 +340,16 @@ pub(crate) struct SanitizerCfiRecoverRequiresCfi; #[diag("`-Zsanitizer-cfi-diag` requires `-Zsanitizer=cfi`")] pub(crate) struct SanitizerCfiDiagRequiresCfi; +#[derive(Diagnostic)] +#[diag("`-Zsanitizer-cfi-minimal-runtime` requires `-Zsanitizer=cfi`")] +pub(crate) struct SanitizerCfiMinimalRuntimeRequiresCfi; + +#[derive(Diagnostic)] +#[diag( + "`-Zsanitizer-cfi-minimal-runtime` requires `-Zsanitizer-cfi-recover` or `-Zsanitizer-cfi-diag`" +)] +pub(crate) struct SanitizerCfiMinimalRuntimeRequiresCfiRecoverOrDiag; + #[derive(Diagnostic)] #[diag("`-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`")] pub(crate) struct SanitizerKcfiArityRequiresKcfi; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 13fc598d86bfa..63bc2da30f063 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -136,6 +136,21 @@ mod target_modifier_consistency_check { } true } + pub(super) fn sanitizer_cfi_minimal_runtime( + sess: &Session, + l: &TargetModifier, + r: Option<&TargetModifier>, + ) -> bool { + // For CFI, the helper flag -Zsanitizer-cfi-minimal-runtime should also be a target modifier + if sess.sanitizers().contains(SanitizerSet::CFI) { + if let Some(r) = r { + return l.extend().tech_value == r.extend().tech_value; + } else { + return false; + } + } + true + } pub(super) fn target_cpu( sess: &Session, l: &TargetModifier, @@ -178,6 +193,11 @@ impl TargetModifier { sess, self, other, ); } + UnstableOptionsTargetModifiers::SanitizerCfiMinimalRuntime => { + return target_modifier_consistency_check::sanitizer_cfi_minimal_runtime( + sess, self, other, + ); + } _ => {} }, OptionsTargetModifiers::CodegenOptions(codegen) => match codegen { @@ -2825,6 +2845,8 @@ written to standard error output)"), "enable CFI diagnostics (default: no)"), sanitizer_cfi_recover: Option = (None, parse_opt_bool, [TRACKED], "enable CFI recovery (default: no)"), + sanitizer_cfi_minimal_runtime: Option = (None, parse_opt_bool, [TRACKED] { TARGET_MODIFIER: SanitizerCfiMinimalRuntime }, + "enable minimal UBSan runtime for CFI (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], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 3b60a13b8e6f2..34847052b29d4 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -745,6 +745,10 @@ impl Session { self.opts.unstable_opts.sanitizer_cfi_diag == Some(true) } + pub fn is_sanitizer_cfi_minimal_runtime_enabled(&self) -> bool { + self.opts.unstable_opts.sanitizer_cfi_minimal_runtime == Some(true) + } + pub fn is_sanitizer_kcfi_arity_enabled(&self) -> bool { self.opts.unstable_opts.sanitizer_kcfi_arity == Some(true) } @@ -1683,6 +1687,16 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } } + // LLVM CFI minimal runtime requires CFI recovery or CFI diagnostics. + if sess.is_sanitizer_cfi_minimal_runtime_enabled() { + if !sess.is_sanitizer_cfi_enabled() { + sess.dcx().emit_err(diagnostics::SanitizerCfiMinimalRuntimeRequiresCfi); + } else if !(sess.is_sanitizer_cfi_recover_enabled() || sess.is_sanitizer_cfi_diag_enabled()) + { + sess.dcx().emit_err(diagnostics::SanitizerCfiMinimalRuntimeRequiresCfiRecoverOrDiag); + } + } + // LLVM CFI integer normalization requires CFI or KCFI. if sess.is_sanitizer_cfi_normalize_integers_enabled() { if !(sess.is_sanitizer_cfi_enabled() || sess.is_sanitizer_kcfi_enabled()) { diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index ef1241266cac6..8f63c96fad707 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -719,6 +719,18 @@ fn layout_of_uncached<'tcx>( abi::Integer::discr_range_of_repr(tcx, ty, &def.repr(), min.start, max.last) }; + // We shouldn't be computing the layout of discrs that fail typeck + if def.is_enum() { + for v in def.variants() { + if let ty::VariantDiscr::Explicit(def_id) = v.discr + && let Some(local_did) = def_id.as_local() + && let Some(guar) = tcx.typeck(local_did).tainted_by_errors + { + return Err(error(cx, LayoutError::ReferencesError(guar))); + } + } + } + let discriminants_iter = || { def.is_enum() .then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val))) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 6700392fc7add..625b3959d3326 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -1927,7 +1927,7 @@ fn supported_sanitizers( "aarch64-unknown-linux-gnu" => common_libs( "linux", "aarch64", - &["asan", "lsan", "msan", "tsan", "hwasan", "rtsan", "ubsan"], + &["asan", "lsan", "msan", "tsan", "hwasan", "rtsan", "ubsan", "ubsan_minimal"], ), "aarch64-unknown-linux-ohos" => { common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"]) @@ -1948,7 +1948,17 @@ fn supported_sanitizers( "x86_64-unknown-linux-gnu" => common_libs( "linux", "x86_64", - &["asan", "dfsan", "lsan", "msan", "safestack", "tsan", "rtsan", "ubsan"], + &[ + "asan", + "dfsan", + "lsan", + "msan", + "safestack", + "tsan", + "rtsan", + "ubsan", + "ubsan_minimal", + ], ), "x86_64-unknown-linux-gnuasan" => common_libs("linux", "x86_64", &["asan"]), "x86_64-unknown-linux-gnumsan" => common_libs("linux", "x86_64", &["msan"]), diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index 0b766a3e557c5..0900afd6594fe 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -16,5 +16,4 @@ rayon = "1.5.1" hex = "0.4.2" [build-dependencies] -serde = "1" serde_json = "1" diff --git a/src/tools/jsondoclint/Cargo.toml b/src/tools/jsondoclint/Cargo.toml index 848c0b37ae94e..e835549878834 100644 --- a/src/tools/jsondoclint/Cargo.toml +++ b/src/tools/jsondoclint/Cargo.toml @@ -9,7 +9,9 @@ edition = "2024" anyhow = "1.0.62" clap = { version = "4.0.15", features = ["derive"] } fs-err = "2.8.1" -rustc-hash = "2.0.0" rustdoc-json-types = { version = "0.1.0", path = "../../rustdoc-json-types" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.85" + +[dev-dependencies] +rustc-hash = "2.0.0" diff --git a/src/tools/remote-test-client/Cargo.toml b/src/tools/remote-test-client/Cargo.toml index 6fe690ba20380..70a6e896a01ab 100644 --- a/src/tools/remote-test-client/Cargo.toml +++ b/src/tools/remote-test-client/Cargo.toml @@ -3,5 +3,5 @@ name = "remote-test-client" version = "0.1.0" edition = "2021" -[dependencies] +[dev-dependencies] assert_cmd = "2" diff --git a/src/tools/replace-version-placeholder/Cargo.toml b/src/tools/replace-version-placeholder/Cargo.toml index 346ce6bd1dbfd..e581194fcf09f 100644 --- a/src/tools/replace-version-placeholder/Cargo.toml +++ b/src/tools/replace-version-placeholder/Cargo.toml @@ -7,4 +7,3 @@ edition = "2021" [dependencies] tidy = { path = "../tidy" } -walkdir = "2" diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 65a7890a5ecc2..e1a5495f81954 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -95,15 +95,34 @@ pub(crate) struct WorkspaceInfo<'a> { pub(crate) path: &'a str, /// The list of license exceptions. pub(crate) exceptions: ExceptionList, - /// Optionally: - /// * A list of crates for which dependencies need to be explicitly allowed. - /// * The list of allowed dependencies. - /// * The source code location of the allowed dependencies list - crates_and_deps: Option<(&'a [&'a str], &'a [&'a str], ListLocation)>, + /// The list of dependencies that are allowed. If None, any crate with an + /// acceptable license is allowed. + allowed_deps: Option>, /// Submodules required for the workspace pub(crate) submodules: &'a [&'a str], } +#[derive(Clone, Copy)] +struct PermittedDeps<'a> { + /// A list of crates for which dependencies need to be explicitly allowed + /// or None to check the entire workspace. + roots: Option<&'a [&'a str]>, + /// The list of allowed dependencies. + deps: &'a [&'a str], + /// The source code location of the allowed dependencies list. + deps_loc: ListLocation, +} + +impl<'a> PermittedDeps<'a> { + const fn new( + roots: Option<&'a [&'a str]>, + deps: &'a [&'a str], + deps_loc: ListLocation, + ) -> Self { + Self { roots, deps, deps_loc } + } +} + const WORKSPACE_LOCATION: ListLocation = location!(+4); /// The workspaces to check for licensing and optionally permitted dependencies. @@ -113,8 +132,8 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ WorkspaceInfo { path: ".", exceptions: EXCEPTIONS, - crates_and_deps: Some(( - &["rustc-main"], + allowed_deps: Some(PermittedDeps::new( + Some(&["rustc-main"]), PERMITTED_RUSTC_DEPENDENCIES, PERMITTED_RUSTC_DEPS_LOCATION, )), @@ -123,8 +142,8 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ WorkspaceInfo { path: "library", exceptions: EXCEPTIONS_STDLIB, - crates_and_deps: Some(( - &["sysroot"], + allowed_deps: Some(PermittedDeps::new( + None, PERMITTED_STDLIB_DEPENDENCIES, PERMITTED_STDLIB_DEPS_LOCATION, )), @@ -133,14 +152,14 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ WorkspaceInfo { path: "library/stdarch", exceptions: EXCEPTIONS_STDARCH, - crates_and_deps: None, + allowed_deps: None, submodules: &[], }, WorkspaceInfo { path: "compiler/rustc_codegen_cranelift", exceptions: EXCEPTIONS_CRANELIFT, - crates_and_deps: Some(( - &["rustc_codegen_cranelift"], + allowed_deps: Some(PermittedDeps::new( + None, PERMITTED_CRANELIFT_DEPENDENCIES, PERMITTED_CRANELIFT_DEPS_LOCATION, )), @@ -149,19 +168,19 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ WorkspaceInfo { path: "compiler/rustc_codegen_gcc", exceptions: EXCEPTIONS_GCC, - crates_and_deps: None, + allowed_deps: None, submodules: &[], }, WorkspaceInfo { path: "src/bootstrap", exceptions: EXCEPTIONS_BOOTSTRAP, - crates_and_deps: None, + allowed_deps: None, submodules: &[], }, WorkspaceInfo { path: "src/tools/cargo", exceptions: EXCEPTIONS_CARGO, - crates_and_deps: None, + allowed_deps: None, submodules: &["src/tools/cargo"], }, // FIXME uncomment once all deps are vendored @@ -178,25 +197,25 @@ pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ WorkspaceInfo { path: "src/tools/rust-analyzer", exceptions: EXCEPTIONS_RUST_ANALYZER, - crates_and_deps: None, + allowed_deps: None, submodules: &[], }, WorkspaceInfo { path: "src/tools/rustbook", exceptions: EXCEPTIONS_RUSTBOOK, - crates_and_deps: None, + allowed_deps: None, submodules: &["src/doc/book", "src/doc/reference"], }, WorkspaceInfo { path: "src/tools/rustc-perf", exceptions: EXCEPTIONS_RUSTC_PERF, - crates_and_deps: None, + allowed_deps: None, submodules: &["src/tools/rustc-perf"], }, WorkspaceInfo { path: "tests/run-make-cargo/uefi-qemu/uefi_qemu_test", exceptions: EXCEPTIONS_UEFI_QEMU_TEST, - crates_and_deps: None, + allowed_deps: None, submodules: &[], }, ]; @@ -638,7 +657,8 @@ pub fn check(root: &Path, cargo: &Path, tidy_ctx: TidyCtx) { check_proc_macro_dep_list(root, cargo, bless, &mut check); - for &WorkspaceInfo { path, exceptions, crates_and_deps, submodules } in WORKSPACES { + for &WorkspaceInfo { path, exceptions, allowed_deps: crates_and_deps, submodules } in WORKSPACES + { if has_missing_submodule(root, submodules, tidy_ctx.is_running_on_ci()) { continue; } @@ -663,14 +683,14 @@ pub fn check(root: &Path, cargo: &Path, tidy_ctx: TidyCtx) { check.error(format!("{path} is part of another workspace ({} != {}), remove from `WORKSPACES` ({WORKSPACE_LOCATION})", absolute_root.display(), absolute_root_real.display())); } check_license_exceptions(&metadata, path, exceptions, &mut check); - if let Some((crates, permitted_deps, location)) = crates_and_deps { - let descr = crates.get(0).unwrap_or(&path); + if let Some(PermittedDeps { roots, deps: permitted_deps, deps_loc }) = crates_and_deps { + let descr = roots.map_or(path, |roots| roots.get(0).unwrap_or(&path)); check_permitted_dependencies( &metadata, descr, permitted_deps, - crates, - location, + roots, + deps_loc, &mut check, ); } @@ -927,15 +947,21 @@ fn check_permitted_dependencies( metadata: &Metadata, descr: &str, permitted_dependencies: &[&'static str], - restricted_dependency_crates: &[&'static str], + restricted_dependency_crates: Option<&[&'static str]>, permitted_location: ListLocation, check: &mut RunningCheck, ) { let mut has_permitted_dep_error = false; let mut deps = HashSet::new(); - for to_check in restricted_dependency_crates { - let to_check = pkg_from_name(metadata, to_check); - deps_of(metadata, &to_check.id, &mut deps); + if let Some(restricted_dependency_crates) = restricted_dependency_crates { + for to_check in restricted_dependency_crates { + let to_check = pkg_from_name(metadata, to_check); + deps_of(metadata, &to_check.id, &mut deps); + } + } else { + for to_check in &metadata.packages { + deps_of(metadata, &to_check.id, &mut deps); + } } // Check that the PERMITTED_DEPENDENCIES does not have unused entries. diff --git a/tests/assembly-llvm/c-variadic/x86-linux.rs b/tests/assembly-llvm/c-variadic/x86-linux.rs index d2f5c1144a991..de647ca861cb6 100644 --- a/tests/assembly-llvm/c-variadic/x86-linux.rs +++ b/tests/assembly-llvm/c-variadic/x86-linux.rs @@ -9,7 +9,7 @@ //@ [I686] compile-flags: -Copt-level=3 -Cllvm-args=-x86-asm-syntax=intel //@ [I686] compile-flags: --target i686-unknown-linux-gnu //@ needs-llvm-components: x86 -#![feature(no_core, lang_items, intrinsics, rustc_attrs)] +#![feature(no_core, lang_items, intrinsics, rustc_attrs, f128)] #![no_core] #![crate_type = "lib"] @@ -64,20 +64,55 @@ unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 { ap.next_arg() } +#[unsafe(no_mangle)] +unsafe extern "C" fn read_f128(ap: &mut VaList<'_>) -> f128 { + // CHECK-LABEL: read_f128 + + // X86_64: mov ecx, dword ptr [rdi + 4] + // X86_64-NEXT: cmp rcx, 160 + // X86_64-NEXT: ja .LBB1_2 + // X86_64-NEXT: mov rax, rcx + // X86_64-NEXT: add rax, qword ptr [rdi + 16] + // X86_64-NEXT: add ecx, 16 + // X86_64-NEXT: mov dword ptr [rdi + 4], ecx + // X86_64-NEXT: movaps xmm0, xmmword ptr [rax] + // X86_64-NEXT: ret + // X86_64-NEXT: .LBB1_2: + // X86_64-NEXT: mov rax, qword ptr [rdi + 8] + // X86_64-NEXT: add rax, 15 + // X86_64-NEXT: and rax, -16 + // X86_64-NEXT: lea rcx, [rax + 16] + // X86_64-NEXT: mov qword ptr [rdi + 8], rcx + // X86_64-NEXT: movaps xmm0, xmmword ptr [rax] + // X86_64-NEXT: ret + + // I686: mov ecx, dword ptr [esp + 12] + // I686-NEXT: mov eax, dword ptr [esp + 8] + // I686-NEXT: mov edx, dword ptr [ecx] + // I686-NEXT: add edx, 15 + // I686-NEXT: and edx, -16 + // I686-NEXT: lea esi, [edx + 16] + // I686-NEXT: mov dword ptr [ecx], esi + // I686-NEXT: movaps xmm0, xmmword ptr [edx] + // I686-NEXT: movaps xmmword ptr [eax], xmm0 + // I686-NEXT: pop esi + ap.next_arg() +} + #[unsafe(no_mangle)] unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { // CHECK-LABEL: read_i32 // // X86_64: mov ecx, dword ptr [rdi] // X86_64-NEXT: cmp rcx, 40 - // X86_64-NEXT: ja .LBB1_2 + // X86_64-NEXT: ja .LBB2_2 // X86_64-NEXT: mov rax, rcx // X86_64-NEXT: add rax, qword ptr [rdi + 16] // X86_64-NEXT: add ecx, 8 // X86_64-NEXT: mov dword ptr [rdi], ecx // X86_64-NEXT: mov eax, dword ptr [rax] // X86_64-NEXT: ret - // X86_64-NEXT: .LBB1_2: + // X86_64-NEXT: .LBB2_2: // X86_64-NEXT: mov rax, qword ptr [rdi + 8] // X86_64-NEXT: lea rcx, [rax + 8] // X86_64-NEXT: mov qword ptr [rdi + 8], rcx @@ -86,14 +121,14 @@ unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { // X86_64-NEXT_GNUX32: mov ecx, dword ptr [edi] // X86_64-NEXT_GNUX32-NEXT: cmp ecx, 40 - // X86_64-NEXT_GNUX32-NEXT: ja .LBB1_2 + // X86_64-NEXT_GNUX32-NEXT: ja .LBB2_2 // X86_64-NEXT_GNUX32-NEXT: mov eax, dword ptr [edi + 12] // X86_64-NEXT_GNUX32-NEXT: add eax, ecx // X86_64-NEXT_GNUX32-NEXT: add ecx, 8 // X86_64-NEXT_GNUX32-NEXT: mov dword ptr [edi], ecx // X86_64-NEXT_GNUX32-NEXT: mov eax, dword ptr [eax] // X86_64-NEXT_GNUX32-NEXT: ret - // X86_64-NEXT_GNUX32-NEXT: .LBB1_2: + // X86_64-NEXT_GNUX32-NEXT: .LBB2_2: // X86_64-NEXT_GNUX32-NEXT: mov eax, dword ptr [edi + 8] // X86_64-NEXT_GNUX32-NEXT: lea ecx, [rax + 8] // X86_64-NEXT_GNUX32-NEXT: mov dword ptr [edi + 8], ecx @@ -115,14 +150,14 @@ unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { // X86_64: mov ecx, dword ptr [rdi] // X86_64-NEXT: cmp rcx, 40 - // X86_64-NEXT: ja .LBB2_2 + // X86_64-NEXT: ja .LBB3_2 // X86_64-NEXT: mov rax, rcx // X86_64-NEXT: add rax, qword ptr [rdi + 16] // X86_64-NEXT: add ecx, 8 // X86_64-NEXT: mov dword ptr [rdi], ecx // X86_64-NEXT: mov rax, qword ptr [rax] // X86_64-NEXT: ret - // X86_64-NEXT: .LBB2_2: + // X86_64-NEXT: .LBB3_2: // X86_64-NEXT: mov rax, qword ptr [rdi + 8] // X86_64-NEXT: lea rcx, [rax + 8] // X86_64-NEXT: mov qword ptr [rdi + 8], rcx @@ -131,7 +166,7 @@ unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { // X86_64-NEXT_GNUX32: mov ecx, dword ptr [edi] // X86_64-NEXT_GNUX32-NEXT: cmp ecx, 40 - // X86_64-NEXT_GNUX32-NEXT: ja .LBB2_2 + // X86_64-NEXT_GNUX32-NEXT: ja .LBB3_2 // X86_64-NEXT_GNUX32-NEXT: mov eax, dword ptr [edi + 12] // X86_64-NEXT_GNUX32-NEXT: add eax, ecx // X86_64-NEXT_GNUX32-NEXT: add ecx, 8 @@ -162,14 +197,14 @@ unsafe extern "C" fn read_i128(ap: &mut VaList<'_>) -> i128 { // // X86_64: mov ecx, dword ptr [rdi] // X86_64-NEXT: cmp rcx, 32 - // X86_64-NEXT: ja .LBB3_2 + // X86_64-NEXT: ja .LBB4_2 // X86_64-NEXT: mov rdx, qword ptr [rdi + 16] // X86_64-NEXT: mov rax, qword ptr [rdx + rcx] // X86_64-NEXT: mov rdx, qword ptr [rdx + rcx + 8] // X86_64-NEXT: add ecx, 16 // X86_64-NEXT: mov dword ptr [rdi], ecx // X86_64-NEXT: ret - // X86_64-NEXT: .LBB3_2: + // X86_64-NEXT: .LBB4_2: // X86_64-NEXT: mov rcx, qword ptr [rdi + 8] // X86_64-NEXT: add rcx, 15 // X86_64-NEXT: and rcx, -16 @@ -181,7 +216,7 @@ unsafe extern "C" fn read_i128(ap: &mut VaList<'_>) -> i128 { // X86_64-NEXT_GNUX32: mov ecx, dword ptr [edi] // X86_64-NEXT_GNUX32-NEXT: cmp ecx, 32 - // X86_64-NEXT_GNUX32-NEXT: ja .LBB3_2 + // X86_64-NEXT_GNUX32-NEXT: ja .LBB4_2 // X86_64-NEXT_GNUX32-NEXT: mov edx, dword ptr [edi + 12] // X86_64-NEXT_GNUX32-NEXT: mov rax, qword ptr [edx + ecx] // X86_64-NEXT_GNUX32-NEXT: mov rdx, qword ptr [edx + ecx + 8] diff --git a/tests/assembly-llvm/pauth-basic.rs b/tests/assembly-llvm/pauth-basic.rs index e240e1317f3a3..34b9c4b5c328c 100644 --- a/tests/assembly-llvm/pauth-basic.rs +++ b/tests/assembly-llvm/pauth-basic.rs @@ -1,8 +1,8 @@ //@ add-minicore //@ assembly-output: emit-asm -//@ only-pauthtest //@ revisions: aarch64_unknown_linux_pauthtest //@ [aarch64_unknown_linux_pauthtest] compile-flags: --target=aarch64-unknown-linux-pauthtest +//@ [aarch64_unknown_linux_pauthtest] compile-flags: -Copt-level=3 //@ [aarch64_unknown_linux_pauthtest] needs-llvm-components: aarch64 #![feature(no_core, lang_items)] diff --git a/tests/codegen-llvm/pauth/pauth-attr-cli-flags.rs b/tests/codegen-llvm/pauth/pauth-attr-cli-flags.rs index 04af1b66140dd..513850f1dd4db 100644 --- a/tests/codegen-llvm/pauth/pauth-attr-cli-flags.rs +++ b/tests/codegen-llvm/pauth/pauth-attr-cli-flags.rs @@ -1,5 +1,4 @@ // ignore-tidy-file-linelength -//@ only-pauthtest //@ revisions: DEFAULT ALL DISABLE_JUMP DISABLE_AUTH_TRAPS DISABLE_CALLS DISABLE_INDIRCT_GOTOS DISABLE_RETURNS DISABLE_INTRINSICS DISABLE_TYPEINFO DISABLE_VT_PTR_ADDR DISABLE_VT_PTR_TYPE NONE //@ add-minicore diff --git a/tests/codegen-llvm/pauth/pauth-attr-special-funcs.rs b/tests/codegen-llvm/pauth/pauth-attr-special-funcs.rs index 2751494b9de7a..24ab1abb10e67 100644 --- a/tests/codegen-llvm/pauth/pauth-attr-special-funcs.rs +++ b/tests/codegen-llvm/pauth/pauth-attr-special-funcs.rs @@ -3,6 +3,8 @@ // Make sure that compiler generated functions (main wrapper and __rust_try) also have ptrauth // attributes set correctly. Rustc only generates __rust_try at O0, so use that opt level for the // test. +// Cannot be converted to minicore: catch_unwind is a std API and is what causes rustc to generate +// the __rust_try wrapper this test is checking. //@ needs-llvm-components: aarch64 diff --git a/tests/codegen-llvm/pauth/pauth-extern-c-direct-indirect-call.rs b/tests/codegen-llvm/pauth/pauth-extern-c-direct-indirect-call.rs index 643b428339b73..d01815954b237 100644 --- a/tests/codegen-llvm/pauth/pauth-extern-c-direct-indirect-call.rs +++ b/tests/codegen-llvm/pauth/pauth-extern-c-direct-indirect-call.rs @@ -1,10 +1,12 @@ //@ add-minicore // ignore-tidy-linelength -//@ only-pauthtest //@ revisions: O0_PAUTH O3_PAUTH //@ [O0_PAUTH] needs-llvm-components: aarch64 //@ [O0_PAUTH] compile-flags: --target=aarch64-unknown-linux-pauthtest -C opt-level=0 +// O3_PAUTH relies on an InstCombine fold that removes the redundant `ptrauth` bundle from calls. +// That fold first shipped in LLVM 22, gate this revision accordingly. +//@ [O3_PAUTH] min-llvm-version: 22 //@ [O3_PAUTH] needs-llvm-components: aarch64 //@ [O3_PAUTH] compile-flags: --target=aarch64-unknown-linux-pauthtest -C opt-level=3 diff --git a/tests/codegen-llvm/pauth/pauth-extern-c.rs b/tests/codegen-llvm/pauth/pauth-extern-c.rs index b22cf6943a804..07e27965e9ebf 100644 --- a/tests/codegen-llvm/pauth/pauth-extern-c.rs +++ b/tests/codegen-llvm/pauth/pauth-extern-c.rs @@ -1,5 +1,4 @@ // ignore-tidy-file-linelength -//@ only-pauthtest //@ add-minicore //@ revisions: O0_PAUTH O3_PAUTH O0_PAUTH-ELF-GOT O3_PAUTH-ELF-GOT O0_NO_PAUTH O3_NO_PAUTH diff --git a/tests/codegen-llvm/pauth/pauth-extern-weak-global.rs b/tests/codegen-llvm/pauth/pauth-extern-weak-global.rs index a83298dd5725c..b7c1f5fd06479 100644 --- a/tests/codegen-llvm/pauth/pauth-extern-weak-global.rs +++ b/tests/codegen-llvm/pauth/pauth-extern-weak-global.rs @@ -1,5 +1,4 @@ // ignore-tidy-linelength -//@ only-pauthtest //@ revisions: O0_PAUTH O3_PAUTH O0_NO_PAUTH O3_NO_PAUTH //@ add-minicore diff --git a/tests/codegen-llvm/pauth/pauth-init-fini.rs b/tests/codegen-llvm/pauth/pauth-init-fini.rs index b54006e56f1f4..5550100ae7f92 100644 --- a/tests/codegen-llvm/pauth/pauth-init-fini.rs +++ b/tests/codegen-llvm/pauth/pauth-init-fini.rs @@ -1,6 +1,5 @@ // ignore-tidy-file-linelength //@ add-minicore -//@ only-pauthtest //@ revisions: O0_PAUTH O3_PAUTH O0_PAUTH-ADDR-DISC O3_PAUTH-ADDR-DISC O0_PAUTH-NO-INIT-FINI O3_PAUTH-NO-INIT-FINI //@ [O0_PAUTH] needs-llvm-components: aarch64 diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-diag-mode.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-diag-mode.rs index 07688a8e5cb0b..4d58872db7c45 100644 --- a/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-diag-mode.rs +++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-diag-mode.rs @@ -1,7 +1,9 @@ // Verifies that pointer type membership tests for indirect calls are emitted. // +//@ revisions: cfi-diag cfi-diag-minimal-runtime //@ needs-sanitizer-cfi -//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-diag=true -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer +//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-diag=true -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-minimal-runtime +//@ [cfi-diag-minimal-runtime] compile-flags: -Zsanitizer-cfi-minimal-runtime=true #![crate_type = "lib"] @@ -14,7 +16,8 @@ pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-NEXT: {{%.+}} = call i32 %f(i32{{.*}} %arg) // CHECK: type_test.fail: // CHECK-NEXT: {{%.+}} = ptrtoint ptr {{%f|%0}} to i64 - // CHECK-NEXT: call void @__ubsan_handle_cfi_check_fail_abort( + // cfi-diag-NEXT: call void @__ubsan_handle_cfi_check_fail_abort( + // cfi-diag-minimal-runtime-NEXT: call void @__ubsan_handle_cfi_check_fail_minimal_abort() // CHECK-NEXT: unreachable f(arg) } diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-recover-mode.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-recover-mode.rs index 0dbcb7a833fb7..3ea97e44c21e7 100644 --- a/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-recover-mode.rs +++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-recover-mode.rs @@ -1,7 +1,9 @@ // Verifies that pointer type membership tests for indirect calls are emitted. // +//@ revisions: cfi-recover cfi-recover-minimal-runtime //@ needs-sanitizer-cfi -//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-recover=true -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer +//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-recover=true -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-minimal-runtime +//@ [cfi-recover-minimal-runtime] compile-flags: -Zsanitizer-cfi-minimal-runtime=true #![crate_type = "lib"] @@ -14,7 +16,8 @@ pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-NEXT: {{%.+}} = call i32 %f(i32{{.*}} %arg) // CHECK: type_test.fail: // CHECK-NEXT: {{%.+}} = ptrtoint ptr {{%f|%0}} to i64 - // CHECK-NEXT: call void @__ubsan_handle_cfi_check_fail( + // cfi-recover-NEXT: call void @__ubsan_handle_cfi_check_fail( + // cfi-recover-minimal-runtime-NEXT: call void @__ubsan_handle_cfi_check_fail_minimal() // CHECK-NEXT: br label %type_test.pass f(arg) } diff --git a/tests/crashes/138660.rs b/tests/crashes/138660.rs deleted file mode 100644 index 90eb8026f072f..0000000000000 --- a/tests/crashes/138660.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: #138660 -enum A { - V1(isize) = 1..=10, - V0 = 1..=10, -} -const B: &'static [A] = &[A::V0, A::V1(111)]; -fn main() {} diff --git a/tests/run-make/sanitizer-cfi-runtime/program.rs b/tests/run-make/sanitizer-cfi-runtime/program.rs new file mode 100644 index 0000000000000..0a46dcedef9de --- /dev/null +++ b/tests/run-make/sanitizer-cfi-runtime/program.rs @@ -0,0 +1,17 @@ +use std::hint::black_box; +use std::mem; + +fn add_one(x: i32) -> i32 { + x + 1 +} + +#[inline(never)] +fn call_with_mismatch(f: fn(i32) -> i32) { + let g: fn(i32, i32) -> i32 = unsafe { mem::transmute(f) }; + let res = g(1, 2); + assert_eq!(res, 2); +} + +fn main() { + call_with_mismatch(black_box(add_one)); +} diff --git a/tests/run-make/sanitizer-cfi-runtime/rmake.rs b/tests/run-make/sanitizer-cfi-runtime/rmake.rs new file mode 100644 index 0000000000000..3cad996a14054 --- /dev/null +++ b/tests/run-make/sanitizer-cfi-runtime/rmake.rs @@ -0,0 +1,172 @@ +//@ needs-sanitizer-support +//@ needs-sanitizer-cfi +//@ ignore-backends: gcc + +use run_make_support::{run, run_fail, rustc}; + +fn main() { + // 1. Check link args for default CFI (no diag/recover, no UBSan runtime) + let link_args_default = rustc() + .arg("-Clto") + .arg("-Ccodegen-units=1") + .arg("-Ctarget-feature=-crt-static") + .arg("-Cunsafe-allow-abi-mismatch=sanitizer") + .arg("-Zsanitizer=cfi") + .print("link-args") + .input("program.rs") + .run() + .stdout_utf8(); + assert!( + !link_args_default.contains("ubsan"), + "did not expect any ubsan runtime in link args, got: {link_args_default}" + ); + + // 2. Check link args for full UBSan runtime with CFI diag mode + let link_args_full_diag = rustc() + .arg("-Clto") + .arg("-Ccodegen-units=1") + .arg("-Ctarget-feature=-crt-static") + .arg("-Cunsafe-allow-abi-mismatch=sanitizer") + .arg("-Zsanitizer=cfi") + .arg("-Zsanitizer-cfi-diag=true") + .print("link-args") + .input("program.rs") + .run() + .stdout_utf8(); + assert!( + link_args_full_diag.contains("rt.ubsan.") || link_args_full_diag.contains("rt.ubsan\""), + "expected ubsan runtime in link args, got: {link_args_full_diag}" + ); + assert!( + !link_args_full_diag.contains("ubsan_minimal"), + "did not expect ubsan_minimal in link args, got: {link_args_full_diag}" + ); + + // 3. Check link args for full UBSan runtime with CFI recover mode + let link_args_full_recover = rustc() + .arg("-Clto") + .arg("-Ccodegen-units=1") + .arg("-Ctarget-feature=-crt-static") + .arg("-Cunsafe-allow-abi-mismatch=sanitizer") + .arg("-Zsanitizer=cfi") + .arg("-Zsanitizer-cfi-recover=true") + .print("link-args") + .input("program.rs") + .run() + .stdout_utf8(); + assert!( + link_args_full_recover.contains("rt.ubsan.") + || link_args_full_recover.contains("rt.ubsan\""), + "expected ubsan runtime in link args, got: {link_args_full_recover}" + ); + assert!( + !link_args_full_recover.contains("ubsan_minimal"), + "did not expect ubsan_minimal in link args, got: {link_args_full_recover}" + ); + + // 4. Check link args for minimal UBSan runtime with CFI diag mode + let link_args_min_diag = rustc() + .arg("-Clto") + .arg("-Ccodegen-units=1") + .arg("-Ctarget-feature=-crt-static") + .arg("-Cunsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-minimal-runtime") + .arg("-Zsanitizer=cfi") + .arg("-Zsanitizer-cfi-diag=true") + .arg("-Zsanitizer-cfi-minimal-runtime=true") + .print("link-args") + .input("program.rs") + .run() + .stdout_utf8(); + assert!( + link_args_min_diag.contains("rt.ubsan_minimal.") + || link_args_min_diag.contains("rt.ubsan_minimal\""), + "expected ubsan_minimal runtime in link args, got: {link_args_min_diag}" + ); + + // 5. Check link args for minimal UBSan runtime with CFI recover mode + let link_args_min_recover = rustc() + .arg("-Clto") + .arg("-Ccodegen-units=1") + .arg("-Ctarget-feature=-crt-static") + .arg("-Cunsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-minimal-runtime") + .arg("-Zsanitizer=cfi") + .arg("-Zsanitizer-cfi-recover=true") + .arg("-Zsanitizer-cfi-minimal-runtime=true") + .print("link-args") + .input("program.rs") + .run() + .stdout_utf8(); + assert!( + link_args_min_recover.contains("rt.ubsan_minimal.") + || link_args_min_recover.contains("rt.ubsan_minimal\""), + "expected ubsan_minimal runtime in link args, got: {link_args_min_recover}" + ); + + // 6. Build and run binary with default CFI (trap mode, no runtime) + rustc() + .arg("-Clto") + .arg("-Ccodegen-units=1") + .arg("-Ctarget-feature=-crt-static") + .arg("-Cunsafe-allow-abi-mismatch=sanitizer") + .arg("-Zsanitizer=cfi") + .output("program_default") + .input("program.rs") + .run(); + run_fail("program_default"); + + // 7. Build and run binary with full runtime in diag (abort) mode + rustc() + .arg("-Clto") + .arg("-Ccodegen-units=1") + .arg("-Ctarget-feature=-crt-static") + .arg("-Cunsafe-allow-abi-mismatch=sanitizer") + .arg("-Zsanitizer=cfi") + .arg("-Zsanitizer-cfi-diag=true") + .output("program_full_diag") + .input("program.rs") + .run(); + run_fail("program_full_diag") + .assert_stderr_contains("runtime error: control flow integrity check for type"); + + // 8. Build and run binary with full runtime in recover mode + rustc() + .arg("-Clto") + .arg("-Ccodegen-units=1") + .arg("-Ctarget-feature=-crt-static") + .arg("-Cunsafe-allow-abi-mismatch=sanitizer") + .arg("-Zsanitizer=cfi") + .arg("-Zsanitizer-cfi-recover=true") + .output("program_full_recover") + .input("program.rs") + .run(); + run("program_full_recover") + .assert_stderr_contains("runtime error: control flow integrity check for type"); + + // 9. Build and run binary with minimal runtime in diag (abort) mode + rustc() + .arg("-Clto") + .arg("-Ccodegen-units=1") + .arg("-Ctarget-feature=-crt-static") + .arg("-Cunsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-minimal-runtime") + .arg("-Zsanitizer=cfi") + .arg("-Zsanitizer-cfi-diag=true") + .arg("-Zsanitizer-cfi-minimal-runtime=true") + .output("program_min_diag") + .input("program.rs") + .run(); + run_fail("program_min_diag").assert_stderr_contains("ubsan: cfi-check-fail"); + + // 10. Build and run binary with minimal runtime in recover mode + rustc() + .arg("-Clto") + .arg("-Ccodegen-units=1") + .arg("-Ctarget-feature=-crt-static") + .arg("-Cunsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-minimal-runtime") + .arg("-Zsanitizer=cfi") + .arg("-Zsanitizer-cfi-recover=true") + .arg("-Zsanitizer-cfi-minimal-runtime=true") + .output("program_min_recover") + .input("program.rs") + .run(); + run("program_min_recover").assert_stderr_contains("ubsan: cfi-check-fail"); +} diff --git a/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.rs b/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.rs new file mode 100644 index 0000000000000..c1e968494540c --- /dev/null +++ b/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.rs @@ -0,0 +1,13 @@ +// Previously, enums with non-int discrs ICEd during CTFE of promoteds. + +enum A { +//~^ ERROR `#[repr(inttype)]` must be specified + V1(isize) = 1..=10, + //~^ ERROR mismatched types + V0 = 1..=10, + //~^ ERROR mismatched types +} + +const B: &'static [A] = &[A::V0, A::V1(111)]; + +fn main() {} diff --git a/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.stderr b/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.stderr new file mode 100644 index 0000000000000..19491ce733d09 --- /dev/null +++ b/tests/ui/enum-discriminant/non-int-discriminant-promoted-ice-138660.stderr @@ -0,0 +1,33 @@ +error[E0308]: mismatched types + --> $DIR/non-int-discriminant-promoted-ice-138660.rs:5:17 + | +LL | V1(isize) = 1..=10, + | ^^^^^^ expected `isize`, found `RangeInclusive<{integer}>` + | + = note: expected type `isize` + found struct `std::ops::RangeInclusive<{integer}>` + = note: enum variant discriminant can only be of a primitive type compatible with the enum's `repr` + +error[E0308]: mismatched types + --> $DIR/non-int-discriminant-promoted-ice-138660.rs:7:10 + | +LL | V0 = 1..=10, + | ^^^^^^ expected `isize`, found `RangeInclusive<{integer}>` + | + = note: expected type `isize` + found struct `std::ops::RangeInclusive<{integer}>` + = note: enum variant discriminant can only be of a primitive type compatible with the enum's `repr` + +error[E0732]: `#[repr(inttype)]` must be specified for enums with explicit discriminants and non-unit variants + --> $DIR/non-int-discriminant-promoted-ice-138660.rs:3:1 + | +LL | enum A { + | ^^^^^^ +LL | +LL | V1(isize) = 1..=10, + | ------ explicit discriminant on non-unit variant specified here + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0732. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/enum-discriminant/size-of-discriminant-no-cycle.rs b/tests/ui/enum-discriminant/size-of-discriminant-no-cycle.rs new file mode 100644 index 0000000000000..09313735fd4c5 --- /dev/null +++ b/tests/ui/enum-discriminant/size-of-discriminant-no-cycle.rs @@ -0,0 +1,8 @@ +//@ check-pass +// Ensure that `size_of::()` as a discriminant does not cause a cycle error. + +enum Thing { + Variant = size_of::() as isize, +} + +fn main() {} diff --git a/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.next.stderr b/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.next.stderr new file mode 100644 index 0000000000000..bf3e6943f0d5a --- /dev/null +++ b/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.next.stderr @@ -0,0 +1,22 @@ +error[E0283]: type annotations needed + --> $DIR/constraint-from-nested-projection.rs:31:5 + | +LL | pick::<(), _>(); + | ^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `pick` + | +note: multiple `impl`s satisfying `(): Pick<_>` found + --> $DIR/constraint-from-nested-projection.rs:25:1 + | +LL | impl RequiresProject<'a>> Pick for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl Pick for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `pick` + --> $DIR/constraint-from-nested-projection.rs:28:12 + | +LL | fn pick, U>() {} + | ^^^^^^^ required by this bound in `pick` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.rs b/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.rs new file mode 100644 index 0000000000000..fda0fa7efa57c --- /dev/null +++ b/tests/ui/higher-ranked/leak-check/constraint-from-nested-projection.rs @@ -0,0 +1,33 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +//@[old] check-pass + +// Evaluate in the old solver does apply constraints from nested `Projection` obligations, +// as they can constrain otherwise unconstrained inference variables. This also allows +// `Projection` goals to otherwise influence its parent obligation by returning constraints +// from matching the impl header. +// +// The new solver entirely ignores region constraints from nested goals in the leak check. +// This is the one case where the the implementation of the new solver will actually weaken +// the leak check. + +trait ProjectStatic<'a> { + type Assoc; +} +impl ProjectStatic<'static> for () { + type Assoc = u32; +} + +trait RequiresProject<'a> {} +impl<'a, T: ProjectStatic<'a, Assoc = u32>> RequiresProject<'a> for T {} + +trait Pick {} +impl RequiresProject<'a>> Pick for T {} +impl Pick for T {} + +fn pick, U>() {} + +fn main() { + pick::<(), _>(); + //[next]~^ ERROR: type annotations needed +} diff --git a/tests/ui/sanitizer/cfi/fn-ptr-type-mismatch-recover.rs b/tests/ui/sanitizer/cfi/fn-ptr-type-mismatch-recover.rs new file mode 100644 index 0000000000000..069ac811f481d --- /dev/null +++ b/tests/ui/sanitizer/cfi/fn-ptr-type-mismatch-recover.rs @@ -0,0 +1,38 @@ +// Verifies that calling a function pointer with a mismatched type with CFI +// recovery enabled reports the failure and continues execution. + +//@ revisions: cfi cfi-minimal-runtime +// FIXME(#122848) Remove only-linux once OSX CFI binaries work +//@ only-linux +//@ ignore-backends: gcc +//@ [cfi] needs-sanitizer-cfi +//@ [cfi] needs-sanitizer-support +//@ [cfi-minimal-runtime] needs-sanitizer-cfi +//@ [cfi-minimal-runtime] needs-sanitizer-support +//@ compile-flags: -C target-feature=-crt-static +//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-minimal-runtime +//@ compile-flags: -C opt-level=0 -C codegen-units=1 -C lto +//@ compile-flags: -C prefer-dynamic=off +//@ compile-flags: -Z sanitizer=cfi +//@ [cfi] compile-flags: -Z sanitizer-cfi-recover=true +//@ [cfi-minimal-runtime] compile-flags: -Z sanitizer-cfi-recover=true +//@ [cfi-minimal-runtime] compile-flags: -Z sanitizer-cfi-minimal-runtime=true +//@ run-pass + +use std::hint::black_box; +use std::mem; + +fn add_one(x: i32) -> i32 { + x + 1 +} + +#[inline(never)] +fn call_with_mismatch(f: fn(i32) -> i32) { + let g: fn(i32, i32) -> i32 = unsafe { mem::transmute(f) }; + let res = g(1, 2); + assert_eq!(res, 2); +} + +fn main() { + call_with_mismatch(black_box(add_one)); +} diff --git a/tests/ui/sanitizer/cfi/fn-ptr-type-mismatch.rs b/tests/ui/sanitizer/cfi/fn-ptr-type-mismatch.rs index 6fe7eec7c6920..1e32a1042c848 100644 --- a/tests/ui/sanitizer/cfi/fn-ptr-type-mismatch.rs +++ b/tests/ui/sanitizer/cfi/fn-ptr-type-mismatch.rs @@ -1,19 +1,26 @@ // Verifies that calling a function pointer with a mismatched type triggers a // CFI violation and causes the process to trap. -//@ revisions: cfi kcfi +//@ revisions: cfi cfi-minimal-runtime kcfi // FIXME(#122848) Remove only-linux once OSX CFI binaries work //@ only-linux //@ ignore-backends: gcc //@ [cfi] needs-sanitizer-cfi //@ [cfi] needs-sanitizer-support +//@ [cfi-minimal-runtime] needs-sanitizer-cfi +//@ [cfi-minimal-runtime] needs-sanitizer-support //@ [kcfi] needs-sanitizer-kcfi //@ compile-flags: -C target-feature=-crt-static -//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer +//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-minimal-runtime //@ [cfi] compile-flags: -C opt-level=0 -C codegen-units=1 -C lto //@ [cfi] compile-flags: -C prefer-dynamic=off //@ [cfi] compile-flags: -Z sanitizer=cfi //@ [cfi] compile-flags: -Z sanitizer-cfi-diag=true +//@ [cfi-minimal-runtime] compile-flags: -C opt-level=0 -C codegen-units=1 -C lto +//@ [cfi-minimal-runtime] compile-flags: -C prefer-dynamic=off +//@ [cfi-minimal-runtime] compile-flags: -Z sanitizer=cfi +//@ [cfi-minimal-runtime] compile-flags: -Z sanitizer-cfi-diag=true +//@ [cfi-minimal-runtime] compile-flags: -Z sanitizer-cfi-minimal-runtime=true //@ [kcfi] compile-flags: -Z sanitizer=kcfi //@ [kcfi] compile-flags: -C panic=abort -C prefer-dynamic=off //@ run-fail-or-crash diff --git a/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi-recover-or-diag.rs b/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi-recover-or-diag.rs new file mode 100644 index 0000000000000..16f39f09ec7a0 --- /dev/null +++ b/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi-recover-or-diag.rs @@ -0,0 +1,11 @@ +// Verifies that `-Zsanitizer-cfi-minimal-runtime` requires +// `-Zsanitizer-cfi-recover` or `-Zsanitizer-cfi-diag`. +// +//@ needs-sanitizer-cfi +//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-minimal-runtime + +#![feature(no_core)] +#![no_core] +#![no_main] + +//~? ERROR `-Zsanitizer-cfi-minimal-runtime` requires `-Zsanitizer-cfi-recover` or `-Zsanitizer-cfi-diag` diff --git a/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi-recover-or-diag.stderr b/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi-recover-or-diag.stderr new file mode 100644 index 0000000000000..f3d483bef7eb7 --- /dev/null +++ b/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi-recover-or-diag.stderr @@ -0,0 +1,4 @@ +error: `-Zsanitizer-cfi-minimal-runtime` requires `-Zsanitizer-cfi-recover` or `-Zsanitizer-cfi-diag` + +error: aborting due to 1 previous error + diff --git a/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi.rs b/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi.rs new file mode 100644 index 0000000000000..cb68734608ac7 --- /dev/null +++ b/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi.rs @@ -0,0 +1,10 @@ +// Verifies that `-Zsanitizer-cfi-minimal-runtime` requires `-Zsanitizer=cfi`. +// +//@ needs-sanitizer-cfi +//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer-cfi-minimal-runtime + +#![feature(no_core)] +#![no_core] +#![no_main] + +//~? ERROR `-Zsanitizer-cfi-minimal-runtime` requires `-Zsanitizer=cfi` diff --git a/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi.stderr b/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi.stderr new file mode 100644 index 0000000000000..5cb83e40dc0c4 --- /dev/null +++ b/tests/ui/sanitizer/cfi/minimal-runtime-requires-cfi.stderr @@ -0,0 +1,4 @@ +error: `-Zsanitizer-cfi-minimal-runtime` requires `-Zsanitizer=cfi` + +error: aborting due to 1 previous error + diff --git a/tests/ui/statics/crt-static-pauthtest.rs b/tests/ui/statics/crt-static-pauthtest.rs index bc5badc600d88..a3fed7f9379ef 100644 --- a/tests/ui/statics/crt-static-pauthtest.rs +++ b/tests/ui/statics/crt-static-pauthtest.rs @@ -1,9 +1,8 @@ //@ compile-flags: -C target-feature=+crt-static --target aarch64-unknown-linux-pauthtest //@ needs-llvm-components: aarch64 -//@ only-pauthtest - #![feature(no_core)] +#![no_core] #![no_main] //~? ERROR pointer authentication requires dynamic linking. Statically linked libc is incompatible, disable it using `-C target-feature=-crt-static` diff --git a/tests/ui/target_modifiers/auxiliary/cfi-minimal-runtime.rs b/tests/ui/target_modifiers/auxiliary/cfi-minimal-runtime.rs new file mode 100644 index 0000000000000..aacea1ee65dd2 --- /dev/null +++ b/tests/ui/target_modifiers/auxiliary/cfi-minimal-runtime.rs @@ -0,0 +1,7 @@ +//@ no-prefer-dynamic +//@ needs-sanitizer-cfi +//@ compile-flags: -Clto -Zsanitizer=cfi -Zsanitizer-cfi-recover -Zsanitizer-cfi-minimal-runtime + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] diff --git a/tests/ui/target_modifiers/auxiliary/pauth.rs b/tests/ui/target_modifiers/auxiliary/pauth.rs index 761f4a520a4d2..32bd7651c0b44 100644 --- a/tests/ui/target_modifiers/auxiliary/pauth.rs +++ b/tests/ui/target_modifiers/auxiliary/pauth.rs @@ -1,6 +1,7 @@ //@ compile-flags: --target aarch64-unknown-linux-pauthtest -Zpointer-authentication=+calls,+init-fini //@ needs-llvm-components: aarch64 -//@ only-pauthtest +//@ no-prefer-dynamic +//@ ignore-backends: gcc #![feature(no_core)] #![crate_type = "rlib"] diff --git a/tests/ui/target_modifiers/incompatible_pauth.error_generated.stderr b/tests/ui/target_modifiers/incompatible_pauth.error_generated.stderr index ddc05e4b55322..1e9390d37e822 100644 --- a/tests/ui/target_modifiers/incompatible_pauth.error_generated.stderr +++ b/tests/ui/target_modifiers/incompatible_pauth.error_generated.stderr @@ -1,8 +1,4 @@ error: mixing `-Zpointer-authentication` will cause an ABI mismatch in crate `incompatible_pauth` - --> $DIR/incompatible_pauth.rs:14:1 - | -LL | #![feature(no_core)] - | ^ | = help: the `-Zpointer-authentication` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely = note: `-Zpointer-authentication=+calls,-init-fini` in this crate is incompatible with `-Zpointer-authentication=+calls,+init-fini` in dependency `pauth` diff --git a/tests/ui/target_modifiers/incompatible_pauth.rs b/tests/ui/target_modifiers/incompatible_pauth.rs index 6fe77a6916568..302e845e8bd4f 100644 --- a/tests/ui/target_modifiers/incompatible_pauth.rs +++ b/tests/ui/target_modifiers/incompatible_pauth.rs @@ -9,12 +9,12 @@ //@ [ok_reverse_order] check-pass //@ [error_generated] compile-flags: -Zpointer-authentication=+calls,-init-fini //@ needs-llvm-components: aarch64 -//@ only-pauthtest +//@ ignore-backends: gcc #![feature(no_core)] -//[error_generated]~^ ERROR mixing `-Zpointer-authentication` will cause an ABI mismatch in crate -//`incompatible_pauth` #![crate_type = "rlib"] #![no_core] extern crate pauth; + +//[error_generated]~? ERROR mixing `-Zpointer-authentication` will cause an ABI mismatch in crate `incompatible_pauth` diff --git a/tests/ui/target_modifiers/sanitizer-cfi-minimal-runtime.rs b/tests/ui/target_modifiers/sanitizer-cfi-minimal-runtime.rs new file mode 100644 index 0000000000000..45c6ad7b521a3 --- /dev/null +++ b/tests/ui/target_modifiers/sanitizer-cfi-minimal-runtime.rs @@ -0,0 +1,18 @@ +// For CFI, the helper flag -Zsanitizer-cfi-minimal-runtime should also be a target modifier. + +//@ needs-sanitizer-cfi +//@ aux-build:cfi-minimal-runtime.rs + +//@ revisions: ok wrong_flag wrong_sanitizer +//@[ok] compile-flags: -Clto -Zsanitizer=cfi -Zsanitizer-cfi-recover -Zsanitizer-cfi-minimal-runtime +//@[wrong_flag] compile-flags: -Clto -Zsanitizer=cfi -Zsanitizer-cfi-recover +//@[ok] check-pass + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] + +extern crate cfi_minimal_runtime; + +//[wrong_flag]~? ERROR mixing `-Zsanitizer-cfi-minimal-runtime` will cause an ABI mismatch in crate `sanitizer_cfi_minimal_runtime` +//[wrong_sanitizer]~? ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizer_cfi_minimal_runtime` diff --git a/tests/ui/target_modifiers/sanitizer-cfi-minimal-runtime.wrong_flag.stderr b/tests/ui/target_modifiers/sanitizer-cfi-minimal-runtime.wrong_flag.stderr new file mode 100644 index 0000000000000..6dfc1a3bb7d16 --- /dev/null +++ b/tests/ui/target_modifiers/sanitizer-cfi-minimal-runtime.wrong_flag.stderr @@ -0,0 +1,9 @@ +error: mixing `-Zsanitizer-cfi-minimal-runtime` will cause an ABI mismatch in crate `sanitizer_cfi_minimal_runtime` + | + = help: the `-Zsanitizer-cfi-minimal-runtime` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely + = note: `-Zsanitizer-cfi-minimal-runtime` is unset in this crate which is incompatible with `-Zsanitizer-cfi-minimal-runtime` being set in dependency `cfi_minimal_runtime` + = help: set `-Zsanitizer-cfi-minimal-runtime` in this crate or unset `-Zsanitizer-cfi-minimal-runtime` in `cfi_minimal_runtime` + = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer-cfi-minimal-runtime` to silence this error + +error: aborting due to 1 previous error + diff --git a/tests/ui/target_modifiers/sanitizer-cfi-minimal-runtime.wrong_sanitizer.stderr b/tests/ui/target_modifiers/sanitizer-cfi-minimal-runtime.wrong_sanitizer.stderr new file mode 100644 index 0000000000000..32ba848b3b2ad --- /dev/null +++ b/tests/ui/target_modifiers/sanitizer-cfi-minimal-runtime.wrong_sanitizer.stderr @@ -0,0 +1,9 @@ +error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizer_cfi_minimal_runtime` + | + = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely + = note: `-Zsanitizer` is unset in this crate which is incompatible with `-Zsanitizer=cfi` in dependency `cfi_minimal_runtime` + = help: set `-Zsanitizer=cfi` in this crate or unset `-Zsanitizer` in `cfi_minimal_runtime` + = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error + +error: aborting due to 1 previous error + diff --git a/tests/ui/traits/mutually-recursive-impls-hang-143018.current.stderr b/tests/ui/traits/mutually-recursive-impls-hang-143018.current.stderr new file mode 100644 index 0000000000000..c6410d7eac39c --- /dev/null +++ b/tests/ui/traits/mutually-recursive-impls-hang-143018.current.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/mutually-recursive-impls-hang-143018.rs:26:5 + | +LL | impls_trait::(); + | ^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `impls_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/mutually-recursive-impls-hang-143018.next.stderr b/tests/ui/traits/mutually-recursive-impls-hang-143018.next.stderr new file mode 100644 index 0000000000000..680182b7350c8 --- /dev/null +++ b/tests/ui/traits/mutually-recursive-impls-hang-143018.next.stderr @@ -0,0 +1,15 @@ +error[E0275]: overflow evaluating the requirement `A: Trait<_>` + --> $DIR/mutually-recursive-impls-hang-143018.rs:26:19 + | +LL | impls_trait::(); + | ^ + | +note: required by a bound in `impls_trait` + --> $DIR/mutually-recursive-impls-hang-143018.rs:24:19 + | +LL | fn impls_trait, V>() {} + | ^^^^^^^^ required by this bound in `impls_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/mutually-recursive-impls-hang-143018.rs b/tests/ui/traits/mutually-recursive-impls-hang-143018.rs new file mode 100644 index 0000000000000..8db92502a8621 --- /dev/null +++ b/tests/ui/traits/mutually-recursive-impls-hang-143018.rs @@ -0,0 +1,29 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Regression test for . + +trait Trait {} +struct A; +struct B; + +impl Trait for A +where + A: Trait, + B: Trait, +{ +} + +impl Trait for B +where + A: Trait, +{ +} + +fn impls_trait, V>() {} +fn main() { + impls_trait::(); + //[current]~^ ERROR type annotations needed + //[next]~^^ ERROR overflow evaluating the requirement +} diff --git a/tests/ui/traits/next-solver/overflow/dont-lower-depth-for-witness-and-rigid-opaque.rs b/tests/ui/traits/next-solver/overflow/dont-lower-depth-for-witness-and-rigid-opaque.rs new file mode 100644 index 0000000000000..c4d493ec0f8d2 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/dont-lower-depth-for-witness-and-rigid-opaque.rs @@ -0,0 +1,31 @@ +//@ compile-flags: -Znext-solver +//@ edition: 2024 +//@ check-pass + +// We don't increase recursion depth when proving auto traits for witness +// and rigid opaques. This is to mitigate the FCW warnings in deeply nested +// async calls. See #159228. + +#![recursion_limit = "6"] + +async fn foo1() {} + +async fn foo2() { + foo1().await +} +async fn foo3() { + foo2().await +} +async fn foo4() { + foo3().await +} + +async fn foo5() { + foo4().await +} + +fn assert_send(_: T) {} + +fn main() { + assert_send(foo5()); +}