Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions compiler/rustc_abi/src/layout/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,19 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
/// function call isn't allowed (a.k.a. `va_list`).
///
/// This function handles transparent types automatically.
pub fn pass_indirectly_in_non_rustic_abis<C>(mut self, cx: &C) -> bool
pub fn pass_indirectly_in_non_rustic_abis<C>(self, cx: &C) -> bool
where
Ty: TyAbiInterface<'a, C> + Copy,
{
let base = self.peel_transparent_wrappers(cx);
Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(base)
}

/// Recursively peel away transparent wrappers, returning the inner value.
///
/// The return value is not `repr(transparent)` and/or does
/// not have a non-1zst field.
pub fn peel_transparent_wrappers<C>(mut self, cx: &C) -> Self
where
Ty: TyAbiInterface<'a, C> + Copy,
{
Expand All @@ -300,7 +312,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
self = field;
}

Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(self)
self
}

/// Finds the one field that is not a 1-ZST.
Expand Down
26 changes: 11 additions & 15 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use rustc_abi::{BackendRepr, ExternAbi, Float, Integer, Primitive, Scalar};
use rustc_abi::ExternAbi;
use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
use rustc_hir::{self as hir, HirId};
use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
use rustc_middle::ty::layout::{LayoutCx, LayoutError, TyAndLayout};
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::Span;

Expand Down Expand Up @@ -150,34 +150,30 @@ fn is_valid_cmse_output<'tcx>(

let typing_env = ty::TypingEnv::fully_monomorphized();
let layout = tcx.layout_of(typing_env.as_query_input(return_type))?;
let layout_cx = LayoutCx::new(tcx, typing_env);

if !is_valid_cmse_output_layout(layout) {
if !is_valid_cmse_output_layout(layout_cx, layout) {
dcx.emit_err(errors::CmseOutputStackSpill { span: fn_decl.output.span(), abi });
}

Ok(())
}

/// Returns whether the output will fit into the available registers
fn is_valid_cmse_output_layout<'tcx>(layout: TyAndLayout<'tcx>) -> bool {
fn is_valid_cmse_output_layout<'tcx>(cx: LayoutCx<'tcx>, layout: TyAndLayout<'tcx>) -> bool {
let size = layout.layout.size().bytes();

if size <= 4 {
return true;
} else if size > 8 {
} else if size != 8 {
return false;
}

// Accept scalar 64-bit types.
let BackendRepr::Scalar(scalar) = layout.layout.backend_repr else {
return false;
};

let Scalar::Initialized { value, .. } = scalar else {
return false;
};

matches!(value, Primitive::Int(Integer::I64, _) | Primitive::Float(Float::F64))
// Accept (transparently wrapped) scalar 64-bit primitives.
matches!(
layout.peel_transparent_wrappers(&cx).ty.kind(),
ty::Int(ty::IntTy::I64) | ty::Uint(ty::UintTy::U64) | ty::Float(ty::FloatTy::F64)
)
}

fn should_emit_layout_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError<'tcx>) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/build_steps/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ macro_rules! tool_check_step {
const IS_HOST: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.paths(&[ $path, $( $alt_path ),* ])
run.path($path) $( .path( $alt_path ) )*
}

fn is_default_step(_builder: &Builder<'_>) -> bool {
Expand Down
6 changes: 3 additions & 3 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3156,7 +3156,7 @@ impl Step for CrateRustdoc {
const IS_HOST: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.paths(&["src/librustdoc", "src/tools/rustdoc"])
run.path("src/librustdoc").path("src/tools/rustdoc")
}

fn is_default_step(_builder: &Builder<'_>) -> bool {
Expand Down Expand Up @@ -3817,7 +3817,7 @@ impl Step for CodegenCranelift {
const IS_HOST: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.paths(&["compiler/rustc_codegen_cranelift"])
run.path("compiler/rustc_codegen_cranelift")
}

fn is_default_step(_builder: &Builder<'_>) -> bool {
Expand Down Expand Up @@ -3938,7 +3938,7 @@ impl Step for CodegenGCC {
const IS_HOST: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.paths(&["compiler/rustc_codegen_gcc"])
run.path("compiler/rustc_codegen_gcc")
}

fn is_default_step(_builder: &Builder<'_>) -> bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,5 @@ expression: bench
- Set({bench::compiler/rustc_windows_rc})
[Bench] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({bench::src/librustdoc, bench::src/tools/rustdoc})
- Set({bench::src/librustdoc})
- Set({bench::src/tools/rustdoc})
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ expression: check
- Set({check::compiler/rustc_windows_rc})
[Check] check::Rustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({check::src/librustdoc, check::src/tools/rustdoc})
- Set({check::src/librustdoc})
- Set({check::src/tools/rustdoc})
[Check] check::CraneliftCodegenBackend
targets: [x86_64-unknown-linux-gnu]
- Set({check::cg_clif})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ expression: check compiletest --include-default-paths
- Set({check::compiler/rustc_windows_rc})
[Check] check::Rustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({check::src/librustdoc, check::src/tools/rustdoc})
- Set({check::src/librustdoc})
- Set({check::src/tools/rustdoc})
[Check] check::CraneliftCodegenBackend
targets: [x86_64-unknown-linux-gnu]
- Set({check::cg_clif})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ expression: fix
- Set({fix::compiler/rustc_windows_rc})
[Fix] check::Rustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({fix::src/librustdoc, fix::src/tools/rustdoc})
- Set({fix::src/librustdoc})
- Set({fix::src/tools/rustdoc})
[Fix] check::CraneliftCodegenBackend
targets: [x86_64-unknown-linux-gnu]
- Set({fix::cg_clif})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ expression: test
- Set({test::compiler/rustc_windows_rc})
[Test] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/librustdoc, test::src/tools/rustdoc})
- Set({test::src/librustdoc})
- Set({test::src/tools/rustdoc})
[Test] test::CrateRustdocJsonTypes
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/rustdoc-json-types})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ expression: test librustdoc rustdoc
---
[Test] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/librustdoc, test::src/tools/rustdoc})
- Set({test::src/librustdoc})
- Set({test::src/tools/rustdoc})
[Test] test::RustdocBook
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/doc/rustdoc})
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ expression: test --skip=coverage
- Set({test::compiler/rustc_windows_rc})
[Test] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/librustdoc, test::src/tools/rustdoc})
- Set({test::src/librustdoc})
- Set({test::src/tools/rustdoc})
[Test] test::CrateRustdocJsonTypes
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/rustdoc-json-types})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ expression: test --skip=tests
- Set({test::compiler/rustc_windows_rc})
[Test] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/librustdoc, test::src/tools/rustdoc})
- Set({test::src/librustdoc})
- Set({test::src/tools/rustdoc})
[Test] test::CrateRustdocJsonTypes
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/rustdoc-json-types})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ expression: test --skip=tests --skip=coverage-map --skip=coverage-run --skip=lib
- Set({test::compiler/rustc_windows_rc})
[Test] test::CrateRustdoc
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/librustdoc, test::src/tools/rustdoc})
- Set({test::src/librustdoc})
- Set({test::src/tools/rustdoc})
[Test] test::CrateRustdocJsonTypes
targets: [x86_64-unknown-linux-gnu]
- Set({test::src/rustdoc-json-types})
Expand Down
39 changes: 10 additions & 29 deletions src/bootstrap/src/core/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,38 +558,19 @@ impl<'a> ShouldRun<'a> {
/// single, non-aliased path
///
/// Must be an on-disk path; use `alias` for names that do not correspond to on-disk paths.
pub fn path(self, path: &str) -> Self {
self.paths(&[path])
}

/// Multiple aliases for the same job.
///
/// This differs from [`path`] in that multiple calls to path will end up calling `make_run`
/// multiple times, whereas a single call to `paths` will only ever generate a single call to
/// `make_run`.
///
/// This is analogous to `all_krates`, although `all_krates` is gone now. Prefer [`path`] where possible.
///
/// [`path`]: ShouldRun::path
pub fn paths(mut self, paths: &[&str]) -> Self {
pub fn path(mut self, path: &str) -> Self {
let submodules_paths = self.builder.submodule_paths();

self.paths.insert(PathSet::Set(
paths
.iter()
.map(|p| {
// assert only if `p` isn't submodule
if !submodules_paths.iter().any(|sm_p| p.contains(sm_p)) {
assert!(
self.builder.src.join(p).exists(),
"`should_run.paths` should correspond to real on-disk paths - use `alias` if there is no relevant path: {p}"
);
}
// assert only if `p` isn't submodule
if !submodules_paths.iter().any(|sm_p| path.contains(sm_p)) {
assert!(
self.builder.src.join(path).exists(),
"`should_run.path` should correspond to a real on-disk path - use `alias` if there is no relevant path: {path}"
);
}

TaskPath { path: p.into(), kind: Some(self.kind) }
})
.collect(),
));
let task = TaskPath { path: path.into(), kind: Some(self.kind) };
self.paths.insert(PathSet::Set(BTreeSet::from_iter([task])));
self
}

Expand Down
12 changes: 8 additions & 4 deletions tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ use minicore::*;
#[repr(C)]
pub struct ReprCU64(u64);

#[repr(Rust)]
pub struct ReprRustU64(u64);

#[repr(C)]
pub struct ReprCBytes(u8, u8, u8, u8, u8);

Expand All @@ -25,10 +28,11 @@ pub struct ReprCAlign16(u16);
#[no_mangle]
pub fn test(
f1: extern "cmse-nonsecure-call" fn() -> ReprCU64, //~ ERROR [E0798]
f2: extern "cmse-nonsecure-call" fn() -> ReprCBytes, //~ ERROR [E0798]
f3: extern "cmse-nonsecure-call" fn() -> U64Compound, //~ ERROR [E0798]
f4: extern "cmse-nonsecure-call" fn() -> ReprCAlign16, //~ ERROR [E0798]
f5: extern "cmse-nonsecure-call" fn() -> [u8; 5], //~ ERROR [E0798]
f2: extern "cmse-nonsecure-call" fn() -> ReprRustU64, //~ ERROR [E0798]
f3: extern "cmse-nonsecure-call" fn() -> ReprCBytes, //~ ERROR [E0798]
f4: extern "cmse-nonsecure-call" fn() -> U64Compound, //~ ERROR [E0798]
f5: extern "cmse-nonsecure-call" fn() -> ReprCAlign16, //~ ERROR [E0798]
f6: extern "cmse-nonsecure-call" fn() -> [u8; 5], //~ ERROR [E0798]
) {
}

Expand Down
37 changes: 23 additions & 14 deletions tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers
--> $DIR/return-via-stack.rs:37:48
--> $DIR/return-via-stack.rs:41:48
|
LL | u128: extern "cmse-nonsecure-call" fn() -> u128,
| ^^^^ this type doesn't fit in the available registers
Expand All @@ -8,7 +8,7 @@ LL | u128: extern "cmse-nonsecure-call" fn() -> u128,
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size

error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers
--> $DIR/return-via-stack.rs:38:48
--> $DIR/return-via-stack.rs:42:48
|
LL | i128: extern "cmse-nonsecure-call" fn() -> i128,
| ^^^^ this type doesn't fit in the available registers
Expand All @@ -17,7 +17,7 @@ LL | i128: extern "cmse-nonsecure-call" fn() -> i128,
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size

error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers
--> $DIR/return-via-stack.rs:27:46
--> $DIR/return-via-stack.rs:30:46
|
LL | f1: extern "cmse-nonsecure-call" fn() -> ReprCU64,
| ^^^^^^^^ this type doesn't fit in the available registers
Expand All @@ -26,43 +26,52 @@ LL | f1: extern "cmse-nonsecure-call" fn() -> ReprCU64,
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size

error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers
--> $DIR/return-via-stack.rs:28:46
--> $DIR/return-via-stack.rs:31:46
|
LL | f2: extern "cmse-nonsecure-call" fn() -> ReprRustU64,
| ^^^^^^^^^^^ this type doesn't fit in the available registers
|
LL | f2: extern "cmse-nonsecure-call" fn() -> ReprCBytes,
= note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size

error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers
--> $DIR/return-via-stack.rs:32:46
|
LL | f3: extern "cmse-nonsecure-call" fn() -> ReprCBytes,
| ^^^^^^^^^^ this type doesn't fit in the available registers
|
= note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size

error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers
--> $DIR/return-via-stack.rs:29:46
--> $DIR/return-via-stack.rs:33:46
|
LL | f3: extern "cmse-nonsecure-call" fn() -> U64Compound,
LL | f4: extern "cmse-nonsecure-call" fn() -> U64Compound,
| ^^^^^^^^^^^ this type doesn't fit in the available registers
|
= note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size

error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers
--> $DIR/return-via-stack.rs:30:46
--> $DIR/return-via-stack.rs:34:46
|
LL | f4: extern "cmse-nonsecure-call" fn() -> ReprCAlign16,
LL | f5: extern "cmse-nonsecure-call" fn() -> ReprCAlign16,
| ^^^^^^^^^^^^ this type doesn't fit in the available registers
|
= note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size

error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers
--> $DIR/return-via-stack.rs:31:46
--> $DIR/return-via-stack.rs:35:46
|
LL | f5: extern "cmse-nonsecure-call" fn() -> [u8; 5],
LL | f6: extern "cmse-nonsecure-call" fn() -> [u8; 5],
| ^^^^^^^ this type doesn't fit in the available registers
|
= note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size

error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers
--> $DIR/return-via-stack.rs:53:46
--> $DIR/return-via-stack.rs:57:46
|
LL | f1: extern "cmse-nonsecure-call" fn() -> ReprRustUnionU64,
| ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
Expand All @@ -71,14 +80,14 @@ LL | f1: extern "cmse-nonsecure-call" fn() -> ReprRustUnionU64,
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size

error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers
--> $DIR/return-via-stack.rs:54:46
--> $DIR/return-via-stack.rs:58:46
|
LL | f2: extern "cmse-nonsecure-call" fn() -> ReprCUnionU64,
| ^^^^^^^^^^^^^ this type doesn't fit in the available registers
|
= note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size

error: aborting due to 9 previous errors
error: aborting due to 10 previous errors

For more information about this error, try `rustc --explain E0798`.
Loading
Loading