Skip to content

Commit 7e5deec

Browse files
committed
-Zunsigned-char=unsigned|signed|default flag for c_char->u8/i8 selection override
1 parent ac91805 commit 7e5deec

File tree

12 files changed

+130
-8
lines changed

12 files changed

+130
-8
lines changed

compiler/rustc_session/src/config.rs

+31-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
2323
use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
2424
use rustc_span::source_map::FilePathMapping;
2525
use rustc_span::{
26-
FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm, Symbol, sym,
26+
FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm, Symbol, kw, sym,
2727
};
2828
use rustc_target::spec::{
2929
FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTuple,
@@ -2946,7 +2946,7 @@ pub(crate) mod dep_tracking {
29462946
LtoCli, MirStripDebugInfo, NextSolverConfig, OomStrategy, OptLevel, OutFileName,
29472947
OutputType, OutputTypes, PatchableFunctionEntry, Polonius, RemapPathScopeComponents,
29482948
ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath,
2949-
SymbolManglingVersion, WasiExecModel,
2949+
SymbolManglingVersion, UnsignedCharVar, WasiExecModel,
29502950
};
29512951
use crate::lint;
29522952
use crate::utils::NativeLib;
@@ -3049,6 +3049,7 @@ pub(crate) mod dep_tracking {
30493049
FunctionReturn,
30503050
WasmCAbi,
30513051
Align,
3052+
UnsignedCharVar,
30523053
);
30533054

30543055
impl<T1, T2> DepTrackingHash for (T1, T2)
@@ -3323,3 +3324,31 @@ impl MirIncludeSpans {
33233324
self == MirIncludeSpans::On
33243325
}
33253326
}
3327+
3328+
/// The different settings that the `-Zunsigned-char` flag can have.
3329+
#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
3330+
pub enum UnsignedCharVar {
3331+
/// Use default signed/unsigned c_char according to target configuration
3332+
#[default]
3333+
Default,
3334+
3335+
/// Set c_char to signed i8
3336+
Signed,
3337+
3338+
/// Set c_char to unsigned u8
3339+
Unsigned,
3340+
}
3341+
3342+
impl UnsignedCharVar {
3343+
pub const fn desc_symbol(&self) -> Symbol {
3344+
match *self {
3345+
Self::Default => kw::Default,
3346+
Self::Signed => sym::signed,
3347+
Self::Unsigned => sym::unsigned,
3348+
}
3349+
}
3350+
3351+
pub const fn all() -> [Symbol; 3] {
3352+
[Self::Unsigned.desc_symbol(), Self::Signed.desc_symbol(), Self::Default.desc_symbol()]
3353+
}
3354+
}

compiler/rustc_session/src/config/cfg.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use rustc_span::{Symbol, sym};
3232
use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, Target};
3333

3434
use crate::Session;
35-
use crate::config::{CrateType, FmtDebug};
35+
use crate::config::{CrateType, FmtDebug, UnsignedCharVar};
3636

3737
/// The parsed `--cfg` options that define the compilation environment of the
3838
/// crate, used to drive conditional compilation.
@@ -144,6 +144,7 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
144144
| (sym::target_has_atomic_load_store, Some(_))
145145
| (sym::target_thread_local, None) => disallow(cfg, "--target"),
146146
(sym::fmt_debug, None | Some(_)) => disallow(cfg, "-Z fmt-debug"),
147+
(sym::unsigned_char, None | Some(_)) => disallow(cfg, "-Z unsigned-char"),
147148
(sym::emscripten_wasm_eh, None | Some(_)) => disallow(cfg, "-Z emscripten_wasm_eh"),
148149
_ => {}
149150
}
@@ -306,6 +307,8 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
306307
ins_none!(sym::contract_checks);
307308
}
308309

310+
ins_sym!(sym::unsigned_char, sess.opts.unstable_opts.unsigned_char.desc_symbol());
311+
309312
ret
310313
}
311314

@@ -470,5 +473,7 @@ impl CheckCfg {
470473

471474
ins!(sym::unix, no_values);
472475
ins!(sym::windows, no_values);
476+
477+
ins!(sym::unsigned_char, empty_values).extend(UnsignedCharVar::all());
473478
}
474479
}

compiler/rustc_session/src/options.rs

+13
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,7 @@ mod desc {
794794
pub(crate) const parse_mir_include_spans: &str =
795795
"either a boolean (`yes`, `no`, `on`, `off`, etc), or `nll` (default: `nll`)";
796796
pub(crate) const parse_align: &str = "a number that is a power of 2 between 1 and 2^29";
797+
pub(crate) const parse_unsigned_char_var: &str = "one of `default`, `unsigned`, `signed`";
797798
}
798799

799800
pub mod parse {
@@ -954,6 +955,16 @@ pub mod parse {
954955
true
955956
}
956957

958+
pub(crate) fn parse_unsigned_char_var(slot: &mut UnsignedCharVar, v: Option<&str>) -> bool {
959+
*slot = match v {
960+
Some("unsigned") => UnsignedCharVar::Unsigned,
961+
Some("signed") => UnsignedCharVar::Signed,
962+
Some("default") => UnsignedCharVar::Default,
963+
_ => return false,
964+
};
965+
true
966+
}
967+
957968
pub(crate) fn parse_location_detail(ld: &mut LocationDetail, v: Option<&str>) -> bool {
958969
if let Some(v) = v {
959970
ld.line = false;
@@ -2567,6 +2578,8 @@ written to standard error output)"),
25672578
`hir-tree` (dump the raw HIR),
25682579
`thir-tree`, `thir-flat`,
25692580
`mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)"),
2581+
unsigned_char: UnsignedCharVar = (UnsignedCharVar::default(), parse_unsigned_char_var, [TRACKED TARGET_MODIFIER],
2582+
"Make c_char type unsigned [default|signed|unsigned]"),
25702583
unsound_mir_opts: bool = (false, parse_bool, [TRACKED],
25712584
"enable unsound and buggy MIR optimizations (default: no)"),
25722585
/// This name is kind of confusing: Most unstable options enable something themselves, while

compiler/rustc_span/src/symbol.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,7 @@ symbols! {
18471847
shr_assign,
18481848
sig_dfl,
18491849
sig_ign,
1850+
signed,
18501851
simd,
18511852
simd_add,
18521853
simd_and,
@@ -2160,6 +2161,8 @@ symbols! {
21602161
unsafe_fields,
21612162
unsafe_no_drop_flag,
21622163
unsafe_pin_internals,
2164+
unsigned,
2165+
unsigned_char,
21632166
unsize,
21642167
unsized_const_param_ty,
21652168
unsized_const_params,

library/core/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@ check-cfg = [
3636
# and to stdarch `core_arch` crate which messes-up with Cargo list
3737
# of declared features, we therefor expect any feature cfg
3838
'cfg(feature, values(any()))',
39+
'cfg(unsigned_char, values(any()))'
3940
]

library/core/src/ffi/primitives.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ mod c_char_definition {
102102
// architecture defaults). As we only have a target for userspace apps so there are no
103103
// special cases for L4Re below.
104104
// https://github.com/rust-lang/rust/pull/132975#issuecomment-2484645240
105-
if #[cfg(all(
105+
if #[cfg(any(unsigned_char = "unsigned", all(
106+
not(unsigned_char = "signed"),
106107
not(windows),
107108
not(target_vendor = "apple"),
108109
any(
@@ -118,7 +119,7 @@ mod c_char_definition {
118119
target_arch = "s390x",
119120
target_arch = "xtensa",
120121
)
121-
))] {
122+
)))] {
122123
pub(super) type c_char = u8;
123124
} else {
124125
// On every other target, c_char is signed.

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

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//@ revisions: target_thread_local_ relocation_model_
99
//@ revisions: fmt_debug_
1010
//@ revisions: emscripten_wasm_eh_
11+
//@ revisions: unsigned_char_
1112

1213
//@ [overflow_checks_]compile-flags: --cfg overflow_checks
1314
//@ [debug_assertions_]compile-flags: --cfg debug_assertions
@@ -35,5 +36,6 @@
3536
//@ [relocation_model_]compile-flags: --cfg relocation_model="a"
3637
//@ [fmt_debug_]compile-flags: --cfg fmt_debug="shallow"
3738
//@ [emscripten_wasm_eh_]compile-flags: --cfg emscripten_wasm_eh
39+
//@ [unsigned_char_]compile-flags: --cfg unsigned_char="unsigned"
3840

3941
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: unexpected `--cfg unsigned_char="unsigned"` flag
2+
|
3+
= note: config `unsigned_char` is only supposed to be controlled by `-Z unsigned-char`
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/check-cfg/well-known-names.stderr

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ LL | #[cfg(list_all_well_known_cfgs)]
3333
`target_thread_local`
3434
`target_vendor`
3535
`ub_checks`
36-
`unix`, and `windows`
36+
`unix`
37+
`unsigned_char`, and `windows`
3738
= help: to expect this configuration use `--check-cfg=cfg(list_all_well_known_cfgs)`
3839
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
3940
= note: `#[warn(unexpected_cfgs)]` on by default

tests/ui/check-cfg/well-known-values.rs

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
//~^ WARN unexpected `cfg` condition value
8181
unix = "_UNEXPECTED_VALUE",
8282
//~^ WARN unexpected `cfg` condition value
83+
unsigned_char = "_UNEXPECTED_VALUE",
84+
//~^ WARN unexpected `cfg` condition value
8385
windows = "_UNEXPECTED_VALUE",
8486
//~^ WARN unexpected `cfg` condition value
8587
// tidy-alphabetical-end

tests/ui/check-cfg/well-known-values.stderr

+11-2
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,15 @@ LL | unix = "_UNEXPECTED_VALUE",
258258
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
259259
--> $DIR/well-known-values.rs:83:5
260260
|
261+
LL | unsigned_char = "_UNEXPECTED_VALUE",
262+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
263+
|
264+
= note: expected values for `unsigned_char` are: `default`, `signed`, and `unsigned`
265+
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
266+
267+
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
268+
--> $DIR/well-known-values.rs:85:5
269+
|
261270
LL | windows = "_UNEXPECTED_VALUE",
262271
| ^^^^^^^----------------------
263272
| |
@@ -267,7 +276,7 @@ LL | windows = "_UNEXPECTED_VALUE",
267276
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
268277

269278
warning: unexpected `cfg` condition value: `linuz`
270-
--> $DIR/well-known-values.rs:89:7
279+
--> $DIR/well-known-values.rs:91:7
271280
|
272281
LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
273282
| ^^^^^^^^^^^^-------
@@ -277,5 +286,5 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
277286
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
278287
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
279288

280-
warning: 28 warnings emitted
289+
warning: 29 warnings emitted
281290

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//@ build-pass
2+
//@ revisions: unsigned_ signed_ default_
3+
//@ [unsigned_] compile-flags: -Zunsigned-char=unsigned
4+
//@ [signed_] compile-flags: -Zunsigned-char=signed
5+
//@ [default_] compile-flags: -Zunsigned-char=default
6+
7+
#![no_core]
8+
#![crate_type = "rlib"]
9+
#![feature(intrinsics, rustc_attrs, no_core, lang_items, staged_api)]
10+
#![stable(feature = "test", since = "1.0.0")]
11+
12+
#[lang="sized"]
13+
trait Sized {}
14+
#[lang = "copy"]
15+
trait Copy {}
16+
impl Copy for bool {}
17+
18+
#[stable(feature = "test", since = "1.0.0")]
19+
#[rustc_const_stable(feature = "test", since = "1.0.0")]
20+
#[rustc_intrinsic]
21+
const unsafe fn unreachable() -> !;
22+
23+
#[rustc_builtin_macro]
24+
macro_rules! cfg {
25+
($($cfg:tt)*) => {};
26+
}
27+
28+
const fn do_or_die(cond: bool) {
29+
if cond {
30+
} else {
31+
unsafe { unreachable() }
32+
}
33+
}
34+
35+
macro_rules! assert {
36+
($x:expr $(,)?) => {
37+
const _: () = do_or_die($x);
38+
};
39+
}
40+
41+
fn main() {
42+
#[cfg(unsigned_)]
43+
assert!(cfg!(unsigned_char = "unsigned"));
44+
#[cfg(signed_)]
45+
assert!(cfg!(unsigned_char = "signed"));
46+
#[cfg(default_)]
47+
assert!(cfg!(unsigned_char = "default"));
48+
}

0 commit comments

Comments
 (0)