Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c0aecdc

Browse files
committed
Add new test directive needs-atomic to support #87377
1 parent f2a3542 commit c0aecdc

File tree

3 files changed

+98
-3
lines changed

3 files changed

+98
-3
lines changed

‎src/tools/compiletest/src/common.rs‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,16 @@ impl Config {
477477
ASM_SUPPORTED_ARCHS.contains(&self.target_cfg().arch.as_str())
478478
}
479479

480+
pub fn has_atomic(&self, size: Option<u64>) -> bool {
481+
if let Some(size) = size {
482+
(self.target_cfg().min_atomic_width()..=self.target_cfg().max_atomic_width())
483+
.contains(&size)
484+
&& self.target_cfg().atomic_cas
485+
} else {
486+
self.target_cfg().atomic_cas
487+
}
488+
}
489+
480490
pub fn git_config(&self) -> GitConfig<'_> {
481491
GitConfig {
482492
git_repository: &self.git_repository,
@@ -645,12 +655,26 @@ pub struct TargetCfg {
645655
pub(crate) xray: bool,
646656
#[serde(default = "default_reloc_model")]
647657
pub(crate) relocation_model: String,
658+
#[serde(default)]
659+
max_atomic_width: Option<u64>,
660+
#[serde(default)]
661+
min_atomic_width: Option<u64>,
662+
#[serde(default = "default_atomic_cas")]
663+
atomic_cas: bool,
648664
}
649665

650666
impl TargetCfg {
651667
pub(crate) fn os_and_env(&self) -> String {
652668
format!("{}-{}", self.os, self.env)
653669
}
670+
671+
fn max_atomic_width(&self) -> u64 {
672+
self.max_atomic_width.unwrap_or(self.pointer_width as _)
673+
}
674+
675+
fn min_atomic_width(&self) -> u64 {
676+
self.min_atomic_width.unwrap_or(8)
677+
}
654678
}
655679

656680
fn default_os() -> String {
@@ -661,6 +685,10 @@ fn default_reloc_model() -> String {
661685
"pic".into()
662686
}
663687

688+
fn default_atomic_cas() -> bool {
689+
true
690+
}
691+
664692
#[derive(Eq, PartialEq, Clone, Debug, Default, serde::Deserialize)]
665693
#[serde(rename_all = "kebab-case")]
666694
pub enum Endian {

‎src/tools/compiletest/src/directive-list.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
127127
"min-llvm-version",
128128
"min-system-llvm-version",
129129
"needs-asm-support",
130+
"needs-atomic",
130131
"needs-deterministic-layouts",
131132
"needs-dlltool",
132133
"needs-dynamic-linking",

‎src/tools/compiletest/src/header/needs.rs‎

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,12 @@ pub(super) fn handle_needs(
171171
},
172172
];
173173

174-
let (name, comment) = match ln.split_once([':', ' ']) {
175-
Some((name, comment)) => (name, Some(comment)),
176-
None => (ln, None),
174+
// Because `needs-atomic` accepts one argument after colon to specify data size, we check whther
175+
// comment starts with colon.
176+
let (name, comment, comment_starts_with_colon) = if let Some(index) = ln.find([':', ' ']) {
177+
(&ln[..index], Some(&ln[index + 1..]), ln.as_bytes()[index] == b':')
178+
} else {
179+
(ln, None, false)
177180
};
178181

179182
if !name.starts_with("needs-") {
@@ -185,6 +188,69 @@ pub(super) fn handle_needs(
185188
return IgnoreDecision::Continue;
186189
}
187190

191+
// Check here because `needs-atomic` requires parsing comments.
192+
if name == "needs-atomic" {
193+
let mut comment = comment;
194+
195+
// Parse the comment to specify data size.
196+
// Just comments not arguments are also accepted.
197+
// No arguments are handled as (none).
198+
let size = if !comment_starts_with_colon {
199+
// Comments starting with spaces are not arguments.
200+
None
201+
} else {
202+
if let Some(comment_content) = comment {
203+
if comment_content.trim().is_empty() {
204+
None
205+
} else {
206+
let (size, rest) = match comment_content.trim_start().split_once([':', ' ']) {
207+
Some((size, rest)) => (size, Some(rest)),
208+
None => (comment_content.trim(), None),
209+
};
210+
211+
if size == "ptr" {
212+
comment = rest;
213+
Some(config.target_cfg().pointer_width as _)
214+
} else if let Ok(size) = size.parse() {
215+
if ![128, 64, 32, 16, 8].contains(&size) {
216+
// Numeric literals but non data size are disallowed.
217+
return IgnoreDecision::Error {
218+
message: "expected values for `needs-atomic` are: (none), `128`,\
219+
`16`, `32`, `64`, `8`, and `ptr"
220+
.into(),
221+
};
222+
} else {
223+
comment = rest;
224+
Some(size)
225+
}
226+
} else {
227+
// Comments starting with non-numeric literals are not arguments.
228+
None
229+
}
230+
}
231+
} else {
232+
None
233+
}
234+
};
235+
236+
return if config.has_atomic(size) {
237+
IgnoreDecision::Continue
238+
} else {
239+
let base = if let Some(size) = size {
240+
format!("ignored on targets without {size}-bit atomic operations")
241+
} else {
242+
format!("ignored on targets without atomic operations")
243+
};
244+
IgnoreDecision::Ignore {
245+
reason: if let Some(comment) = comment {
246+
format!("{base}: ({})", comment.trim())
247+
} else {
248+
base
249+
},
250+
}
251+
};
252+
}
253+
188254
let mut found_valid = false;
189255
for need in needs {
190256
if need.name == name {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /