Skip to content

Commit 7f51a73

Browse files
committed
sanitizers: Add support for stable sanitizers
Add suppport for specifying stable sanitizers in addition to the existing supported sanitizers.
1 parent df35ff6 commit 7f51a73

File tree

123 files changed

+323
-247
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+323
-247
lines changed

compiler/rustc_codegen_llvm/src/abi.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_session::config;
1414
use rustc_target::callconv::{
1515
ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, Conv, FnAbi, PassMode,
1616
};
17-
use rustc_target::spec::SanitizerSet;
1817
use smallvec::SmallVec;
1918

2019
use crate::attributes::{self, llfn_attrs_from_instance};
@@ -82,7 +81,7 @@ fn get_attrs<'ll>(this: &ArgAttributes, cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'
8281
attrs.push(llattr.create_attr(cx.llcx));
8382
}
8483
}
85-
} else if cx.tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
84+
} else if cx.tcx.sess.is_sanitizer_memory_enabled() {
8685
// If we're not optimising, *but* memory sanitizer is on, emit noundef, since it affects
8786
// memory sanitizer's behavior.
8887

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub(crate) fn sanitize_attrs<'ll>(
8686
no_sanitize: SanitizerSet,
8787
) -> SmallVec<[&'ll Attribute; 4]> {
8888
let mut attrs = SmallVec::new();
89-
let enabled = cx.tcx.sess.opts.unstable_opts.sanitizer - no_sanitize;
89+
let enabled = cx.tcx.sess.opts.cg.sanitize - no_sanitize;
9090
if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) {
9191
attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx));
9292
}
@@ -219,13 +219,7 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
219219
// Currently stack probes seem somewhat incompatible with the address
220220
// sanitizer and thread sanitizer. With asan we're already protected from
221221
// stack overflow anyway so we don't really need stack probes regardless.
222-
if cx
223-
.sess()
224-
.opts
225-
.unstable_opts
226-
.sanitizer
227-
.intersects(SanitizerSet::ADDRESS | SanitizerSet::THREAD)
228-
{
222+
if cx.sess().is_sanitizer_address_enabled() || cx.sess().is_sanitizer_thread_enabled() {
229223
return None;
230224
}
231225

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,7 +1250,7 @@ fn add_sanitizer_libraries(
12501250
return;
12511251
}
12521252

1253-
let sanitizer = sess.opts.unstable_opts.sanitizer;
1253+
let sanitizer = sess.opts.cg.sanitize;
12541254
if sanitizer.contains(SanitizerSet::ADDRESS) {
12551255
link_sanitizer_runtime(sess, flavor, linker, "asan");
12561256
}
@@ -2480,11 +2480,7 @@ fn add_order_independent_options(
24802480
&& crate_type == CrateType::Executable
24812481
&& !matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))
24822482
{
2483-
let prefix = if sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) {
2484-
"asan/"
2485-
} else {
2486-
""
2487-
};
2483+
let prefix = if sess.is_sanitizer_address_enabled() { "asan/" } else { "" };
24882484
cmd.link_arg(format!("--dynamic-linker={prefix}ld.so.1"));
24892485
}
24902486

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_middle::util::Providers;
1515
use rustc_session::config::{CrateType, OomStrategy};
1616
use rustc_symbol_mangling::mangle_internal_symbol;
1717
use rustc_target::callconv::Conv;
18-
use rustc_target::spec::{SanitizerSet, TlsModel};
18+
use rustc_target::spec::TlsModel;
1919
use tracing::debug;
2020

2121
use crate::base::allocator_kind_for_codegen;
@@ -267,15 +267,15 @@ fn exported_symbols_provider_local(
267267
}));
268268
}
269269

270-
if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
270+
if tcx.sess.is_sanitizer_memory_enabled() {
271271
let mut msan_weak_symbols = Vec::new();
272272

273273
// Similar to profiling, preserve weak msan symbol during LTO.
274-
if tcx.sess.opts.unstable_opts.sanitizer_recover.contains(SanitizerSet::MEMORY) {
274+
if tcx.sess.is_sanitizer_memory_recover_enabled() {
275275
msan_weak_symbols.push("__msan_keep_going");
276276
}
277277

278-
if tcx.sess.opts.unstable_opts.sanitizer_memory_track_origins != 0 {
278+
if tcx.sess.is_sanitizer_memory_track_origins_enabled() {
279279
msan_weak_symbols.push("__msan_track_origins");
280280
}
281281

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl ModuleConfig {
186186
debug_info_for_profiling: sess.opts.unstable_opts.debug_info_for_profiling,
187187
instrument_coverage: if_regular!(sess.instrument_coverage(), false),
188188

189-
sanitizer: if_regular!(sess.opts.unstable_opts.sanitizer, SanitizerSet::empty()),
189+
sanitizer: if_regular!(sess.opts.cg.sanitize, SanitizerSet::empty()),
190190
sanitizer_dataflow_abilist: if_regular!(
191191
sess.opts.unstable_opts.sanitizer_dataflow_abilist.clone(),
192192
Vec::new()

compiler/rustc_interface/src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,7 @@ fn test_codegen_options_tracking_hash() {
637637
tracked!(profile_use, Some(PathBuf::from("abc")));
638638
tracked!(relocation_model, Some(RelocModel::Pic));
639639
tracked!(relro_level, Some(RelroLevel::Full));
640+
tracked!(sanitize, SanitizerSet::ADDRESS);
640641
tracked!(soft_float, true);
641642
tracked!(split_debuginfo, Some(SplitDebuginfo::Packed));
642643
tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0));
@@ -849,7 +850,6 @@ fn test_unstable_options_tracking_hash() {
849850
tracked!(regparm, Some(3));
850851
tracked!(relax_elf_relocations, Some(true));
851852
tracked!(remap_cwd_prefix, Some(PathBuf::from("abc")));
852-
tracked!(sanitizer, SanitizerSet::ADDRESS);
853853
tracked!(sanitizer_cfi_canonical_jump_tables, None);
854854
tracked!(sanitizer_cfi_generalize_pointers, Some(true));
855855
tracked!(sanitizer_cfi_normalize_integers, Some(true));

compiler/rustc_metadata/src/native_libs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub fn walk_native_lib_search_dirs<R>(
7373
|| sess.target.os == "linux"
7474
|| sess.target.os == "fuchsia"
7575
|| sess.target.is_like_aix
76-
|| sess.target.is_like_darwin && !sess.opts.unstable_opts.sanitizer.is_empty()
76+
|| sess.target.is_like_darwin && !sess.opts.cg.sanitize.is_empty()
7777
{
7878
f(&sess.target_tlib_path.dir, false)?;
7979
}

compiler/rustc_session/messages.ftl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ session_branch_protection_requires_aarch64 = `-Zbranch-protection` is only suppo
99
1010
session_cannot_enable_crt_static_linux = sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static`
1111
12-
session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}`
12+
session_cannot_mix_and_match_sanitizers = `-Csanitize={$first}` is incompatible with `-Csanitize={$second}`
1313
1414
session_cli_feature_diagnostic_help =
1515
add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable
@@ -90,15 +90,15 @@ session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C pr
9090
9191
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist
9292
93-
session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi`
93+
session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Csanitize=cfi`
9494
95-
session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`
95+
session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-generalize-pointers` requires `-Csanitize=cfi` or `-Csanitize=kcfi`
9696
97-
session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`
97+
session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Csanitize=cfi` or `-Csanitize=kcfi`
9898
99-
session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`
99+
session_sanitizer_cfi_requires_lto = `-Csanitize=cfi` requires `-Clto` or `-Clinker-plugin-lto`
100100
101-
session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
101+
session_sanitizer_cfi_requires_single_codegen_unit = `-Csanitize=cfi` with `-Clto` requires `-Ccodegen-units=1`
102102
103103
session_sanitizer_kcfi_arity_requires_kcfi = `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`
104104

compiler/rustc_session/src/config/cfg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
212212
ins_sym!(sym::relocation_model, sess.target.relocation_model.desc_symbol());
213213
}
214214

215-
for mut s in sess.opts.unstable_opts.sanitizer {
215+
for mut s in sess.opts.cg.sanitize {
216216
// KASAN is still ASAN under the hood, so it uses the same attribute.
217217
if s == SanitizerSet::KERNELADDRESS {
218218
s = SanitizerSet::ADDRESS;

compiler/rustc_session/src/options.rs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,25 +1156,14 @@ pub mod parse {
11561156
}
11571157

11581158
pub(crate) fn parse_sanitizers(slot: &mut SanitizerSet, v: Option<&str>) -> bool {
1159-
if let Some(v) = v {
1160-
for s in v.split(',') {
1161-
*slot |= match s {
1162-
"address" => SanitizerSet::ADDRESS,
1163-
"cfi" => SanitizerSet::CFI,
1164-
"dataflow" => SanitizerSet::DATAFLOW,
1165-
"kcfi" => SanitizerSet::KCFI,
1166-
"kernel-address" => SanitizerSet::KERNELADDRESS,
1167-
"leak" => SanitizerSet::LEAK,
1168-
"memory" => SanitizerSet::MEMORY,
1169-
"memtag" => SanitizerSet::MEMTAG,
1170-
"shadow-call-stack" => SanitizerSet::SHADOWCALLSTACK,
1171-
"thread" => SanitizerSet::THREAD,
1172-
"hwaddress" => SanitizerSet::HWADDRESS,
1173-
"safestack" => SanitizerSet::SAFESTACK,
1174-
_ => return false,
1175-
}
1159+
if let Some(s) = v {
1160+
let sanitizer_set = SanitizerSet::from_comma_list(s);
1161+
if sanitizer_set.is_ok() {
1162+
*slot |= sanitizer_set.unwrap();
1163+
true
1164+
} else {
1165+
false
11761166
}
1177-
true
11781167
} else {
11791168
false
11801169
}
@@ -2043,6 +2032,8 @@ options! {
20432032
"output remarks for these optimization passes (space separated, or \"all\")"),
20442033
rpath: bool = (false, parse_bool, [UNTRACKED],
20452034
"set rpath values in libs/exes (default: no)"),
2035+
sanitize: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],
2036+
"use one or multiple sanitizers"),
20462037
save_temps: bool = (false, parse_bool, [UNTRACKED],
20472038
"save all temporary output files during compilation (default: no)"),
20482039
soft_float: bool = (false, parse_bool, [TRACKED],
@@ -2440,8 +2431,6 @@ options! {
24402431
remark_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
24412432
"directory into which to write optimization remarks (if not specified, they will be \
24422433
written to standard error output)"),
2443-
sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],
2444-
"use a sanitizer"),
24452434
sanitizer_cfi_canonical_jump_tables: Option<bool> = (Some(true), parse_opt_bool, [TRACKED],
24462435
"enable canonical jump tables (default: yes)"),
24472436
sanitizer_cfi_generalize_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],

compiler/rustc_session/src/session.rs

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,12 @@ impl Session {
371371
self.opts.unstable_opts.coverage_options.discard_all_spans_in_codegen
372372
}
373373

374+
pub fn is_sanitizer_address_enabled(&self) -> bool {
375+
self.opts.cg.sanitize.contains(SanitizerSet::ADDRESS)
376+
}
377+
374378
pub fn is_sanitizer_cfi_enabled(&self) -> bool {
375-
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
379+
self.opts.cg.sanitize.contains(SanitizerSet::CFI)
376380
}
377381

378382
pub fn is_sanitizer_cfi_canonical_jump_tables_disabled(&self) -> bool {
@@ -391,12 +395,36 @@ impl Session {
391395
self.opts.unstable_opts.sanitizer_cfi_normalize_integers == Some(true)
392396
}
393397

398+
pub fn is_sanitizer_hwaddress_enabled(&self) -> bool {
399+
self.opts.cg.sanitize.contains(SanitizerSet::HWADDRESS)
400+
}
401+
394402
pub fn is_sanitizer_kcfi_arity_enabled(&self) -> bool {
395403
self.opts.unstable_opts.sanitizer_kcfi_arity == Some(true)
396404
}
397405

398406
pub fn is_sanitizer_kcfi_enabled(&self) -> bool {
399-
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI)
407+
self.opts.cg.sanitize.contains(SanitizerSet::KCFI)
408+
}
409+
410+
pub fn is_sanitizer_kernel_address_enabled(&self) -> bool {
411+
self.opts.cg.sanitize.contains(SanitizerSet::KERNELADDRESS)
412+
}
413+
414+
pub fn is_sanitizer_memory_enabled(&self) -> bool {
415+
self.opts.cg.sanitize.contains(SanitizerSet::MEMORY)
416+
}
417+
418+
pub fn is_sanitizer_memory_recover_enabled(&self) -> bool {
419+
self.opts.unstable_opts.sanitizer_recover.contains(SanitizerSet::MEMORY)
420+
}
421+
422+
pub fn is_sanitizer_memory_track_origins_enabled(&self) -> bool {
423+
self.opts.unstable_opts.sanitizer_memory_track_origins != 0
424+
}
425+
426+
pub fn is_sanitizer_thread_enabled(&self) -> bool {
427+
self.opts.cg.sanitize.contains(SanitizerSet::THREAD)
400428
}
401429

402430
pub fn is_split_lto_unit_enabled(&self) -> bool {
@@ -578,7 +606,10 @@ impl Session {
578606
// AddressSanitizer and KernelAddressSanitizer uses lifetimes to detect use after scope bugs.
579607
// MemorySanitizer uses lifetimes to detect use of uninitialized stack variables.
580608
// HWAddressSanitizer will use lifetimes to detect use after scope bugs in the future.
581-
|| self.opts.unstable_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS)
609+
|| self.is_sanitizer_address_enabled()
610+
|| self.is_sanitizer_kernel_address_enabled()
611+
|| self.is_sanitizer_memory_enabled()
612+
|| self.is_sanitizer_hwaddress_enabled()
582613
}
583614

584615
pub fn diagnostic_width(&self) -> usize {
@@ -714,7 +745,7 @@ impl Session {
714745
let more_names = self.opts.output_types.contains_key(&OutputType::LlvmAssembly)
715746
|| self.opts.output_types.contains_key(&OutputType::Bitcode)
716747
// AddressSanitizer and MemorySanitizer use alloca name when reporting an issue.
717-
|| self.opts.unstable_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY);
748+
|| self.is_sanitizer_address_enabled() || self.is_sanitizer_memory_enabled();
718749
!more_names
719750
}
720751
}
@@ -1211,14 +1242,19 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
12111242
}
12121243
}
12131244

1214-
// Sanitizers can only be used on platforms that we know have working sanitizer codegen.
1215-
let supported_sanitizers = sess.target.options.supported_sanitizers;
1216-
let mut unsupported_sanitizers = sess.opts.unstable_opts.sanitizer - supported_sanitizers;
1245+
let supported_sanitizers = if sess.unstable_options() {
1246+
sess.target.options.supported_sanitizers | sess.target.options.stable_sanitizers
1247+
} else {
1248+
sess.target.options.stable_sanitizers
1249+
};
1250+
let mut unsupported_sanitizers = sess.opts.cg.sanitize - supported_sanitizers;
1251+
12171252
// Niche: if `fixed-x18`, or effectively switching on `reserved-x18` flag, is enabled
12181253
// we should allow Shadow Call Stack sanitizer.
12191254
if sess.opts.unstable_opts.fixed_x18 && sess.target.arch == "aarch64" {
12201255
unsupported_sanitizers -= SanitizerSet::SHADOWCALLSTACK;
12211256
}
1257+
12221258
match unsupported_sanitizers.into_iter().count() {
12231259
0 => {}
12241260
1 => {
@@ -1233,18 +1269,15 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
12331269
}
12341270

12351271
// Cannot mix and match mutually-exclusive sanitizers.
1236-
if let Some((first, second)) = sess.opts.unstable_opts.sanitizer.mutually_exclusive() {
1272+
if let Some((first, second)) = sess.opts.cg.sanitize.mutually_exclusive() {
12371273
sess.dcx().emit_err(errors::CannotMixAndMatchSanitizers {
12381274
first: first.to_string(),
12391275
second: second.to_string(),
12401276
});
12411277
}
12421278

12431279
// Cannot enable crt-static with sanitizers on Linux
1244-
if sess.crt_static(None)
1245-
&& !sess.opts.unstable_opts.sanitizer.is_empty()
1246-
&& !sess.target.is_like_msvc
1247-
{
1280+
if sess.crt_static(None) && !sess.opts.cg.sanitize.is_empty() && !sess.target.is_like_msvc {
12481281
sess.dcx().emit_err(errors::CannotEnableCrtStaticLinux);
12491282
}
12501283

compiler/rustc_target/src/spec/json.rs

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use serde_json::Value;
66

77
use super::{Target, TargetKind, TargetOptions, TargetWarnings};
88
use crate::json::{Json, ToJson};
9+
use crate::spec::SanitizerSet;
910

1011
impl Target {
1112
/// Loads a target descriptor from a JSON object.
@@ -357,32 +358,15 @@ impl Target {
357358
} );
358359
($key_name:ident, SanitizerSet) => ( {
359360
let name = (stringify!($key_name)).replace("_", "-");
360-
if let Some(o) = obj.remove(&name) {
361-
if let Some(a) = o.as_array() {
362-
for s in a {
363-
use super::SanitizerSet;
364-
base.$key_name |= match s.as_str() {
365-
Some("address") => SanitizerSet::ADDRESS,
366-
Some("cfi") => SanitizerSet::CFI,
367-
Some("dataflow") => SanitizerSet::DATAFLOW,
368-
Some("kcfi") => SanitizerSet::KCFI,
369-
Some("kernel-address") => SanitizerSet::KERNELADDRESS,
370-
Some("leak") => SanitizerSet::LEAK,
371-
Some("memory") => SanitizerSet::MEMORY,
372-
Some("memtag") => SanitizerSet::MEMTAG,
373-
Some("safestack") => SanitizerSet::SAFESTACK,
374-
Some("shadow-call-stack") => SanitizerSet::SHADOWCALLSTACK,
375-
Some("thread") => SanitizerSet::THREAD,
376-
Some("hwaddress") => SanitizerSet::HWADDRESS,
377-
Some(s) => return Err(format!("unknown sanitizer {}", s)),
378-
_ => return Err(format!("not a string: {:?}", s)),
379-
};
380-
}
381-
} else {
382-
incorrect_type.push(name)
383-
}
384-
}
385-
Ok::<(), String>(())
361+
obj.remove(&name).and_then(|o| match SanitizerSet::from_json(&o) {
362+
Ok(v) => {
363+
base.$key_name = v;
364+
Some(Ok(()))
365+
},
366+
Err(s) => Some(Err(
367+
format!("`{:?}` is not a valid value for `{}`: {}", o, name, s)
368+
)),
369+
}).unwrap_or(Ok(()))
386370
} );
387371
($key_name:ident, link_self_contained_components) => ( {
388372
// Skeleton of what needs to be parsed:
@@ -656,6 +640,7 @@ impl Target {
656640
key!(split_debuginfo, SplitDebuginfo)?;
657641
key!(supported_split_debuginfo, fallible_list)?;
658642
key!(supported_sanitizers, SanitizerSet)?;
643+
key!(stable_sanitizers, SanitizerSet)?;
659644
key!(generate_arange_section, bool);
660645
key!(supports_stack_protector, bool);
661646
key!(small_data_threshold_support, SmallDataThresholdSupport)?;
@@ -835,6 +820,7 @@ impl ToJson for Target {
835820
target_option_val!(split_debuginfo);
836821
target_option_val!(supported_split_debuginfo);
837822
target_option_val!(supported_sanitizers);
823+
target_option_val!(stable_sanitizers);
838824
target_option_val!(c_enum_min_bits);
839825
target_option_val!(generate_arange_section);
840826
target_option_val!(supports_stack_protector);

0 commit comments

Comments
 (0)