diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index a186c16f1aa71..6adf9ddaf3438 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1149,7 +1149,6 @@ impl Step for Compiletest { // requires that a C++ compiler was configured which isn't always the case. if !builder.config.dry_run && suite == "run-make-fulldeps" { let llvm_components = output(Command::new(&llvm_config).arg("--components")); - let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags")); cmd.arg("--cc") .arg(builder.cc(target)) .arg("--cxx") @@ -1157,9 +1156,7 @@ impl Step for Compiletest { .arg("--cflags") .arg(builder.cflags(target, GitRepo::Rustc).join(" ")) .arg("--llvm-components") - .arg(llvm_components.trim()) - .arg("--llvm-cxxflags") - .arg(llvm_cxxflags.trim()); + .arg(llvm_components.trim()); if let Some(ar) = builder.ar(target) { cmd.arg("--ar").arg(ar); } @@ -1197,8 +1194,6 @@ impl Step for Compiletest { .arg("--cflags") .arg("") .arg("--llvm-components") - .arg("") - .arg("--llvm-cxxflags") .arg(""); } diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 9cc19060cbddc..64c0298c1fa4e 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -319,7 +319,6 @@ pub struct Config { pub ar: String, pub linker: Option, pub llvm_components: String, - pub llvm_cxxflags: String, /// Path to a NodeJS executable. Used for JS doctests, emscripten and WASM tests pub nodejs: Option, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 34f9ac037b4b8..817705c0bd6bf 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -24,6 +24,7 @@ enum ParsedNameDirective { /// Properties which must be known very early, before actually running /// the test. +#[derive(Default)] pub struct EarlyProps { pub ignore: bool, pub should_fail: bool, @@ -34,18 +35,16 @@ pub struct EarlyProps { impl EarlyProps { pub fn from_file(config: &Config, testfile: &Path) -> Self { - let mut props = EarlyProps { - ignore: false, - should_fail: false, - aux: Vec::new(), - aux_crate: Vec::new(), - revisions: vec![], - }; + let file = File::open(testfile).unwrap(); + Self::from_reader(config, testfile, file) + } + pub fn from_reader(config: &Config, testfile: &Path, rdr: R) -> Self { + let mut props = EarlyProps::default(); let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some(); let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some(); - iter_header(testfile, None, &mut |ln| { + iter_header(testfile, None, rdr, &mut |ln| { // we should check if any only- exists and if it exists // and does not matches the current platform, skip the test if !props.ignore { @@ -392,138 +391,143 @@ impl TestProps { /// `//[foo]`), then the property is ignored unless `cfg` is /// `Some("foo")`. fn load_from(&mut self, testfile: &Path, cfg: Option<&str>, config: &Config) { - iter_header(testfile, cfg, &mut |ln| { - if let Some(ep) = config.parse_error_pattern(ln) { - self.error_patterns.push(ep); - } + if !testfile.is_dir() { + let file = File::open(testfile).unwrap(); - if let Some(flags) = config.parse_compile_flags(ln) { - self.compile_flags.extend(flags.split_whitespace().map(|s| s.to_owned())); - } + iter_header(testfile, cfg, file, &mut |ln| { + if let Some(ep) = config.parse_error_pattern(ln) { + self.error_patterns.push(ep); + } - if let Some(edition) = config.parse_edition(ln) { - self.compile_flags.push(format!("--edition={}", edition)); - } + if let Some(flags) = config.parse_compile_flags(ln) { + self.compile_flags.extend(flags.split_whitespace().map(|s| s.to_owned())); + } - if let Some(r) = config.parse_revisions(ln) { - self.revisions.extend(r); - } + if let Some(edition) = config.parse_edition(ln) { + self.compile_flags.push(format!("--edition={}", edition)); + } - if self.run_flags.is_none() { - self.run_flags = config.parse_run_flags(ln); - } + if let Some(r) = config.parse_revisions(ln) { + self.revisions.extend(r); + } - if self.pp_exact.is_none() { - self.pp_exact = config.parse_pp_exact(ln, testfile); - } + if self.run_flags.is_none() { + self.run_flags = config.parse_run_flags(ln); + } - if !self.should_ice { - self.should_ice = config.parse_should_ice(ln); - } + if self.pp_exact.is_none() { + self.pp_exact = config.parse_pp_exact(ln, testfile); + } - if !self.build_aux_docs { - self.build_aux_docs = config.parse_build_aux_docs(ln); - } + if !self.should_ice { + self.should_ice = config.parse_should_ice(ln); + } - if !self.force_host { - self.force_host = config.parse_force_host(ln); - } + if !self.build_aux_docs { + self.build_aux_docs = config.parse_build_aux_docs(ln); + } - if !self.check_stdout { - self.check_stdout = config.parse_check_stdout(ln); - } + if !self.force_host { + self.force_host = config.parse_force_host(ln); + } - if !self.check_run_results { - self.check_run_results = config.parse_check_run_results(ln); - } + if !self.check_stdout { + self.check_stdout = config.parse_check_stdout(ln); + } - if !self.dont_check_compiler_stdout { - self.dont_check_compiler_stdout = config.parse_dont_check_compiler_stdout(ln); - } + if !self.check_run_results { + self.check_run_results = config.parse_check_run_results(ln); + } - if !self.dont_check_compiler_stderr { - self.dont_check_compiler_stderr = config.parse_dont_check_compiler_stderr(ln); - } + if !self.dont_check_compiler_stdout { + self.dont_check_compiler_stdout = config.parse_dont_check_compiler_stdout(ln); + } - if !self.no_prefer_dynamic { - self.no_prefer_dynamic = config.parse_no_prefer_dynamic(ln); - } + if !self.dont_check_compiler_stderr { + self.dont_check_compiler_stderr = config.parse_dont_check_compiler_stderr(ln); + } - if !self.pretty_expanded { - self.pretty_expanded = config.parse_pretty_expanded(ln); - } + if !self.no_prefer_dynamic { + self.no_prefer_dynamic = config.parse_no_prefer_dynamic(ln); + } - if let Some(m) = config.parse_pretty_mode(ln) { - self.pretty_mode = m; - } + if !self.pretty_expanded { + self.pretty_expanded = config.parse_pretty_expanded(ln); + } - if !self.pretty_compare_only { - self.pretty_compare_only = config.parse_pretty_compare_only(ln); - } + if let Some(m) = config.parse_pretty_mode(ln) { + self.pretty_mode = m; + } - if let Some(ab) = config.parse_aux_build(ln) { - self.aux_builds.push(ab); - } + if !self.pretty_compare_only { + self.pretty_compare_only = config.parse_pretty_compare_only(ln); + } - if let Some(ac) = config.parse_aux_crate(ln) { - self.aux_crates.push(ac); - } + if let Some(ab) = config.parse_aux_build(ln) { + self.aux_builds.push(ab); + } - if let Some(ee) = config.parse_env(ln, "exec-env") { - self.exec_env.push(ee); - } + if let Some(ac) = config.parse_aux_crate(ln) { + self.aux_crates.push(ac); + } - if let Some(ee) = config.parse_env(ln, "rustc-env") { - self.rustc_env.push(ee); - } + if let Some(ee) = config.parse_env(ln, "exec-env") { + self.exec_env.push(ee); + } - if let Some(ev) = config.parse_name_value_directive(ln, "unset-rustc-env") { - self.unset_rustc_env.push(ev); - } + if let Some(ee) = config.parse_env(ln, "rustc-env") { + self.rustc_env.push(ee); + } - if let Some(cl) = config.parse_check_line(ln) { - self.check_lines.push(cl); - } + if let Some(ev) = config.parse_name_value_directive(ln, "unset-rustc-env") { + self.unset_rustc_env.push(ev); + } - if let Some(of) = config.parse_forbid_output(ln) { - self.forbid_output.push(of); - } + if let Some(cl) = config.parse_check_line(ln) { + self.check_lines.push(cl); + } - if !self.check_test_line_numbers_match { - self.check_test_line_numbers_match = config.parse_check_test_line_numbers_match(ln); - } + if let Some(of) = config.parse_forbid_output(ln) { + self.forbid_output.push(of); + } - self.update_pass_mode(ln, cfg, config); - self.update_fail_mode(ln, config); + if !self.check_test_line_numbers_match { + self.check_test_line_numbers_match = + config.parse_check_test_line_numbers_match(ln); + } - if !self.ignore_pass { - self.ignore_pass = config.parse_ignore_pass(ln); - } + self.update_pass_mode(ln, cfg, config); + self.update_fail_mode(ln, config); - if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stdout") { - self.normalize_stdout.push(rule); - } - if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stderr") { - self.normalize_stderr.push(rule); - } + if !self.ignore_pass { + self.ignore_pass = config.parse_ignore_pass(ln); + } - if let Some(code) = config.parse_failure_status(ln) { - self.failure_status = code; - } + if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stdout") { + self.normalize_stdout.push(rule); + } + if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stderr") { + self.normalize_stderr.push(rule); + } - if !self.run_rustfix { - self.run_rustfix = config.parse_run_rustfix(ln); - } + if let Some(code) = config.parse_failure_status(ln) { + self.failure_status = code; + } - if !self.rustfix_only_machine_applicable { - self.rustfix_only_machine_applicable = - config.parse_rustfix_only_machine_applicable(ln); - } + if !self.run_rustfix { + self.run_rustfix = config.parse_run_rustfix(ln); + } - if self.assembly_output.is_none() { - self.assembly_output = config.parse_assembly_output(ln); - } - }); + if !self.rustfix_only_machine_applicable { + self.rustfix_only_machine_applicable = + config.parse_rustfix_only_machine_applicable(ln); + } + + if self.assembly_output.is_none() { + self.assembly_output = config.parse_assembly_output(ln); + } + }); + } if self.failure_status == -1 { self.failure_status = match config.mode { @@ -617,7 +621,7 @@ impl TestProps { } } -fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) { +fn iter_header(testfile: &Path, cfg: Option<&str>, rdr: R, it: &mut dyn FnMut(&str)) { if testfile.is_dir() { return; } @@ -628,12 +632,18 @@ fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) { // It took me like 2 days to debug why compile-flags weren’t taken into account for my test :) let comment_with_brace = comment.to_string() + "["; - let rdr = BufReader::new(File::open(testfile).unwrap()); - for ln in rdr.lines() { + let mut rdr = BufReader::new(rdr); + let mut ln = String::new(); + + loop { + ln.clear(); + if rdr.read_line(&mut ln).unwrap() == 0 { + break; + } + // Assume that any directives will be found before the first // module or function. This doesn't seem to be an optimization // with a warm page cache. Maybe with a cold one. - let ln = ln.unwrap(); let ln = ln.trim(); if ln.starts_with("fn") || ln.starts_with("mod") { return; diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 2a1831d5ee80c..38fa778219de2 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -1,4 +1,7 @@ -use super::*; +use std::path::Path; + +use crate::common::{Config, Debugger}; +use crate::header::{parse_normalization_string, EarlyProps}; #[test] fn test_parse_normalization_string() { @@ -25,3 +28,153 @@ fn test_parse_normalization_string() { assert_eq!(first, Some("something (32 bits)".to_owned())); assert_eq!(s, " -> \"something ($WORD bits)."); } + +fn config() -> Config { + let args = &[ + "compiletest", + "--mode=ui", + "--compile-lib-path=", + "--run-lib-path=", + "--rustc-path=", + "--lldb-python=", + "--docck-python=", + "--src-base=", + "--build-base=", + "--stage-id=stage2", + "--cc=c", + "--cxx=c++", + "--cflags=", + "--llvm-components=", + "--android-cross-path=", + "--target=x86_64-unknown-linux-gnu", + ]; + let args = args.iter().map(ToString::to_string).collect(); + crate::parse_config(args) +} + +fn parse_rs(config: &Config, contents: &str) -> EarlyProps { + let bytes = contents.as_bytes(); + EarlyProps::from_reader(config, Path::new("a.rs"), bytes) +} + +fn parse_makefile(config: &Config, contents: &str) -> EarlyProps { + let bytes = contents.as_bytes(); + EarlyProps::from_reader(config, Path::new("Makefile"), bytes) +} + +#[test] +fn should_fail() { + let config = config(); + + assert!(!parse_rs(&config, "").should_fail); + assert!(parse_rs(&config, "// should-fail").should_fail); +} + +#[test] +fn revisions() { + let config = config(); + + assert_eq!(parse_rs(&config, "// revisions: a b c").revisions, vec!["a", "b", "c"],); + assert_eq!( + parse_makefile(&config, "# revisions: hello there").revisions, + vec!["hello", "there"], + ); +} + +#[test] +fn aux_build() { + let config = config(); + + assert_eq!( + parse_rs( + &config, + r" + // aux-build: a.rs + // aux-build: b.rs + " + ) + .aux, + vec!["a.rs", "b.rs"], + ); +} + +#[test] +fn no_system_llvm() { + let mut config = config(); + + config.system_llvm = false; + assert!(!parse_rs(&config, "// no-system-llvm").ignore); + + config.system_llvm = true; + assert!(parse_rs(&config, "// no-system-llvm").ignore); +} + +#[test] +fn ignore_target() { + let mut config = config(); + config.target = "x86_64-unknown-linux-gnu".to_owned(); + + assert!(parse_rs(&config, "// ignore-x86_64-unknown-linux-gnu").ignore); + assert!(parse_rs(&config, "// ignore-x86_64").ignore); + assert!(parse_rs(&config, "// ignore-linux").ignore); + assert!(parse_rs(&config, "// ignore-gnu").ignore); + assert!(parse_rs(&config, "// ignore-64bit").ignore); + + assert!(!parse_rs(&config, "// ignore-i686").ignore); + assert!(!parse_rs(&config, "// ignore-windows").ignore); + assert!(!parse_rs(&config, "// ignore-msvc").ignore); + assert!(!parse_rs(&config, "// ignore-32bit").ignore); +} + +#[test] +fn only_target() { + let mut config = config(); + config.target = "x86_64-pc-windows-gnu".to_owned(); + + assert!(parse_rs(&config, "// only-i686").ignore); + assert!(parse_rs(&config, "// only-linux").ignore); + assert!(parse_rs(&config, "// only-msvc").ignore); + assert!(parse_rs(&config, "// only-32bit").ignore); + + assert!(!parse_rs(&config, "// only-x86_64-pc-windows-gnu").ignore); + assert!(!parse_rs(&config, "// only-x86_64").ignore); + assert!(!parse_rs(&config, "// only-windows").ignore); + assert!(!parse_rs(&config, "// only-gnu").ignore); + assert!(!parse_rs(&config, "// only-64bit").ignore); +} + +#[test] +fn stage() { + let mut config = config(); + config.stage_id = "stage1".to_owned(); + + assert!(parse_rs(&config, "// ignore-stage1").ignore); + assert!(!parse_rs(&config, "// ignore-stage2").ignore); +} + +#[test] +fn cross_compile() { + let mut config = config(); + config.host = "x86_64-apple-darwin".to_owned(); + config.target = "wasm32-unknown-unknown".to_owned(); + assert!(parse_rs(&config, "// ignore-cross-compile").ignore); + + config.target = config.host.clone(); + assert!(!parse_rs(&config, "// ignore-cross-compile").ignore); +} + +#[test] +fn debugger() { + let mut config = config(); + config.debugger = None; + assert!(!parse_rs(&config, "// ignore-cdb").ignore); + + config.debugger = Some(Debugger::Cdb); + assert!(parse_rs(&config, "// ignore-cdb").ignore); + + config.debugger = Some(Debugger::Gdb); + assert!(parse_rs(&config, "// ignore-gdb").ignore); + + config.debugger = Some(Debugger::Lldb); + assert!(parse_rs(&config, "// ignore-lldb").ignore); +} diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 5f8aa01f4fc79..a61b940398704 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -70,7 +70,8 @@ pub fn parse_config(args: Vec) -> Config { "", "mode", "which sort of compile tests to run", - "(compile-fail|run-fail|run-pass-valgrind|pretty|debug-info|incremental|mir-opt)", + "compile-fail | run-fail | run-pass-valgrind | pretty | debug-info | codegen | rustdoc \ + codegen-units | incremental | run-make | ui | js-doc-test | mir-opt | assembly", ) .optopt( "", @@ -115,7 +116,6 @@ pub fn parse_config(args: Vec) -> Config { .optopt("", "ar", "path to an archiver", "PATH") .optopt("", "linker", "path to a linker", "PATH") .reqopt("", "llvm-components", "list of LLVM components built in", "LIST") - .reqopt("", "llvm-cxxflags", "C++ flags for LLVM", "FLAGS") .optopt("", "llvm-bin-dir", "Path to LLVM's `bin` directory", "PATH") .optopt("", "nodejs", "the name of nodejs", "PATH") .optopt("", "remote-test-client", "path to the remote test client", "PATH") @@ -239,7 +239,6 @@ pub fn parse_config(args: Vec) -> Config { ar: matches.opt_str("ar").unwrap_or("ar".into()), linker: matches.opt_str("linker"), llvm_components: matches.opt_str("llvm-components").unwrap(), - llvm_cxxflags: matches.opt_str("llvm-cxxflags").unwrap(), nodejs: matches.opt_str("nodejs"), } } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index d1ee60d74e7e2..7661ac27f0206 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2651,7 +2651,6 @@ impl<'test> TestCx<'test> { .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path)) .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path)) .env("LLVM_COMPONENTS", &self.config.llvm_components) - .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags) // We for sure don't want these tests to run in parallel, so make // sure they don't have access to these vars if we run via `make` // at the top level