From 4aa92aff054c8e89c61ac06551a405af828ade70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20BRANSTETT?= Date: Fri, 25 Feb 2022 16:10:26 +0100 Subject: [PATCH] Add well known values to --check-cfg implementation --- compiler/rustc_session/src/config.rs | 107 +++++++++++++++++- compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/spec/mod.rs | 20 +++- src/test/ui/check-cfg/empty-values.rs | 6 +- src/test/ui/check-cfg/empty-values.stderr | 11 ++ src/test/ui/check-cfg/well-known-values.rs | 28 +++++ .../ui/check-cfg/well-known-values.stderr | 31 +++++ 7 files changed, 196 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/check-cfg/empty-values.stderr create mode 100644 src/test/ui/check-cfg/well-known-values.rs create mode 100644 src/test/ui/check-cfg/well-known-values.stderr diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 02cfdcf86f84..6c32115c6a25 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -13,6 +13,7 @@ use rustc_data_structures::impl_stable_hash_via_hash; use rustc_target::abi::{Align, TargetDataLayout}; use rustc_target::spec::{LinkerFlavor, SplitDebuginfo, Target, TargetTriple, TargetWarnings}; +use rustc_target::spec::{PanicStrategy, SanitizerSet, TARGETS}; use rustc_serialize::json; @@ -1067,8 +1068,9 @@ pub fn to_crate_check_config(cfg: CheckCfg) -> CrateCheckConfig { impl CrateCheckConfig { /// Fills a `CrateCheckConfig` with well-known configuration names. - pub fn fill_well_known(&mut self) { - // NOTE: This should be kept in sync with `default_configuration` + fn fill_well_known_names(&mut self) { + // NOTE: This should be kept in sync with `default_configuration` and + // `fill_well_known_values` const WELL_KNOWN_NAMES: &[Symbol] = &[ sym::unix, sym::windows, @@ -1093,13 +1095,108 @@ impl CrateCheckConfig { sym::doctest, sym::feature, ]; + + // We only insert well-known names if `names()` was activated if let Some(names_valid) = &mut self.names_valid { - for &name in WELL_KNOWN_NAMES { - names_valid.insert(name); - } + names_valid.extend(WELL_KNOWN_NAMES); } } + /// Fills a `CrateCheckConfig` with well-known configuration values. + fn fill_well_known_values(&mut self) { + if !self.well_known_values { + return; + } + + // NOTE: This should be kept in sync with `default_configuration` and + // `fill_well_known_names` + + let panic_values = &PanicStrategy::all(); + + let atomic_values = &[ + sym::ptr, + sym::integer(8usize), + sym::integer(16usize), + sym::integer(32usize), + sym::integer(64usize), + sym::integer(128usize), + ]; + + let sanitize_values = SanitizerSet::all() + .into_iter() + .map(|sanitizer| Symbol::intern(sanitizer.as_str().unwrap())); + + // No-values + for name in [ + sym::unix, + sym::windows, + sym::debug_assertions, + sym::proc_macro, + sym::test, + sym::doc, + sym::doctest, + sym::target_thread_local, + ] { + self.values_valid.entry(name).or_default(); + } + + // Pre-defined values + self.values_valid.entry(sym::panic).or_default().extend(panic_values); + self.values_valid.entry(sym::sanitize).or_default().extend(sanitize_values); + self.values_valid.entry(sym::target_has_atomic).or_default().extend(atomic_values); + self.values_valid + .entry(sym::target_has_atomic_load_store) + .or_default() + .extend(atomic_values); + self.values_valid + .entry(sym::target_has_atomic_equal_alignment) + .or_default() + .extend(atomic_values); + + // Target specific values + for target in + TARGETS.iter().map(|target| Target::expect_builtin(&TargetTriple::from_triple(target))) + { + self.values_valid + .entry(sym::target_os) + .or_default() + .insert(Symbol::intern(&target.options.os)); + self.values_valid + .entry(sym::target_family) + .or_default() + .extend(target.options.families.iter().map(|family| Symbol::intern(family))); + self.values_valid + .entry(sym::target_arch) + .or_default() + .insert(Symbol::intern(&target.arch)); + self.values_valid + .entry(sym::target_endian) + .or_default() + .insert(Symbol::intern(&target.options.endian.as_str())); + self.values_valid + .entry(sym::target_env) + .or_default() + .insert(Symbol::intern(&target.options.env)); + self.values_valid + .entry(sym::target_abi) + .or_default() + .insert(Symbol::intern(&target.options.abi)); + self.values_valid + .entry(sym::target_vendor) + .or_default() + .insert(Symbol::intern(&target.options.vendor)); + self.values_valid + .entry(sym::target_pointer_width) + .or_default() + .insert(sym::integer(target.pointer_width)); + } + } + + pub fn fill_well_known(&mut self) { + self.fill_well_known_names(); + self.fill_well_known_values(); + } + /// Fills a `CrateCheckConfig` with configuration names and values that are actually active. pub fn fill_actual(&mut self, cfg: &CrateConfig) { for &(k, v) in cfg { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6767593bbc51..bb2d469ba6bc 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1062,6 +1062,7 @@ symbols! { proc_macro_path_invoc, profiler_builtins, profiler_runtime, + ptr, ptr_guaranteed_eq, ptr_guaranteed_ne, ptr_null, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 92678aed5b1a..ca5f2b4af8a9 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -186,12 +186,16 @@ impl PanicStrategy { } } - pub fn desc_symbol(&self) -> Symbol { + pub const fn desc_symbol(&self) -> Symbol { match *self { PanicStrategy::Unwind => sym::unwind, PanicStrategy::Abort => sym::abort, } } + + pub const fn all() -> [Symbol; 2] { + [Self::Abort.desc_symbol(), Self::Unwind.desc_symbol()] + } } impl ToJson for PanicStrategy { @@ -614,7 +618,7 @@ impl SanitizerSet { /// Return sanitizer's name /// /// Returns none if the flags is a set of sanitizers numbering not exactly one. - fn as_str(self) -> Option<&'static str> { + pub fn as_str(self) -> Option<&'static str> { Some(match self { SanitizerSet::ADDRESS => "address", SanitizerSet::CFI => "cfi", @@ -2137,6 +2141,18 @@ impl Target { )) } + /// Load a built-in target + pub fn expect_builtin(target_triple: &TargetTriple) -> Target { + match *target_triple { + TargetTriple::TargetTriple(ref target_triple) => { + load_builtin(target_triple).expect("built-in target") + } + TargetTriple::TargetPath(..) => { + panic!("built-in targets doens't support target-paths") + } + } + } + /// Search for a JSON file specifying the given target triple. /// /// If none is found in `$RUST_TARGET_PATH`, look for a file called `target.json` inside the diff --git a/src/test/ui/check-cfg/empty-values.rs b/src/test/ui/check-cfg/empty-values.rs index 5464846409ac..9bda42e5d15f 100644 --- a/src/test/ui/check-cfg/empty-values.rs +++ b/src/test/ui/check-cfg/empty-values.rs @@ -1,6 +1,10 @@ -// Check that a an empty values() pass +// Check warning for unexpected cfg value // // check-pass // compile-flags: --check-cfg=values() -Z unstable-options +#[cfg(test = "value")] +//~^ WARNING unexpected `cfg` condition value +pub fn f() {} + fn main() {} diff --git a/src/test/ui/check-cfg/empty-values.stderr b/src/test/ui/check-cfg/empty-values.stderr new file mode 100644 index 000000000000..834b28f1244c --- /dev/null +++ b/src/test/ui/check-cfg/empty-values.stderr @@ -0,0 +1,11 @@ +warning: unexpected `cfg` condition value + --> $DIR/empty-values.rs:6:7 + | +LL | #[cfg(test = "value")] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(unexpected_cfgs)]` on by default + = note: no expected value for `test` + +warning: 1 warning emitted + diff --git a/src/test/ui/check-cfg/well-known-values.rs b/src/test/ui/check-cfg/well-known-values.rs new file mode 100644 index 000000000000..46004be43d81 --- /dev/null +++ b/src/test/ui/check-cfg/well-known-values.rs @@ -0,0 +1,28 @@ +// This test check that we lint on non well known values and that we don't lint on well known +// values +// +// check-pass +// compile-flags: --check-cfg=values() -Z unstable-options + +#[cfg(target_os = "linuz")] +//~^ WARNING unexpected `cfg` condition value +fn target_os_linux_misspell() {} + +#[cfg(target_os = "linux")] +fn target_os_linux() {} + +#[cfg(target_has_atomic = "0")] +//~^ WARNING unexpected `cfg` condition value +fn target_has_atomic_invalid() {} + +#[cfg(target_has_atomic = "8")] +fn target_has_atomic() {} + +#[cfg(unix = "aa")] +//~^ WARNING unexpected `cfg` condition value +fn unix_with_value() {} + +#[cfg(unix)] +fn unix() {} + +fn main() {} diff --git a/src/test/ui/check-cfg/well-known-values.stderr b/src/test/ui/check-cfg/well-known-values.stderr new file mode 100644 index 000000000000..05b2a8af0eec --- /dev/null +++ b/src/test/ui/check-cfg/well-known-values.stderr @@ -0,0 +1,31 @@ +warning: unexpected `cfg` condition value + --> $DIR/well-known-values.rs:7:7 + | +LL | #[cfg(target_os = "linuz")] + | ^^^^^^^^^^^^------- + | | + | help: did you mean: `"linux"` + | + = note: `#[warn(unexpected_cfgs)]` on by default + = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, windows + +warning: unexpected `cfg` condition value + --> $DIR/well-known-values.rs:14:7 + | +LL | #[cfg(target_has_atomic = "0")] + | ^^^^^^^^^^^^^^^^^^^^--- + | | + | help: did you mean: `"8"` + | + = note: expected values for `target_has_atomic` are: 128, 16, 32, 64, 8, ptr + +warning: unexpected `cfg` condition value + --> $DIR/well-known-values.rs:21:7 + | +LL | #[cfg(unix = "aa")] + | ^^^^^^^^^^^ + | + = note: no expected value for `unix` + +warning: 3 warnings emitted +