Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 4b8291f

Browse files
committed
styling fixes, skipped_targets clearly defined, bitXor removed, clang status check
1 parent 95f7416 commit 4b8291f

File tree

3 files changed

+138
-101
lines changed

3 files changed

+138
-101
lines changed

tests/auxiliary/minicore.rs

Lines changed: 55 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,60 @@
2121
#![no_std]
2222
#![no_core]
2323

24+
/// Vendored from the 'cfg_if' crate
25+
26+
macro_rules! cfg_if {
27+
// match if/else chains with a final `else`
28+
(
29+
$(
30+
if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
31+
) else+
32+
else { $( $e_tokens:tt )* }
33+
) => {
34+
cfg_if! {
35+
@__items () ;
36+
$(
37+
(( $i_meta ) ( $( $i_tokens )* )) ,
38+
)+
39+
(() ( $( $e_tokens )* )) ,
40+
}
41+
};
42+
43+
// Internal and recursive macro to emit all the items
44+
//
45+
// Collects all the previous cfgs in a list at the beginning, so they can be
46+
// negated. After the semicolon is all the remaining items.
47+
(@__items ( $( $_:meta , )* ) ; ) => {};
48+
(
49+
@__items ( $( $no:meta , )* ) ;
50+
(( $( $yes:meta )? ) ( $( $tokens:tt )* )) ,
51+
$( $rest:tt , )*
52+
) => {
53+
// Emit all items within one block, applying an appropriate #[cfg]. The
54+
// #[cfg] will require all `$yes` matchers specified and must also negate
55+
// all previous matchers.
56+
#[cfg(all(
57+
$( $yes , )?
58+
not(any( $( $no ),* ))
59+
))]
60+
cfg_if! { @__identity $( $tokens )* }
61+
62+
// Recurse to emit all other items in `$rest`, and when we do so add all
63+
// our `$yes` matchers to the list of `$no` matchers as future emissions
64+
// will have to negate everything we just matched as well.
65+
cfg_if! {
66+
@__items ( $( $no , )* $( $yes , )? ) ;
67+
$( $rest , )*
68+
}
69+
};
70+
71+
// Internal macro to make __apply work out right for different match types,
72+
// because of how macros match/expand stuff.
73+
(@__identity $( $tokens:tt )* ) => {
74+
$( $tokens )*
75+
};
76+
}
77+
2478
// `core` has some exotic `marker_impls!` macro for handling the with-generics cases, but for our
2579
// purposes, just use a simple macro_rules macro.
2680
macro_rules! impl_marker_trait {
@@ -102,6 +156,7 @@ macro_rules! concat {
102156
/* compiler built-in */
103157
};
104158
}
159+
105160
#[rustc_builtin_macro]
106161
#[macro_export]
107162
macro_rules! stringify {
@@ -110,58 +165,6 @@ macro_rules! stringify {
110165
};
111166
}
112167

113-
macro_rules! cfg_if {
114-
// match if/else chains with a final `else`
115-
(
116-
$(
117-
if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
118-
) else+
119-
else { $( $e_tokens:tt )* }
120-
) => {
121-
cfg_if! {
122-
@__items () ;
123-
$(
124-
(( $i_meta ) ( $( $i_tokens )* )) ,
125-
)+
126-
(() ( $( $e_tokens )* )) ,
127-
}
128-
};
129-
130-
// Internal and recursive macro to emit all the items
131-
//
132-
// Collects all the previous cfgs in a list at the beginning, so they can be
133-
// negated. After the semicolon is all the remaining items.
134-
(@__items ( $( $_:meta , )* ) ; ) => {};
135-
(
136-
@__items ( $( $no:meta , )* ) ;
137-
(( $( $yes:meta )? ) ( $( $tokens:tt )* )) ,
138-
$( $rest:tt , )*
139-
) => {
140-
// Emit all items within one block, applying an appropriate #[cfg]. The
141-
// #[cfg] will require all `$yes` matchers specified and must also negate
142-
// all previous matchers.
143-
#[cfg(all(
144-
$( $yes , )?
145-
not(any( $( $no ),* ))
146-
))]
147-
cfg_if! { @__identity $( $tokens )* }
148-
149-
// Recurse to emit all other items in `$rest`, and when we do so add all
150-
// our `$yes` matchers to the list of `$no` matchers as future emissions
151-
// will have to negate everything we just matched as well.
152-
cfg_if! {
153-
@__items ( $( $no , )* $( $yes , )? ) ;
154-
$( $rest , )*
155-
}
156-
};
157-
158-
// Internal macro to make __apply work out right for different match types,
159-
// because of how macros match/expand stuff.
160-
(@__identity $( $tokens:tt )* ) => {
161-
$( $tokens )*
162-
};
163-
}
164-
165168
#[macro_export]
166169
macro_rules! panic {
167170
($msg:literal) => {
@@ -208,19 +211,6 @@ impl PartialEq for bool {
208211
}
209212
}
210213

211-
#[lang = "bitxor"]
212-
pub trait BitXor<Rhs = Self> {
213-
type Output;
214-
fn bitxor(self, rhs: Rhs) -> Self::Output;
215-
}
216-
217-
impl BitXor for bool {
218-
type Output = bool;
219-
fn bitxor(self, rhs: bool) -> bool {
220-
(self || rhs) && !(self && rhs)
221-
}
222-
}
223-
224214
#[lang = "not"]
225215
pub trait Not {
226216
type Output;

tests/run-make/core-ffi-typecheck-clang/rmake.rs

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,52 @@
11
//@ needs-force-clang-based-tests
2+
// This test checks that the clang defines for each target allign with the core ffi types defined in
3+
// mod.rs. Therefore each rust target is queried and the clang defines for each target are read and
4+
// compared to the core sizes to verify all types and sizes allign at buildtime.
5+
//
6+
// If this test fails because Rust adds a target that Clang does not support, this target should be
7+
// added to SKIPPED_TARGETS.
28

39
use run_make_support::{clang, regex, rfs, rustc};
410

11+
// It is not possible to run the Rust test-suite on these targets.
512
const SKIPPED_TARGETS: &[&str] = &[
6-
"riscv", //error: unknown target triple 'riscv32e-unknown-none-elf'
7-
"wasm", //error: unknown target triple 'wasm32v1-none'
8-
"xtensa", //error: unknown target triple 'xtensa-esp32-espidf'
13+
"riscv32gc-unknown-linux-gnu",
14+
"riscv32gc-unknown-linux-musl",
15+
"riscv32im-risc0-zkvm-elf",
16+
"riscv32imac-esp-espidf",
17+
"riscv32imafc-esp-espidf",
18+
"riscv32imafc-unknown-nuttx-elf",
19+
"riscv32imc-esp-espidf",
20+
"riscv32imac-unknown-nuttx-elf",
21+
"riscv32imac-unknown-xous-elf",
22+
"riscv32imc-unknown-nuttx-elf",
23+
"riscv32e-unknown-none-elf",
24+
"riscv32em-unknown-none-elf",
25+
"riscv32emc-unknown-none-elf",
26+
"riscv32i-unknown-none-elf",
27+
"riscv32im-unknown-none-elf",
28+
"riscv32imc-unknown-none-elf",
29+
"riscv32ima-unknown-none-elf",
30+
"riscv32imac-unknown-none-elf",
31+
"riscv32imafc-unknown-none-elf",
32+
"riscv64gc-unknown-freebsd",
33+
"riscv64gc-unknown-fuchsia",
34+
"riscv64gc-unknown-hermit",
35+
"riscv64gc-unknown-linux-gnu",
36+
"riscv64gc-unknown-linux-musl",
37+
"riscv64gc-unknown-netbsd",
38+
"riscv64gc-unknown-none-elf",
39+
"riscv64gc-unknown-nuttx-elf",
40+
"riscv64gc-unknown-openbsd",
41+
"riscv64imac-unknown-none-elf",
42+
"riscv64imac-unknown-nuttx-elf",
43+
"wasm32v1-none",
44+
"xtensa-esp32-espidf",
45+
"xtensa-esp32-none-elf",
46+
"xtensa-esp32s2-espidf",
47+
"xtensa-esp32s2-none-elf",
48+
"xtensa-esp32s3-espidf",
49+
"xtensa-esp32s3-none-elf",
950
];
1051

1152
fn main() {
@@ -16,13 +57,18 @@ fn main() {
1657
regex_mod();
1758

1859
for target in targets.lines() {
19-
if SKIPPED_TARGETS.iter().any(|prefix| target.starts_with(prefix)) {
60+
if SKIPPED_TARGETS.iter().any(|&to_skip_target| target == to_skip_target) {
2061
continue;
2162
}
2263

64+
// Run Clang's preprocessor for the relevant target, printing default macro definitions.
2365
let clang_output =
2466
clang().args(&["-E", "-dM", "-x", "c", "/dev/null", "-target", target]).run();
2567

68+
if !clang_output.status().success() {
69+
continue;
70+
}
71+
2672
let defines = String::from_utf8(clang_output.stdout()).expect("Invalid UTF-8");
2773

2874
let minicore_content = rfs::read_to_string(&minicore_path);
@@ -33,13 +79,16 @@ fn main() {
3379
#![feature(link_cfg)]
3480
#![allow(unused)]
3581
#![crate_type = "rlib"]
36-
{}
82+
83+
/* begin minicore content */
84+
{minicore_content}
85+
/* end minicore content */
86+
3787
#[path = "processed_mod.rs"]
3888
mod ffi;
3989
#[path = "tests.rs"]
4090
mod tests;
41-
"#,
42-
minicore_content
91+
"#
4392
);
4493

4594
rmake_content.push_str(&format!(
@@ -54,7 +103,7 @@ fn main() {
54103
const CLANG_C_DOUBLE_SIZE: usize = {};
55104
",
56105
parse_size(&defines, "CHAR"),
57-
parse_signed(&defines, "CHAR"),
106+
char_is_signed(&defines),
58107
parse_size(&defines, "SHORT"),
59108
parse_size(&defines, "INT"),
60109
parse_size(&defines, "LONG"),
@@ -63,20 +112,20 @@ fn main() {
63112
parse_size(&defines, "DOUBLE"),
64113
));
65114

66-
// Write to target-specific rmake file
67-
let mut file_name = format!("{}_rmake.rs", target.replace("-", "_"));
115+
// Generate a target-specific rmake file.
116+
// If type misalignments occur, use the generated rmake file name to identify the failing target.
117+
// Replace dots (.) and hyphens (-) in the target name with underscores to ensure valid filenames.
118+
let file_name = format!("{}_rmake.rs", target.replace("-", "_").replace(".", "_"));
68119

69-
if target.starts_with("thumbv8m") {
70-
file_name = String::from("thumbv8m_rmake.rs");
71-
}
72-
73-
rfs::create_file(&file_name);
120+
// Attempt to build the test file for the relevant target. Tests use constant evaluation,
121+
// so running is not necessary.
74122
rfs::write(&file_name, rmake_content);
75123
let rustc_output = rustc()
76124
.arg("-Zunstable-options")
77125
.arg("--emit=metadata")
78126
.arg("--target")
79127
.arg(target)
128+
.arg("-o-")
80129
.arg(&file_name)
81130
.run();
82131
rfs::remove_file(&file_name);
@@ -89,6 +138,7 @@ fn main() {
89138
rfs::remove_file("processed_mod.rs");
90139
}
91140

141+
/// Get a list of available targets for 'rustc'.
92142
fn get_target_list() -> String {
93143
let completed_process = rustc().arg("--print").arg("target-list").run();
94144
String::from_utf8(completed_process.stdout()).expect("error not a string")
@@ -113,18 +163,11 @@ fn parse_size(defines: &str, type_name: &str) -> usize {
113163
panic!("Could not find size definition for type: {}", type_name);
114164
}
115165

116-
// Helper to parse signedness from clang defines
117-
fn parse_signed(defines: &str, type_name: &str) -> bool {
118-
match type_name.to_uppercase().as_str() {
119-
"CHAR" => {
120-
// Check if char is explicitly unsigned
121-
!defines.lines().any(|line| line.contains("__CHAR_UNSIGNED__"))
122-
}
123-
_ => true,
124-
}
166+
fn char_is_signed(defines: &str) -> bool {
167+
!defines.lines().any(|line| line.contains("__CHAR_UNSIGNED__"))
125168
}
126169

127-
// Parse core/ffi/mod.rs to retrieve only necessary macros and type defines
170+
/// Parse core/ffi/mod.rs to retrieve only necessary macros and type defines
128171
fn regex_mod() {
129172
let mod_path = run_make_support::source_root().join("library/core/src/ffi/mod.rs");
130173
let mut content = rfs::read_to_string(&mod_path);
@@ -157,7 +200,7 @@ fn regex_mod() {
157200
re = regex::Regex::new(r"(?s)impl fmt::Debug for.*?\{.*?\}").unwrap();
158201
content = re.replace_all(&content, "").to_string();
159202

160-
let file_name = format!("processed_mod.rs");
203+
let file_name = "processed_mod.rs";
161204

162205
rfs::create_file(&file_name);
163206
rfs::write(&file_name, content);

tests/run-make/core-ffi-typecheck-clang/tests.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
// tests.rs
1+
/// This file compares the size and signedness of Rust `c_*` types to those from Clang,
2+
/// based on the `CLANG_C_*` constants. Comparisons are done at compile time so this
3+
/// does not need to be executed.
4+
use super::*; // `super` will include everything from the common template
25

3-
use super::*; // `super` will include everything from `smallcore` once glued together
6+
trait Signed {
7+
const SIGNED: bool;
8+
}
49

10+
// Verify Rust's 'c_long' is correct.
511
cfg_if! {
612
if #[cfg(all(target_arch = "aarch64", target_abi = "ilp32"))] {
713
// FIXME: long is not long enough on aarch64 ilp32, should be 8, defaulting to 4
@@ -18,28 +24,30 @@ cfg_if! {
1824
}
1925
}
2026

27+
// Verify Rust's 'c_char' has correct sign.
2128
cfg_if! {
2229
if #[cfg(target_arch = "csky")] {
2330
// FIXME: c_char signedness misallignment on csky, should be signed on CLANG
2431
const XFAIL_C_CHAR_SIGNED: bool = false;
25-
pub const TEST_C_CHAR_UNSIGNED: () = if ffi::c_char::SIGNED ^ XFAIL_C_CHAR_SIGNED {
32+
pub const TEST_C_CHAR_UNSIGNED: () = if ffi::c_char::SIGNED != XFAIL_C_CHAR_SIGNED {
2633
panic!("mismatched c_char signed, target_arch: csky");
2734
};
2835
}
2936
else if #[cfg(target_arch = "msp430")] {
3037
// FIXME: c_char signedness misallignment on msp430, should be signed on CLANG
31-
const XFAIL_C_CHAR_SIGNED: bool = false; // Change to true for darwin
32-
pub const TEST_C_CHAR_UNSIGNED: () = if ffi::c_char::SIGNED ^ XFAIL_C_CHAR_SIGNED {
38+
const XFAIL_C_CHAR_SIGNED: bool = false;
39+
pub const TEST_C_CHAR_UNSIGNED: () = if ffi::c_char::SIGNED != XFAIL_C_CHAR_SIGNED {
3340
panic!("mismatched c_char signed, target_arch: msp430");
3441
};
3542
}
3643
else {
37-
pub const TEST_C_CHAR_UNSIGNED: () = if ffi::c_char::SIGNED ^ CLANG_C_CHAR_SIGNED {
44+
pub const TEST_C_CHAR_UNSIGNED: () = if ffi::c_char::SIGNED != CLANG_C_CHAR_SIGNED {
3845
panic!("mismatched c_char sign");
3946
};
4047
}
4148
}
4249

50+
// Verify Rust's 'c_double' is correct.
4351
cfg_if! {
4452
if #[cfg(target_arch = "avr")] {
4553
// FIXME: double is not short enough on avr-unknown-gnu-atmega328 (should be 4 bytes)
@@ -55,10 +63,6 @@ cfg_if! {
5563
}
5664
}
5765

58-
trait Signed {
59-
const SIGNED: bool;
60-
}
61-
6266
impl Signed for i8 {
6367
const SIGNED: bool = true;
6468
}

0 commit comments

Comments
 (0)