Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 20090e6

Browse files
committed
Disallow setting built-in cfgs via set the command-line
1 parent 9531c0d commit 20090e6

38 files changed

+381
-18
lines changed

compiler/rustc_lint/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,10 @@ lint_undropped_manually_drops = calls to `std::mem::drop` with `std::mem::Manual
775775
.label = argument has type `{$arg_ty}`
776776
.suggestion = use `std::mem::ManuallyDrop::into_inner` to get the inner value
777777
778+
lint_unexpected_builtin_cfg = unexpected `--cfg {$cfg}` flag
779+
.controlled_by = config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}`
780+
.incoherent = manually setting a built-in cfg can and does create incoherent behaviors
781+
778782
lint_unexpected_cfg_add_build_rs_println = or consider adding `{$build_rs_println}` to the top of the `build.rs`
779783
lint_unexpected_cfg_add_cargo_feature = consider using a Cargo feature instead
780784
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}

compiler/rustc_lint/src/context/diagnostics.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,5 +438,8 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
438438
BuiltinLintDiag::OutOfScopeMacroCalls { path } => {
439439
lints::OutOfScopeMacroCalls { path }.decorate_lint(diag)
440440
}
441+
BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => {
442+
lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag)
443+
}
441444
}
442445
}

compiler/rustc_lint/src/lints.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2377,6 +2377,16 @@ pub mod unexpected_cfg_value {
23772377
}
23782378
}
23792379

2380+
#[derive(LintDiagnostic)]
2381+
#[diag(lint_unexpected_builtin_cfg)]
2382+
#[note(lint_controlled_by)]
2383+
#[note(lint_incoherent)]
2384+
pub struct UnexpectedBuiltinCfg {
2385+
pub(crate) cfg: String,
2386+
pub(crate) cfg_name: Symbol,
2387+
pub(crate) controlled_by: &'static str,
2388+
}
2389+
23802390
#[derive(LintDiagnostic)]
23812391
#[diag(lint_macro_use_deprecated)]
23822392
#[help]

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ declare_lint_pass! {
4343
DUPLICATE_MACRO_ATTRIBUTES,
4444
ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
4545
ELIDED_LIFETIMES_IN_PATHS,
46+
EXPLICIT_BUILTIN_CFGS_IN_FLAGS,
4647
EXPORTED_PRIVATE_DEPENDENCIES,
4748
FFI_UNWIND_CALLS,
4849
FORBIDDEN_LINT_GROUPS,
@@ -3289,6 +3290,39 @@ declare_lint! {
32893290
"detects unexpected names and values in `#[cfg]` conditions",
32903291
}
32913292

3293+
declare_lint! {
3294+
/// The `explicit_builtin_cfgs_in_flags` lint detects builtin cfgs set via the `--cfg` flag.
3295+
///
3296+
/// ### Example
3297+
///
3298+
/// ```text
3299+
/// rustc --cfg unix
3300+
/// ```
3301+
///
3302+
/// ```rust,ignore (needs command line option)
3303+
/// fn main() {}
3304+
/// ```
3305+
///
3306+
/// This will produce:
3307+
///
3308+
/// ```text
3309+
/// error: unexpected `--cfg unix` flag
3310+
/// |
3311+
/// = note: config `unix` is only supposed to be controlled by `--target`
3312+
/// = note: manually setting a built-in cfg can and does create incoherent behaviors
3313+
/// = note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default
3314+
/// ```
3315+
///
3316+
/// ### Explanation
3317+
///
3318+
/// Setting builtin cfgs can and does produce incoherent behavior, it's better to the use
3319+
/// the appropriate `rustc` flag that controls the config. For example setting the `windows`
3320+
/// cfg but on Linux based target.
3321+
pub EXPLICIT_BUILTIN_CFGS_IN_FLAGS,
3322+
Deny,
3323+
"detects builtin cfgs set via the `--cfg`"
3324+
}
3325+
32923326
declare_lint! {
32933327
/// The `repr_transparent_external_private_fields` lint
32943328
/// detects types marked `#[repr(transparent)]` that (transitively)

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,11 @@ pub enum BuiltinLintDiag {
746746
OutOfScopeMacroCalls {
747747
path: String,
748748
},
749+
UnexpectedBuiltinCfg {
750+
cfg: String,
751+
cfg_name: Symbol,
752+
controlled_by: &'static str,
753+
},
749754
}
750755

751756
/// Lints that are buffered up early on in the `Session` before the

compiler/rustc_session/src/config.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1300,7 +1300,10 @@ pub(crate) const fn default_lib_output() -> CrateType {
13001300
}
13011301

13021302
pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
1303-
// Combine the configuration requested by the session (command line) with
1303+
// First disallow some configuration given on the command line
1304+
cfg::disallow_cfgs(sess, &user_cfg);
1305+
1306+
// Then combine the configuration requested by the session (command line) with
13041307
// some default and generated configuration items.
13051308
user_cfg.extend(cfg::default_configuration(sess));
13061309
user_cfg

compiler/rustc_session/src/config/cfg.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@
1717
//! - Add the activation logic in [`default_configuration`]
1818
//! - Add the cfg to [`CheckCfg::fill_well_known`] (and related files),
1919
//! so that the compiler can know the cfg is expected
20+
//! - Add the cfg in [`disallow_cfgs`] to disallow users from setting it via `--cfg`
2021
//! - Add the feature gating in `compiler/rustc_feature/src/builtin_attrs.rs`
2122
2223
use std::hash::Hash;
2324
use std::iter;
2425

26+
use rustc_ast::ast;
2527
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
28+
use rustc_lint_defs::builtin::EXPLICIT_BUILTIN_CFGS_IN_FLAGS;
29+
use rustc_lint_defs::BuiltinLintDiag;
2630
use rustc_span::symbol::{sym, Symbol};
2731
use rustc_target::abi::Align;
2832
use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, Target, TargetTriple, TARGETS};
@@ -82,6 +86,67 @@ impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> {
8286
}
8387
}
8488

89+
/// Disallow builtin cfgs from the CLI.
90+
pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
91+
let disallow = |cfg: &(Symbol, Option<Symbol>), controlled_by| {
92+
let cfg_name = cfg.0;
93+
let cfg = if let Some(value) = cfg.1 {
94+
format!(r#"{}="{}""#, cfg_name, value)
95+
} else {
96+
format!("{}", cfg_name)
97+
};
98+
sess.psess.opt_span_buffer_lint(
99+
EXPLICIT_BUILTIN_CFGS_IN_FLAGS,
100+
None,
101+
ast::CRATE_NODE_ID,
102+
BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by },
103+
)
104+
};
105+
106+
// We want to restrict setting builtin cfgs that will produce incoherent behavior
107+
// between the cfg and the rustc cli flag that sets it.
108+
//
109+
// The tests are in tests/ui/cfg/disallowed-cli-cfgs.rs.
110+
111+
// By-default all builtin cfgs are disallowed, only those are allowed:
112+
// - test: as it makes sense to the have the `test` cfg active without the builtin
113+
// test harness. See Cargo `harness = false` config.
114+
//
115+
// Cargo `--cfg test`: https://github.com/rust-lang/cargo/blob/bc89bffa5987d4af8f71011c7557119b39e44a65/src/cargo/core/compiler/mod.rs#L1124
116+
117+
for cfg in user_cfgs {
118+
match cfg {
119+
(sym::overflow_checks, None) => disallow(cfg, "-C overflow-checks"),
120+
(sym::debug_assertions, None) => disallow(cfg, "-C debug-assertions"),
121+
(sym::ub_checks, None) => disallow(cfg, "-Z ub-checks"),
122+
(sym::sanitize, None | Some(_)) => disallow(cfg, "-Z sanitizer"),
123+
(
124+
sym::sanitizer_cfi_generalize_pointers | sym::sanitizer_cfi_normalize_integers,
125+
None | Some(_),
126+
) => disallow(cfg, "-Z sanitizer=cfi"),
127+
(sym::proc_macro, None) => disallow(cfg, "--crate-type proc-macro"),
128+
(sym::panic, Some(sym::abort | sym::unwind)) => disallow(cfg, "-C panic"),
129+
(sym::target_feature, Some(_)) => disallow(cfg, "-C target-feature"),
130+
(sym::unix, None)
131+
| (sym::windows, None)
132+
| (sym::relocation_model, Some(_))
133+
| (sym::target_abi, None | Some(_))
134+
| (sym::target_arch, Some(_))
135+
| (sym::target_endian, Some(_))
136+
| (sym::target_env, None | Some(_))
137+
| (sym::target_family, Some(_))
138+
| (sym::target_os, Some(_))
139+
| (sym::target_pointer_width, Some(_))
140+
| (sym::target_vendor, None | Some(_))
141+
| (sym::target_has_atomic, Some(_))
142+
| (sym::target_has_atomic_equal_alignment, Some(_))
143+
| (sym::target_has_atomic_load_store, Some(_))
144+
| (sym::target_thread_local, None) => disallow(cfg, "--target"),
145+
_ => {}
146+
}
147+
}
148+
}
149+
85150
/// Generate the default configs for a given session
86151
pub(crate) fn default_configuration(sess: &Session) -> Cfg {
87152
let mut ret = Cfg::default();

tests/codegen/aarch64-struct-align-128.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Test that structs aligned to 128 bits are passed with the correct ABI on aarch64.
22

3-
//@ revisions:linux darwin windows
3+
//@ revisions: linux darwin win
44
//@[linux] compile-flags: --target aarch64-unknown-linux-gnu
55
//@[darwin] compile-flags: --target aarch64-apple-darwin
6-
//@[windows] compile-flags: --target aarch64-pc-windows-msvc
6+
//@[win] compile-flags: --target aarch64-pc-windows-msvc
77
//@[linux] needs-llvm-components: aarch64
88
//@[darwin] needs-llvm-components: aarch64
9-
//@[windows] needs-llvm-components: aarch64
9+
//@[win] needs-llvm-components: aarch64
1010

1111
#![feature(no_core, lang_items)]
1212
#![crate_type = "lib"]
@@ -41,7 +41,7 @@ pub struct Wrapped8 {
4141
extern "C" {
4242
// linux: declare void @test_8([2 x i64], [2 x i64], [2 x i64])
4343
// darwin: declare void @test_8([2 x i64], [2 x i64], [2 x i64])
44-
// windows: declare void @test_8([2 x i64], [2 x i64], [2 x i64])
44+
// win: declare void @test_8([2 x i64], [2 x i64], [2 x i64])
4545
fn test_8(a: Align8, b: Transparent8, c: Wrapped8);
4646
}
4747

@@ -71,7 +71,7 @@ pub struct Wrapped16 {
7171
extern "C" {
7272
// linux: declare void @test_16([2 x i64], [2 x i64], i128)
7373
// darwin: declare void @test_16(i128, i128, i128)
74-
// windows: declare void @test_16(i128, i128, i128)
74+
// win: declare void @test_16(i128, i128, i128)
7575
fn test_16(a: Align16, b: Transparent16, c: Wrapped16);
7676
}
7777

@@ -96,7 +96,7 @@ pub struct WrappedI128 {
9696
extern "C" {
9797
// linux: declare void @test_i128(i128, i128, i128)
9898
// darwin: declare void @test_i128(i128, i128, i128)
99-
// windows: declare void @test_i128(i128, i128, i128)
99+
// win: declare void @test_i128(i128, i128, i128)
100100
fn test_i128(a: I128, b: TransparentI128, c: WrappedI128);
101101
}
102102

@@ -123,7 +123,7 @@ pub struct WrappedPacked {
123123
extern "C" {
124124
// linux: declare void @test_packed([2 x i64], [2 x i64], [2 x i64])
125125
// darwin: declare void @test_packed([2 x i64], [2 x i64], [2 x i64])
126-
// windows: declare void @test_packed([2 x i64], [2 x i64], [2 x i64])
126+
// win: declare void @test_packed([2 x i64], [2 x i64], [2 x i64])
127127
fn test_packed(a: Packed, b: TransparentPacked, c: WrappedPacked);
128128
}
129129

tests/codegen/default-requires-uwtable.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
//@ revisions: WINDOWS ANDROID
1+
//@ revisions: WINDOWS_ ANDROID_
22
//@ compile-flags: -C panic=abort -Copt-level=0
3-
//@ [WINDOWS] compile-flags: --target=x86_64-pc-windows-msvc
4-
//@ [WINDOWS] needs-llvm-components: x86
5-
//@ [ANDROID] compile-flags: --target=armv7-linux-androideabi
6-
//@ [ANDROID] needs-llvm-components: arm
3+
//@ [WINDOWS_] compile-flags: --target=x86_64-pc-windows-msvc
4+
//@ [WINDOWS_] needs-llvm-components: x86
5+
//@ [ANDROID_] compile-flags: --target=armv7-linux-androideabi
6+
//@ [ANDROID_] needs-llvm-components: arm
77

88
#![feature(no_core, lang_items)]
99
#![crate_type = "lib"]

tests/codegen/repr/transparent-sysv64.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
//@ revisions: linux apple windows
1+
//@ revisions: linux apple win
22
//@ compile-flags: -O -C no-prepopulate-passes
33

44
//@[linux] compile-flags: --target x86_64-unknown-linux-gnu
55
//@[linux] needs-llvm-components: x86
66
//@[apple] compile-flags: --target x86_64-apple-darwin
77
//@[apple] needs-llvm-components: x86
8-
//@[windows] compile-flags: --target x86_64-pc-windows-msvc
9-
//@[windows] needs-llvm-components: x86
8+
//@[win] compile-flags: --target x86_64-pc-windows-msvc
9+
//@[win] needs-llvm-components: x86
1010

1111
#![feature(no_core, lang_items)]
1212
#![crate_type = "lib"]

tests/debuginfo/thread-names.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//@ compile-flags:-g
2-
//@ revisions: macos windows
2+
//@ revisions: macos win
33
// We can't set the main thread name on Linux because it renames the process (#97191)
44
//@[macos] only-macos
5-
//@[windows] only-windows
5+
//@[win] only-windows
66
//@ ignore-sgx
77
//@ ignore-windows-gnu
88

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//@ check-pass
2+
//@ compile-flags: --cfg unix -Aexplicit_builtin_cfgs_in_flags
3+
4+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: unexpected `--cfg debug_assertions` flag
2+
|
3+
= note: config `debug_assertions` is only supposed to be controlled by `-C debug-assertions`
4+
= note: manually setting a built-in cfg can and does create incoherent behaviors
5+
= note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default
6+
7+
error: aborting due to 1 previous error
8+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: unexpected `--cfg overflow_checks` flag
2+
|
3+
= note: config `overflow_checks` is only supposed to be controlled by `-C overflow-checks`
4+
= note: manually setting a built-in cfg can and does create incoherent behaviors
5+
= note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default
6+
7+
error: aborting due to 1 previous error
8+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: unexpected `--cfg panic="abort"` flag
2+
|
3+
= note: config `panic` is only supposed to be controlled by `-C panic`
4+
= note: manually setting a built-in cfg can and does create incoherent behaviors
5+
= note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default
6+
7+
error: aborting due to 1 previous error
8+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: unexpected `--cfg proc_macro` flag
2+
|
3+
= note: config `proc_macro` is only supposed to be controlled by `--crate-type proc-macro`
4+
= note: manually setting a built-in cfg can and does create incoherent behaviors
5+
= note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default
6+
7+
error: aborting due to 1 previous error
8+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: unexpected `--cfg relocation_model="a"` flag
2+
|
3+
= note: config `relocation_model` is only supposed to be controlled by `--target`
4+
= note: manually setting a built-in cfg can and does create incoherent behaviors
5+
= note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default
6+
7+
error: aborting due to 1 previous error
8+

tests/ui/cfg/disallowed-cli-cfgs.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//@ check-fail
2+
//@ revisions: overflow_checks_ debug_assertions_ ub_checks_ sanitize_
3+
//@ revisions: sanitizer_cfi_generalize_pointers_ sanitizer_cfi_normalize_integers_
4+
//@ revisions: proc_macro_ panic_ target_feature_ unix_ windows_ target_abi_
5+
//@ revisions: target_arch_ target_endian_ target_env_ target_family_ target_os_
6+
//@ revisions: target_pointer_width_ target_vendor_ target_has_atomic_
7+
//@ revisions: target_has_atomic_equal_alignment_ target_has_atomic_load_store_
8+
//@ revisions: target_thread_local_ relocation_model_
9+
10+
//@ [overflow_checks_]compile-flags: --cfg overflow_checks
11+
//@ [debug_assertions_]compile-flags: --cfg debug_assertions
12+
//@ [ub_checks_]compile-flags: --cfg ub_checks
13+
//@ [sanitize_]compile-flags: --cfg sanitize="cfi"
14+
//@ [sanitizer_cfi_generalize_pointers_]compile-flags: --cfg sanitizer_cfi_generalize_pointers
15+
//@ [sanitizer_cfi_normalize_integers_]compile-flags: --cfg sanitizer_cfi_normalize_integers
16+
//@ [proc_macro_]compile-flags: --cfg proc_macro
17+
//@ [panic_]compile-flags: --cfg panic="abort"
18+
//@ [target_feature_]compile-flags: --cfg target_feature="sse3"
19+
//@ [unix_]compile-flags: --cfg unix
20+
//@ [windows_]compile-flags: --cfg windows
21+
//@ [target_abi_]compile-flags: --cfg target_abi="gnu"
22+
//@ [target_arch_]compile-flags: --cfg target_arch="arm"
23+
//@ [target_endian_]compile-flags: --cfg target_endian="little"
24+
//@ [target_env_]compile-flags: --cfg target_env
25+
//@ [target_family_]compile-flags: --cfg target_family="unix"
26+
//@ [target_os_]compile-flags: --cfg target_os="linux"
27+
//@ [target_pointer_width_]compile-flags: --cfg target_pointer_width="32"
28+
//@ [target_vendor_]compile-flags: --cfg target_vendor
29+
//@ [target_has_atomic_]compile-flags: --cfg target_has_atomic="32"
30+
//@ [target_has_atomic_equal_alignment_]compile-flags: --cfg target_has_atomic_equal_alignment="32"
31+
//@ [target_has_atomic_load_store_]compile-flags: --cfg target_has_atomic_load_store="32"
32+
//@ [target_thread_local_]compile-flags: --cfg target_thread_local
33+
//@ [relocation_model_]compile-flags: --cfg relocation_model="a"
34+
35+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: unexpected `--cfg sanitize="cfi"` flag
2+
|
3+
= note: config `sanitize` is only supposed to be controlled by `-Z sanitizer`
4+
= note: manually setting a built-in cfg can and does create incoherent behaviors
5+
= note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default
6+
7+
error: aborting due to 1 previous error
8+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: unexpected `--cfg sanitizer_cfi_generalize_pointers` flag
2+
|
3+
= note: config `sanitizer_cfi_generalize_pointers` is only supposed to be controlled by `-Z sanitizer=cfi`
4+
= note: manually setting a built-in cfg can and does create incoherent behaviors
5+
= note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)