about summary refs log tree commit diff
path: root/compiler/rustc_session
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_session')
-rw-r--r--compiler/rustc_session/src/config.rs5
-rw-r--r--compiler/rustc_session/src/config/cfg.rs65
-rw-r--r--compiler/rustc_session/src/parse.rs12
3 files changed, 80 insertions, 2 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index a60af3f2d71..20c14a98502 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1304,7 +1304,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
diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs
index 4109ebb6d34..a64b1e21e9e 100644
--- a/compiler/rustc_session/src/config/cfg.rs
+++ b/compiler/rustc_session/src/config/cfg.rs
@@ -17,12 +17,16 @@
 //!  - 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 std::hash::Hash;
 use std::iter;
 
+use rustc_ast::ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
+use rustc_lint_defs::builtin::EXPLICIT_BUILTIN_CFGS_IN_FLAGS;
+use rustc_lint_defs::BuiltinLintDiag;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_target::abi::Align;
 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> {
     }
 }
 
+/// Disallow builtin cfgs from the CLI.
+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(
+            EXPLICIT_BUILTIN_CFGS_IN_FLAGS,
+            None,
+            ast::CRATE_NODE_ID,
+            BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by },
+        )
+    };
+
+    // We want to restrict setting builtin cfgs that will produce incoherent behavior
+    // between the cfg and the rustc cli flag that sets it.
+    //
+    // The tests are in tests/ui/cfg/disallowed-cli-cfgs.rs.
+
+    // By-default all builtin cfgs are disallowed, only those are allowed:
+    //  - test: as it makes sense to the have the `test` cfg active without the builtin
+    //          test harness. See Cargo `harness = false` config.
+    //
+    // Cargo `--cfg test`: https://github.com/rust-lang/cargo/blob/bc89bffa5987d4af8f71011c7557119b39e44a65/src/cargo/core/compiler/mod.rs#L1124
+
+    for cfg in user_cfgs {
+        match cfg {
+            (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();
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index ebd5021dae1..d6c58e9d1be 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -307,9 +307,19 @@ impl ParseSess {
         node_id: NodeId,
         diagnostic: BuiltinLintDiag,
     ) {
+        self.opt_span_buffer_lint(lint, Some(span.into()), node_id, diagnostic)
+    }
+
+    pub fn opt_span_buffer_lint(
+        &self,
+        lint: &'static Lint,
+        span: Option<MultiSpan>,
+        node_id: NodeId,
+        diagnostic: BuiltinLintDiag,
+    ) {
         self.buffered_lints.with_lock(|buffered_lints| {
             buffered_lints.push(BufferedEarlyLint {
-                span: span.into(),
+                span,
                 node_id,
                 lint_id: LintId::of(lint),
                 diagnostic,