Skip to content

Commit

Permalink
Disallow setting built-in cfgs via set the command-line
Browse files Browse the repository at this point in the history
  • Loading branch information
Urgau committed Jun 22, 2024
1 parent ff63c14 commit 4ebdd5c
Show file tree
Hide file tree
Showing 35 changed files with 374 additions and 2 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,10 @@ lint_undropped_manually_drops = calls to `std::mem::drop` with `std::mem::Manual
.label = argument has type `{$arg_ty}`
.suggestion = use `std::mem::ManuallyDrop::into_inner` to get the inner value
lint_unexpected_builtin_cfg = unexpected `--cfg {$cfg}` flag
.controlled_by = config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}`
.issue = see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
lint_unexpected_cfg_add_build_rs_println = or consider adding `{$build_rs_println}` to the top of the `build.rs`
lint_unexpected_cfg_add_cargo_feature = consider using a Cargo feature instead
lint_unexpected_cfg_add_cargo_toml_lint_cfg = or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:{$cargo_toml_lint_cfg}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_lint/src/context/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,5 +424,8 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
lints::InnerAttributeUnstable::CustomInnerAttribute
}
.decorate_lint(diag),
BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => {
lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag)
}
}
}
10 changes: 10 additions & 0 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2319,6 +2319,16 @@ pub mod unexpected_cfg_value {
}
}

#[derive(LintDiagnostic)]
#[diag(lint_unexpected_builtin_cfg)]
#[note(lint_controlled_by)]
#[note(lint_issue)]
pub struct UnexpectedBuiltinCfg {
pub(crate) cfg: String,
pub(crate) cfg_name: Symbol,
pub(crate) controlled_by: &'static str,
}

#[derive(LintDiagnostic)]
#[diag(lint_macro_use_deprecated)]
#[help]
Expand Down
34 changes: 34 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ declare_lint_pass! {
UNCONDITIONAL_RECURSION,
UNCOVERED_PARAM_IN_PROJECTION,
UNDEFINED_NAKED_FUNCTION_ABI,
UNEXPECTED_BUILTIN_CFGS,
UNEXPECTED_CFGS,
UNFULFILLED_LINT_EXPECTATIONS,
UNINHABITED_STATIC,
Expand Down Expand Up @@ -3268,6 +3269,39 @@ declare_lint! {
"detects unexpected names and values in `#[cfg]` conditions",
}

declare_lint! {
/// The `unexpected_builtin_cfgs` lint detects builtin cfgs set via the CLI, `--cfg`.
///
/// ### Example
///
/// ```text
/// rustc --cfg unix
/// ```
///
/// ```rust,ignore (needs command line option)
/// fn main() {}
/// ```
///
/// This will produce:
///
/// ```text
/// error: unexpected `--cfg unix` flag
/// |
/// = note: config `unix` is only supposed to be controlled by `--target`
/// = note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
/// = note: `#[deny(unexpected_builtin_cfgs)]` on by default
/// ```
///
/// ### Explanation
///
/// Setting builtin cfgs can and does produce incoherent behavior, it's better to the use
/// the appropriate `rustc` flag that controls the config. For example setting the `windows`
/// cfg but on Linux based target.
pub UNEXPECTED_BUILTIN_CFGS,
Deny,
"detects builtin cfgs set via the `--cfg`"
}

declare_lint! {
/// The `repr_transparent_external_private_fields` lint
/// detects types marked `#[repr(transparent)]` that (transitively)
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_lint_defs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,11 @@ pub enum BuiltinLintDiag {
InnerAttributeUnstable {
is_macro: bool,
},
UnexpectedBuiltinCfg {
cfg: String,
cfg_name: Symbol,
controlled_by: &'static str,
},
}

/// Lints that are buffered up early on in the `Session` before the
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1292,7 +1292,10 @@ pub(crate) const fn default_lib_output() -> CrateType {
}

pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
// Combine the configuration requested by the session (command line) with
// First disallow some configuration given on the command line
cfg::disallow_cfgs(sess, &user_cfg);

// Then combine the configuration requested by the session (command line) with
// some default and generated configuration items.
user_cfg.extend(cfg::default_configuration(sess));
user_cfg
Expand Down
73 changes: 73 additions & 0 deletions compiler/rustc_session/src/config/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@
//! - Add the activation logic in [`default_configuration`]
//! - Add the cfg to [`CheckCfg::fill_well_known`] (and related files),
//! so that the compiler can know the cfg is expected
//! - Add the cfg in [`disallow_cfgs`] to disallow users from setting it via `--cfg`
//! - Add the feature gating in `compiler/rustc_feature/src/builtin_attrs.rs`
use rustc_ast::ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_lint_defs::builtin::UNEXPECTED_BUILTIN_CFGS;
use rustc_lint_defs::BuiltinLintDiag;
use rustc_span::symbol::{sym, Symbol};
use rustc_target::abi::Align;
use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet};
Expand Down Expand Up @@ -83,6 +87,75 @@ impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> {
}
}

/// Disallow "builtin" cfgs from the CLI as they produce incoherent behavior
pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
let disallow = |cfg: &(Symbol, Option<Symbol>), controlled_by| {
let cfg_name = cfg.0;
let cfg = if let Some(value) = cfg.1 {
format!(r#"{}="{}""#, cfg_name, value)
} else {
format!("{}", cfg_name)
};
sess.psess.opt_span_buffer_lint(
UNEXPECTED_BUILTIN_CFGS,
None,
ast::CRATE_NODE_ID,
BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by },
)
};

// We want to restrict setting cfgs that will produce "incoherent" behavior between
// the cfg and the "real" flag that sets it.
//
// The tests are in tests/ui/cfg/disallowed-cli-cfgs.rs.
//
// Not all "well known cfgs" can be disallowed, as they are set by external tools via the
// CLI, we therefore don't lint on them:
//
// - clippy
// - doc
// - doctest
// - miri
// - rustfmt
//
// doc/doctest: https://github.com/rust-lang/rust/blob/d03d6c0fead582c98c6446ec92456ca8fd03ff65/src/librustdoc/doctest.rs#L134-L135
// clippy: https://github.com/rust-lang/rust/blob/f1b0d54ca9a5ea43950c279985a6e12dcf387de8/src/tools/clippy/src/driver.rs#L276
// miri: https://github.com/rust-lang/rust/blob/d03d6c0fead582c98c6446ec92456ca8fd03ff65/src/tools/miri/src/lib.rs#L161

for cfg in user_cfgs {
match cfg {
(sym::test, None) => disallow(cfg, "--test"),
(sym::overflow_checks, None) => disallow(cfg, "-C overflow-checks"),
(sym::debug_assertions, None) => disallow(cfg, "-C debug-assertions"),
(sym::ub_checks, None) => disallow(cfg, "-Z ub-checks"),
(sym::sanitize, None | Some(_)) => disallow(cfg, "-Z sanitizer"),
(
sym::sanitizer_cfi_generalize_pointers | sym::sanitizer_cfi_normalize_integers,
None | Some(_),
) => disallow(cfg, "-Z sanitizer=cfi"),
(sym::proc_macro, None) => disallow(cfg, "--crate-type proc-macro"),
(sym::panic, Some(sym::abort | sym::unwind)) => disallow(cfg, "-C panic"),
(sym::target_feature, Some(_)) => disallow(cfg, "-C target-feature"),
(sym::unix, None)
| (sym::windows, None)
| (sym::relocation_model, Some(_))
| (sym::target_abi, None | Some(_))
| (sym::target_arch, Some(_))
| (sym::target_endian, Some(_))
| (sym::target_env, None | Some(_))
| (sym::target_family, Some(_))
| (sym::target_os, Some(_))
| (sym::target_pointer_width, Some(_))
| (sym::target_vendor, None | Some(_))
| (sym::target_has_atomic, Some(_))
| (sym::target_has_atomic_equal_alignment, Some(_))
| (sym::target_has_atomic_load_store, Some(_))
| (sym::target_thread_local, None) => disallow(cfg, "--target"),
_ => {}
}
}
}

/// Generate the default configs for a given session
pub(crate) fn default_configuration(sess: &Session) -> Cfg {
let mut ret = Cfg::default();
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs-allow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//@ check-pass
//@ compile-flags: --cfg unix -Aunexpected_builtin_cfgs

fn main() {}
8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.debug_assertions_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg debug_assertions` flag
|
= note: config `debug_assertions` is only supposed to be controlled by `-C debug-assertions`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.overflow_checks_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg overflow_checks` flag
|
= note: config `overflow_checks` is only supposed to be controlled by `-C overflow-checks`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.panic_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg panic="abort"` flag
|
= note: config `panic` is only supposed to be controlled by `-C panic`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.proc_macro_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg proc_macro` flag
|
= note: config `proc_macro` is only supposed to be controlled by `--crate-type proc-macro`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.relocation_model_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg relocation_model="a"` flag
|
= note: config `relocation_model` is only supposed to be controlled by `--target`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

36 changes: 36 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//@ check-fail
//@ revisions: test_ overflow_checks_ debug_assertions_ ub_checks_ sanitize_
//@ revisions: sanitizer_cfi_generalize_pointers_ sanitizer_cfi_normalize_integers_
//@ revisions: proc_macro_ panic_ target_feature_ unix_ windows_ target_abi_
//@ revisions: target_arch_ target_endian_ target_env_ target_family_ target_os_
//@ revisions: target_pointer_width_ target_vendor_ target_has_atomic_
//@ revisions: target_has_atomic_equal_alignment_ target_has_atomic_load_store_
//@ revisions: target_thread_local_ relocation_model_

//@ [test_]compile-flags: --cfg test
//@ [overflow_checks_]compile-flags: --cfg overflow_checks
//@ [debug_assertions_]compile-flags: --cfg debug_assertions
//@ [ub_checks_]compile-flags: --cfg ub_checks
//@ [sanitize_]compile-flags: --cfg sanitize="cfi"
//@ [sanitizer_cfi_generalize_pointers_]compile-flags: --cfg sanitizer_cfi_generalize_pointers
//@ [sanitizer_cfi_normalize_integers_]compile-flags: --cfg sanitizer_cfi_normalize_integers
//@ [proc_macro_]compile-flags: --cfg proc_macro
//@ [panic_]compile-flags: --cfg panic="abort"
//@ [target_feature_]compile-flags: --cfg target_feature="sse3"
//@ [unix_]compile-flags: --cfg unix
//@ [windows_]compile-flags: --cfg windows
//@ [target_abi_]compile-flags: --cfg target_abi="gnu"
//@ [target_arch_]compile-flags: --cfg target_arch="arm"
//@ [target_endian_]compile-flags: --cfg target_endian="little"
//@ [target_env_]compile-flags: --cfg target_env
//@ [target_family_]compile-flags: --cfg target_family="unix"
//@ [target_os_]compile-flags: --cfg target_os="linux"
//@ [target_pointer_width_]compile-flags: --cfg target_pointer_width="32"
//@ [target_vendor_]compile-flags: --cfg target_vendor
//@ [target_has_atomic_]compile-flags: --cfg target_has_atomic="32"
//@ [target_has_atomic_equal_alignment_]compile-flags: --cfg target_has_atomic_equal_alignment="32"
//@ [target_has_atomic_load_store_]compile-flags: --cfg target_has_atomic_load_store="32"
//@ [target_thread_local_]compile-flags: --cfg target_thread_local
//@ [relocation_model_]compile-flags: --cfg relocation_model="a"

fn main() {}
8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.sanitize_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg sanitize="cfi"` flag
|
= note: config `sanitize` is only supposed to be controlled by `-Z sanitizer`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg sanitizer_cfi_generalize_pointers` flag
|
= note: config `sanitizer_cfi_generalize_pointers` is only supposed to be controlled by `-Z sanitizer=cfi`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg sanitizer_cfi_normalize_integers` flag
|
= note: config `sanitizer_cfi_normalize_integers` is only supposed to be controlled by `-Z sanitizer=cfi`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.target_abi_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg target_abi="gnu"` flag
|
= note: config `target_abi` is only supposed to be controlled by `--target`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.target_arch_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg target_arch="arm"` flag
|
= note: config `target_arch` is only supposed to be controlled by `--target`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.target_endian_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg target_endian="little"` flag
|
= note: config `target_endian` is only supposed to be controlled by `--target`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.target_env_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg target_env` flag
|
= note: config `target_env` is only supposed to be controlled by `--target`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.target_family_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg target_family="unix"` flag
|
= note: config `target_family` is only supposed to be controlled by `--target`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.target_feature_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg target_feature="sse3"` flag
|
= note: config `target_feature` is only supposed to be controlled by `-C target-feature`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.target_has_atomic_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg target_has_atomic="32"` flag
|
= note: config `target_has_atomic` is only supposed to be controlled by `--target`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg target_has_atomic_equal_alignment="32"` flag
|
= note: config `target_has_atomic_equal_alignment` is only supposed to be controlled by `--target`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg target_has_atomic_load_store="32"` flag
|
= note: config `target_has_atomic_load_store` is only supposed to be controlled by `--target`
= note: see <https://github.com/rust-lang/rust/issues/xxxxx> for more information
= note: `#[deny(unexpected_builtin_cfgs)]` on by default

error: aborting due to 1 previous error

Loading

0 comments on commit 4ebdd5c

Please sign in to comment.