Verify llvm-needs-components are not empty and match the --target value
This commit is contained in:
parent
7278554d82
commit
cffde732ce
30 changed files with 277 additions and 97 deletions
|
|
@ -293,8 +293,6 @@ See [Pretty-printer](compiletest.md#pretty-printer-tests).
|
|||
|
||||
- `no-auto-check-cfg` — disable auto check-cfg (only for `--check-cfg` tests)
|
||||
- [`revisions`](compiletest.md#revisions) — compile multiple times
|
||||
- [`unused-revision-names`](compiletest.md#ignoring-unused-revision-names) -
|
||||
suppress tidy checks for mentioning unknown revision names
|
||||
-[`forbid-output`](compiletest.md#incremental-tests) — incremental cfail rejects
|
||||
output pattern
|
||||
- [`should-ice`](compiletest.md#incremental-tests) — incremental cfail should
|
||||
|
|
@ -315,6 +313,17 @@ test suites that use those tools:
|
|||
- `llvm-cov-flags` adds extra flags when running LLVM's `llvm-cov` tool.
|
||||
- Used by [coverage tests](compiletest.md#coverage-tests) in `coverage-run` mode.
|
||||
|
||||
### Tidy specific directives
|
||||
|
||||
The following directives control how the [tidy script](../conventions.md#formatting)
|
||||
verifies tests.
|
||||
|
||||
- `ignore-tidy-target-specific-tests` disables checking that the appropriate
|
||||
LLVM component is required (via a `needs-llvm-components` directive) when a
|
||||
test is compiled for a specific target (via the `--target` flag in a
|
||||
`compile-flag` directive).
|
||||
- [`unused-revision-names`](compiletest.md#ignoring-unused-revision-names) -
|
||||
suppress tidy checks for mentioning unknown revision names.
|
||||
|
||||
## Substitutions
|
||||
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ impl EarlyProps {
|
|||
&mut poisoned,
|
||||
testfile,
|
||||
rdr,
|
||||
&mut |DirectiveLine { raw_directive: ln, .. }| {
|
||||
parse_and_update_aux(config, ln, &mut props.aux);
|
||||
config.parse_and_update_revisions(testfile, ln, &mut props.revisions);
|
||||
&mut |DirectiveLine { line_number, raw_directive: ln, .. }| {
|
||||
parse_and_update_aux(config, ln, testfile, line_number, &mut props.aux);
|
||||
config.parse_and_update_revisions(testfile, line_number, ln, &mut props.revisions);
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ impl TestProps {
|
|||
&mut poisoned,
|
||||
testfile,
|
||||
file,
|
||||
&mut |directive @ DirectiveLine { raw_directive: ln, .. }| {
|
||||
&mut |directive @ DirectiveLine { line_number, raw_directive: ln, .. }| {
|
||||
if !directive.applies_to_test_revision(test_revision) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -361,17 +361,28 @@ impl TestProps {
|
|||
config.push_name_value_directive(
|
||||
ln,
|
||||
ERROR_PATTERN,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.error_patterns,
|
||||
|r| r,
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
REGEX_ERROR_PATTERN,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.regex_error_patterns,
|
||||
|r| r,
|
||||
);
|
||||
|
||||
config.push_name_value_directive(ln, DOC_FLAGS, &mut self.doc_flags, |r| r);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
DOC_FLAGS,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.doc_flags,
|
||||
|r| r,
|
||||
);
|
||||
|
||||
fn split_flags(flags: &str) -> Vec<String> {
|
||||
// Individual flags can be single-quoted to preserve spaces; see
|
||||
|
|
@ -386,7 +397,9 @@ impl TestProps {
|
|||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) {
|
||||
if let Some(flags) =
|
||||
config.parse_name_value_directive(ln, COMPILE_FLAGS, testfile, line_number)
|
||||
{
|
||||
let flags = split_flags(&flags);
|
||||
for flag in &flags {
|
||||
if flag == "--edition" || flag.starts_with("--edition=") {
|
||||
|
|
@ -395,25 +408,40 @@ impl TestProps {
|
|||
}
|
||||
self.compile_flags.extend(flags);
|
||||
}
|
||||
if config.parse_name_value_directive(ln, INCORRECT_COMPILER_FLAGS).is_some() {
|
||||
if config
|
||||
.parse_name_value_directive(
|
||||
ln,
|
||||
INCORRECT_COMPILER_FLAGS,
|
||||
testfile,
|
||||
line_number,
|
||||
)
|
||||
.is_some()
|
||||
{
|
||||
panic!("`compiler-flags` directive should be spelled `compile-flags`");
|
||||
}
|
||||
|
||||
if let Some(edition) = config.parse_edition(ln) {
|
||||
if let Some(edition) = config.parse_edition(ln, testfile, line_number) {
|
||||
// The edition is added at the start, since flags from //@compile-flags must
|
||||
// be passed to rustc last.
|
||||
self.compile_flags.insert(0, format!("--edition={}", edition.trim()));
|
||||
has_edition = true;
|
||||
}
|
||||
|
||||
config.parse_and_update_revisions(testfile, ln, &mut self.revisions);
|
||||
config.parse_and_update_revisions(
|
||||
testfile,
|
||||
line_number,
|
||||
ln,
|
||||
&mut self.revisions,
|
||||
);
|
||||
|
||||
if let Some(flags) = config.parse_name_value_directive(ln, RUN_FLAGS) {
|
||||
if let Some(flags) =
|
||||
config.parse_name_value_directive(ln, RUN_FLAGS, testfile, line_number)
|
||||
{
|
||||
self.run_flags.extend(split_flags(&flags));
|
||||
}
|
||||
|
||||
if self.pp_exact.is_none() {
|
||||
self.pp_exact = config.parse_pp_exact(ln, testfile);
|
||||
self.pp_exact = config.parse_pp_exact(ln, testfile, line_number);
|
||||
}
|
||||
|
||||
config.set_name_directive(ln, SHOULD_ICE, &mut self.should_ice);
|
||||
|
|
@ -435,7 +463,9 @@ impl TestProps {
|
|||
);
|
||||
config.set_name_directive(ln, NO_PREFER_DYNAMIC, &mut self.no_prefer_dynamic);
|
||||
|
||||
if let Some(m) = config.parse_name_value_directive(ln, PRETTY_MODE) {
|
||||
if let Some(m) =
|
||||
config.parse_name_value_directive(ln, PRETTY_MODE, testfile, line_number)
|
||||
{
|
||||
self.pretty_mode = m;
|
||||
}
|
||||
|
||||
|
|
@ -446,35 +476,45 @@ impl TestProps {
|
|||
);
|
||||
|
||||
// Call a helper method to deal with aux-related directives.
|
||||
parse_and_update_aux(config, ln, &mut self.aux);
|
||||
parse_and_update_aux(config, ln, testfile, line_number, &mut self.aux);
|
||||
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
EXEC_ENV,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.exec_env,
|
||||
Config::parse_env,
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
UNSET_EXEC_ENV,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.unset_exec_env,
|
||||
|r| r.trim().to_owned(),
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
RUSTC_ENV,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.rustc_env,
|
||||
Config::parse_env,
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
UNSET_RUSTC_ENV,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.unset_rustc_env,
|
||||
|r| r.trim().to_owned(),
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
FORBID_OUTPUT,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.forbid_output,
|
||||
|r| r,
|
||||
);
|
||||
|
|
@ -510,7 +550,7 @@ impl TestProps {
|
|||
}
|
||||
|
||||
if let Some(code) = config
|
||||
.parse_name_value_directive(ln, FAILURE_STATUS)
|
||||
.parse_name_value_directive(ln, FAILURE_STATUS, testfile, line_number)
|
||||
.and_then(|code| code.trim().parse::<i32>().ok())
|
||||
{
|
||||
self.failure_status = Some(code);
|
||||
|
|
@ -531,6 +571,8 @@ impl TestProps {
|
|||
config.set_name_value_directive(
|
||||
ln,
|
||||
ASSEMBLY_OUTPUT,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.assembly_output,
|
||||
|r| r.trim().to_string(),
|
||||
);
|
||||
|
|
@ -543,7 +585,9 @@ impl TestProps {
|
|||
|
||||
// Unlike the other `name_value_directive`s this needs to be handled manually,
|
||||
// because it sets a `bool` flag.
|
||||
if let Some(known_bug) = config.parse_name_value_directive(ln, KNOWN_BUG) {
|
||||
if let Some(known_bug) =
|
||||
config.parse_name_value_directive(ln, KNOWN_BUG, testfile, line_number)
|
||||
{
|
||||
let known_bug = known_bug.trim();
|
||||
if known_bug == "unknown"
|
||||
|| known_bug.split(',').all(|issue_ref| {
|
||||
|
|
@ -571,16 +615,25 @@ impl TestProps {
|
|||
config.set_name_value_directive(
|
||||
ln,
|
||||
TEST_MIR_PASS,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.mir_unit_test,
|
||||
|s| s.trim().to_string(),
|
||||
);
|
||||
config.set_name_directive(ln, REMAP_SRC_BASE, &mut self.remap_src_base);
|
||||
|
||||
if let Some(flags) = config.parse_name_value_directive(ln, LLVM_COV_FLAGS) {
|
||||
if let Some(flags) =
|
||||
config.parse_name_value_directive(ln, LLVM_COV_FLAGS, testfile, line_number)
|
||||
{
|
||||
self.llvm_cov_flags.extend(split_flags(&flags));
|
||||
}
|
||||
|
||||
if let Some(flags) = config.parse_name_value_directive(ln, FILECHECK_FLAGS) {
|
||||
if let Some(flags) = config.parse_name_value_directive(
|
||||
ln,
|
||||
FILECHECK_FLAGS,
|
||||
testfile,
|
||||
line_number,
|
||||
) {
|
||||
self.filecheck_flags.extend(split_flags(&flags));
|
||||
}
|
||||
|
||||
|
|
@ -588,9 +641,12 @@ impl TestProps {
|
|||
|
||||
self.update_add_core_stubs(ln, config);
|
||||
|
||||
if let Some(err_kind) =
|
||||
config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS)
|
||||
{
|
||||
if let Some(err_kind) = config.parse_name_value_directive(
|
||||
ln,
|
||||
DONT_REQUIRE_ANNOTATIONS,
|
||||
testfile,
|
||||
line_number,
|
||||
) {
|
||||
self.dont_require_annotations
|
||||
.insert(ErrorKind::expect_from_user_str(err_kind.trim()));
|
||||
}
|
||||
|
|
@ -1206,6 +1262,7 @@ impl Config {
|
|||
fn parse_and_update_revisions(
|
||||
&self,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
line: &str,
|
||||
existing: &mut Vec<String>,
|
||||
) {
|
||||
|
|
@ -1219,7 +1276,8 @@ impl Config {
|
|||
const FILECHECK_FORBIDDEN_REVISION_NAMES: [&str; 9] =
|
||||
["CHECK", "COM", "NEXT", "SAME", "EMPTY", "NOT", "COUNT", "DAG", "LABEL"];
|
||||
|
||||
if let Some(raw) = self.parse_name_value_directive(line, "revisions") {
|
||||
if let Some(raw) = self.parse_name_value_directive(line, "revisions", testfile, line_number)
|
||||
{
|
||||
if self.mode == TestMode::RunMake {
|
||||
panic!("`run-make` tests do not support revisions: {}", testfile);
|
||||
}
|
||||
|
|
@ -1264,8 +1322,13 @@ impl Config {
|
|||
(name.to_owned(), value.to_owned())
|
||||
}
|
||||
|
||||
fn parse_pp_exact(&self, line: &str, testfile: &Utf8Path) -> Option<Utf8PathBuf> {
|
||||
if let Some(s) = self.parse_name_value_directive(line, "pp-exact") {
|
||||
fn parse_pp_exact(
|
||||
&self,
|
||||
line: &str,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
) -> Option<Utf8PathBuf> {
|
||||
if let Some(s) = self.parse_name_value_directive(line, "pp-exact", testfile, line_number) {
|
||||
Some(Utf8PathBuf::from(&s))
|
||||
} else if self.parse_name_directive(line, "pp-exact") {
|
||||
testfile.file_name().map(Utf8PathBuf::from)
|
||||
|
|
@ -1306,19 +1369,31 @@ impl Config {
|
|||
line.starts_with("no-") && self.parse_name_directive(&line[3..], directive)
|
||||
}
|
||||
|
||||
pub fn parse_name_value_directive(&self, line: &str, directive: &str) -> Option<String> {
|
||||
pub fn parse_name_value_directive(
|
||||
&self,
|
||||
line: &str,
|
||||
directive: &str,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
) -> Option<String> {
|
||||
let colon = directive.len();
|
||||
if line.starts_with(directive) && line.as_bytes().get(colon) == Some(&b':') {
|
||||
let value = line[(colon + 1)..].to_owned();
|
||||
debug!("{}: {}", directive, value);
|
||||
Some(expand_variables(value, self))
|
||||
let value = expand_variables(value, self);
|
||||
if value.is_empty() {
|
||||
error!("{testfile}:{line_number}: empty value for directive `{directive}`");
|
||||
help!("expected syntax is: `{directive}: value`");
|
||||
panic!("empty directive value detected");
|
||||
}
|
||||
Some(value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_edition(&self, line: &str) -> Option<String> {
|
||||
self.parse_name_value_directive(line, "edition")
|
||||
fn parse_edition(&self, line: &str, testfile: &Utf8Path, line_number: usize) -> Option<String> {
|
||||
self.parse_name_value_directive(line, "edition", testfile, line_number)
|
||||
}
|
||||
|
||||
fn set_name_directive(&self, line: &str, directive: &str, value: &mut bool) {
|
||||
|
|
@ -1340,11 +1415,14 @@ impl Config {
|
|||
&self,
|
||||
line: &str,
|
||||
directive: &str,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
value: &mut Option<T>,
|
||||
parse: impl FnOnce(String) -> T,
|
||||
) {
|
||||
if value.is_none() {
|
||||
*value = self.parse_name_value_directive(line, directive).map(parse);
|
||||
*value =
|
||||
self.parse_name_value_directive(line, directive, testfile, line_number).map(parse);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1352,10 +1430,14 @@ impl Config {
|
|||
&self,
|
||||
line: &str,
|
||||
directive: &str,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
values: &mut Vec<T>,
|
||||
parse: impl FnOnce(String) -> T,
|
||||
) {
|
||||
if let Some(value) = self.parse_name_value_directive(line, directive).map(parse) {
|
||||
if let Some(value) =
|
||||
self.parse_name_value_directive(line, directive, testfile, line_number).map(parse)
|
||||
{
|
||||
values.push(value);
|
||||
}
|
||||
}
|
||||
|
|
@ -1672,9 +1754,9 @@ pub(crate) fn make_test_description<R: Read>(
|
|||
decision!(cfg::handle_ignore(config, ln));
|
||||
decision!(cfg::handle_only(config, ln));
|
||||
decision!(needs::handle_needs(&cache.needs, config, ln));
|
||||
decision!(ignore_llvm(config, path, ln));
|
||||
decision!(ignore_backends(config, path, ln));
|
||||
decision!(needs_backends(config, path, ln));
|
||||
decision!(ignore_llvm(config, path, ln, line_number));
|
||||
decision!(ignore_backends(config, path, ln, line_number));
|
||||
decision!(needs_backends(config, path, ln, line_number));
|
||||
decision!(ignore_cdb(config, ln));
|
||||
decision!(ignore_gdb(config, ln));
|
||||
decision!(ignore_lldb(config, ln));
|
||||
|
|
@ -1801,8 +1883,15 @@ fn ignore_lldb(config: &Config, line: &str) -> IgnoreDecision {
|
|||
IgnoreDecision::Continue
|
||||
}
|
||||
|
||||
fn ignore_backends(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision {
|
||||
if let Some(backends_to_ignore) = config.parse_name_value_directive(line, "ignore-backends") {
|
||||
fn ignore_backends(
|
||||
config: &Config,
|
||||
path: &Utf8Path,
|
||||
line: &str,
|
||||
line_number: usize,
|
||||
) -> IgnoreDecision {
|
||||
if let Some(backends_to_ignore) =
|
||||
config.parse_name_value_directive(line, "ignore-backends", path, line_number)
|
||||
{
|
||||
for backend in backends_to_ignore.split_whitespace().map(|backend| {
|
||||
match CodegenBackend::try_from(backend) {
|
||||
Ok(backend) => backend,
|
||||
|
|
@ -1821,8 +1910,15 @@ fn ignore_backends(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecisi
|
|||
IgnoreDecision::Continue
|
||||
}
|
||||
|
||||
fn needs_backends(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision {
|
||||
if let Some(needed_backends) = config.parse_name_value_directive(line, "needs-backends") {
|
||||
fn needs_backends(
|
||||
config: &Config,
|
||||
path: &Utf8Path,
|
||||
line: &str,
|
||||
line_number: usize,
|
||||
) -> IgnoreDecision {
|
||||
if let Some(needed_backends) =
|
||||
config.parse_name_value_directive(line, "needs-backends", path, line_number)
|
||||
{
|
||||
if !needed_backends
|
||||
.split_whitespace()
|
||||
.map(|backend| match CodegenBackend::try_from(backend) {
|
||||
|
|
@ -1844,9 +1940,9 @@ fn needs_backends(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecisio
|
|||
IgnoreDecision::Continue
|
||||
}
|
||||
|
||||
fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision {
|
||||
fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize) -> IgnoreDecision {
|
||||
if let Some(needed_components) =
|
||||
config.parse_name_value_directive(line, "needs-llvm-components")
|
||||
config.parse_name_value_directive(line, "needs-llvm-components", path, line_number)
|
||||
{
|
||||
let components: HashSet<_> = config.llvm_components.split_whitespace().collect();
|
||||
if let Some(missing_component) = needed_components
|
||||
|
|
@ -1867,7 +1963,9 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision {
|
|||
if let Some(actual_version) = &config.llvm_version {
|
||||
// Note that these `min` versions will check for not just major versions.
|
||||
|
||||
if let Some(version_string) = config.parse_name_value_directive(line, "min-llvm-version") {
|
||||
if let Some(version_string) =
|
||||
config.parse_name_value_directive(line, "min-llvm-version", path, line_number)
|
||||
{
|
||||
let min_version = extract_llvm_version(&version_string);
|
||||
// Ignore if actual version is smaller than the minimum required version.
|
||||
if *actual_version < min_version {
|
||||
|
|
@ -1878,7 +1976,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision {
|
|||
};
|
||||
}
|
||||
} else if let Some(version_string) =
|
||||
config.parse_name_value_directive(line, "max-llvm-major-version")
|
||||
config.parse_name_value_directive(line, "max-llvm-major-version", path, line_number)
|
||||
{
|
||||
let max_version = extract_llvm_version(&version_string);
|
||||
// Ignore if actual major version is larger than the maximum required major version.
|
||||
|
|
@ -1892,7 +1990,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision {
|
|||
};
|
||||
}
|
||||
} else if let Some(version_string) =
|
||||
config.parse_name_value_directive(line, "min-system-llvm-version")
|
||||
config.parse_name_value_directive(line, "min-system-llvm-version", path, line_number)
|
||||
{
|
||||
let min_version = extract_llvm_version(&version_string);
|
||||
// Ignore if using system LLVM and actual version
|
||||
|
|
@ -1905,7 +2003,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision {
|
|||
};
|
||||
}
|
||||
} else if let Some(version_range) =
|
||||
config.parse_name_value_directive(line, "ignore-llvm-version")
|
||||
config.parse_name_value_directive(line, "ignore-llvm-version", path, line_number)
|
||||
{
|
||||
// Syntax is: "ignore-llvm-version: <version1> [- <version2>]"
|
||||
let (v_min, v_max) =
|
||||
|
|
@ -1931,7 +2029,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision {
|
|||
}
|
||||
}
|
||||
} else if let Some(version_string) =
|
||||
config.parse_name_value_directive(line, "exact-llvm-major-version")
|
||||
config.parse_name_value_directive(line, "exact-llvm-major-version", path, line_number)
|
||||
{
|
||||
// Syntax is "exact-llvm-major-version: <version>"
|
||||
let version = extract_llvm_version(&version_string);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
use std::iter;
|
||||
|
||||
use camino::Utf8Path;
|
||||
|
||||
use super::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE, PROC_MACRO};
|
||||
use crate::common::Config;
|
||||
|
||||
|
|
@ -41,17 +43,42 @@ impl AuxProps {
|
|||
|
||||
/// If the given test directive line contains an `aux-*` directive, parse it
|
||||
/// and update [`AuxProps`] accordingly.
|
||||
pub(super) fn parse_and_update_aux(config: &Config, ln: &str, aux: &mut AuxProps) {
|
||||
pub(super) fn parse_and_update_aux(
|
||||
config: &Config,
|
||||
ln: &str,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
aux: &mut AuxProps,
|
||||
) {
|
||||
if !(ln.starts_with("aux-") || ln.starts_with("proc-macro")) {
|
||||
return;
|
||||
}
|
||||
|
||||
config.push_name_value_directive(ln, AUX_BUILD, &mut aux.builds, |r| r.trim().to_string());
|
||||
config.push_name_value_directive(ln, AUX_BIN, &mut aux.bins, |r| r.trim().to_string());
|
||||
config.push_name_value_directive(ln, AUX_CRATE, &mut aux.crates, parse_aux_crate);
|
||||
config
|
||||
.push_name_value_directive(ln, PROC_MACRO, &mut aux.proc_macros, |r| r.trim().to_string());
|
||||
if let Some(r) = config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND) {
|
||||
config.push_name_value_directive(ln, AUX_BUILD, testfile, line_number, &mut aux.builds, |r| {
|
||||
r.trim().to_string()
|
||||
});
|
||||
config.push_name_value_directive(ln, AUX_BIN, testfile, line_number, &mut aux.bins, |r| {
|
||||
r.trim().to_string()
|
||||
});
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
AUX_CRATE,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut aux.crates,
|
||||
parse_aux_crate,
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
PROC_MACRO,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut aux.proc_macros,
|
||||
|r| r.trim().to_string(),
|
||||
);
|
||||
if let Some(r) =
|
||||
config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND, testfile, line_number)
|
||||
{
|
||||
aux.codegen_backend = Some(r.trim().to_owned());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,10 +47,14 @@ impl DebuggerCommands {
|
|||
continue;
|
||||
};
|
||||
|
||||
if let Some(command) = config.parse_name_value_directive(&line, &command_directive) {
|
||||
if let Some(command) =
|
||||
config.parse_name_value_directive(&line, &command_directive, file, line_no)
|
||||
{
|
||||
commands.push(command);
|
||||
}
|
||||
if let Some(pattern) = config.parse_name_value_directive(&line, &check_directive) {
|
||||
if let Some(pattern) =
|
||||
config.parse_name_value_directive(&line, &check_directive, file, line_no)
|
||||
{
|
||||
check_lines.push((line_no, pattern));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -519,8 +519,11 @@ pub fn check(path: &Path, bad: &mut bool) {
|
|||
.any(|directive| matches!(directive, Directive::Ignore(_)));
|
||||
let has_alphabetical_directive = line.contains("tidy-alphabetical-start")
|
||||
|| line.contains("tidy-alphabetical-end");
|
||||
let has_recognized_directive =
|
||||
has_recognized_ignore_directive || has_alphabetical_directive;
|
||||
let has_other_tidy_ignore_directive =
|
||||
line.contains("ignore-tidy-target-specific-tests");
|
||||
let has_recognized_directive = has_recognized_ignore_directive
|
||||
|| has_alphabetical_directive
|
||||
|| has_other_tidy_ignore_directive;
|
||||
if contains_potential_directive && (!has_recognized_directive) {
|
||||
err("Unrecognized tidy directive")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,16 @@ const COMPILE_FLAGS_HEADER: &str = "compile-flags:";
|
|||
|
||||
#[derive(Default, Debug)]
|
||||
struct RevisionInfo<'a> {
|
||||
target_arch: Option<&'a str>,
|
||||
target_arch: Option<Option<&'a str>>,
|
||||
llvm_components: Option<Vec<&'a str>>,
|
||||
}
|
||||
|
||||
pub fn check(tests_path: &Path, bad: &mut bool) {
|
||||
crate::walk::walk(tests_path, |path, _is_dir| filter_not_rust(path), &mut |entry, content| {
|
||||
if content.contains("// ignore-tidy-target-specific-tests") {
|
||||
return;
|
||||
}
|
||||
|
||||
let file = entry.path().display();
|
||||
let mut header_map = BTreeMap::new();
|
||||
iter_header(content, &mut |HeaderLine { revision, directive, .. }| {
|
||||
|
|
@ -34,10 +38,11 @@ pub fn check(tests_path: &Path, bad: &mut bool) {
|
|||
&& let Some((_, v)) = compile_flags.split_once("--target")
|
||||
{
|
||||
let v = v.trim_start_matches([' ', '=']);
|
||||
let v = if v == "{{target}}" { Some((v, v)) } else { v.split_once("-") };
|
||||
if let Some((arch, _)) = v {
|
||||
let info = header_map.entry(revision).or_insert(RevisionInfo::default());
|
||||
info.target_arch.replace(arch);
|
||||
let info = header_map.entry(revision).or_insert(RevisionInfo::default());
|
||||
if v.starts_with("{{") {
|
||||
info.target_arch.replace(None);
|
||||
} else if let Some((arch, _)) = v.split_once("-") {
|
||||
info.target_arch.replace(Some(arch));
|
||||
} else {
|
||||
eprintln!("{file}: seems to have a malformed --target value");
|
||||
*bad = true;
|
||||
|
|
@ -54,9 +59,11 @@ pub fn check(tests_path: &Path, bad: &mut bool) {
|
|||
let rev = rev.unwrap_or("[unspecified]");
|
||||
match (target_arch, llvm_components) {
|
||||
(None, None) => {}
|
||||
(Some(_), None) => {
|
||||
(Some(target_arch), None) => {
|
||||
let llvm_component =
|
||||
target_arch.map_or_else(|| "<arch>".to_string(), arch_to_llvm_component);
|
||||
eprintln!(
|
||||
"{file}: revision {rev} should specify `{LLVM_COMPONENTS_HEADER}` as it has `--target` set"
|
||||
"{file}: revision {rev} should specify `{LLVM_COMPONENTS_HEADER} {llvm_component}` as it has `--target` set"
|
||||
);
|
||||
*bad = true;
|
||||
}
|
||||
|
|
@ -66,11 +73,45 @@ pub fn check(tests_path: &Path, bad: &mut bool) {
|
|||
);
|
||||
*bad = true;
|
||||
}
|
||||
(Some(_), Some(_)) => {
|
||||
// FIXME: check specified components against the target architectures we
|
||||
// gathered.
|
||||
(Some(target_arch), Some(llvm_components)) => {
|
||||
if let Some(target_arch) = target_arch {
|
||||
let llvm_component = arch_to_llvm_component(target_arch);
|
||||
if !llvm_components.contains(&llvm_component.as_str()) {
|
||||
eprintln!(
|
||||
"{file}: revision {rev} should specify `{LLVM_COMPONENTS_HEADER} {llvm_component}` as it has `--target` set"
|
||||
);
|
||||
*bad = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn arch_to_llvm_component(arch: &str) -> String {
|
||||
// NOTE: This is an *approximate* mapping of Rust's `--target` architecture to LLVM component
|
||||
// names. It is not intended to be an authoritative source, but rather a best-effort that's good
|
||||
// enough for the purpose of this tidy check.
|
||||
match arch {
|
||||
"amdgcn" => "amdgpu".into(),
|
||||
"aarch64_be" | "arm64_32" | "arm64e" | "arm64ec" => "aarch64".into(),
|
||||
"i386" | "i586" | "i686" | "x86" | "x86_64" | "x86_64h" => "x86".into(),
|
||||
"loongarch32" | "loongarch64" => "loongarch".into(),
|
||||
"nvptx64" => "nvptx".into(),
|
||||
"s390x" => "systemz".into(),
|
||||
"sparc64" | "sparcv9" => "sparc".into(),
|
||||
"wasm32" | "wasm32v1" | "wasm64" => "webassembly".into(),
|
||||
_ if arch.starts_with("armeb")
|
||||
|| arch.starts_with("armv")
|
||||
|| arch.starts_with("thumbv") =>
|
||||
{
|
||||
"arm".into()
|
||||
}
|
||||
_ if arch.starts_with("bpfe") => "bpf".into(),
|
||||
_ if arch.starts_with("mips") => "mips".into(),
|
||||
_ if arch.starts_with("powerpc") => "powerpc".into(),
|
||||
_ if arch.starts_with("riscv") => "riscv".into(),
|
||||
_ => arch.to_ascii_lowercase(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue