Skip to content

Commit 21cbbdc

Browse files
committed
Auto merge of #82045 - Dylan-DPC:rollup-244l0sb, r=Dylan-DPC
Rollup of 10 pull requests Successful merges: - #79775 (Fix injected errors when running doctests on a crate named after a keyword) - #81012 (Stabilize the partition_point feature) - #81479 (Allow casting mut array ref to mut ptr) - #81506 (HWAddressSanitizer support) - #81741 (Increment `self.index` before calling `Iterator::self.a.__iterator_ge…) - #81850 (use RWlock when accessing os::env) - #81911 (GAT/const_generics: Allow with_opt_const_param to return GAT param def_id) - #82022 (Push a `char` instead of a `str` with len one into a String) - #82023 (Remove unnecessary lint allow attrs on example) - #82030 (Use `Iterator::all` instead of open-coding it) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3f5aee2 + 1ef566f commit 21cbbdc

File tree

39 files changed

+494
-76
lines changed

39 files changed

+494
-76
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ pub fn sanitize(cx: &CodegenCx<'ll, '_>, no_sanitize: SanitizerSet, llfn: &'ll V
5353
if enabled.contains(SanitizerSet::THREAD) {
5454
llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn);
5555
}
56+
if enabled.contains(SanitizerSet::HWADDRESS) {
57+
llvm::Attribute::SanitizeHWAddress.apply_llfn(Function, llfn);
58+
}
5659
}
5760

5861
/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.

compiler/rustc_codegen_llvm/src/back/write.rs

+6
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,8 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
440440
sanitize_memory_recover: config.sanitizer_recover.contains(SanitizerSet::MEMORY),
441441
sanitize_memory_track_origins: config.sanitizer_memory_track_origins as c_int,
442442
sanitize_thread: config.sanitizer.contains(SanitizerSet::THREAD),
443+
sanitize_hwaddress: config.sanitizer.contains(SanitizerSet::HWADDRESS),
444+
sanitize_hwaddress_recover: config.sanitizer_recover.contains(SanitizerSet::HWADDRESS),
443445
})
444446
} else {
445447
None
@@ -652,6 +654,10 @@ unsafe fn add_sanitizer_passes(config: &ModuleConfig, passes: &mut Vec<&'static
652654
if config.sanitizer.contains(SanitizerSet::THREAD) {
653655
passes.push(llvm::LLVMRustCreateThreadSanitizerPass());
654656
}
657+
if config.sanitizer.contains(SanitizerSet::HWADDRESS) {
658+
let recover = config.sanitizer_recover.contains(SanitizerSet::HWADDRESS);
659+
passes.push(llvm::LLVMRustCreateHWAddressSanitizerPass(recover));
660+
}
655661
}
656662

657663
pub(crate) fn link(

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+4
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ pub enum Attribute {
131131
ReturnsTwice = 25,
132132
ReadNone = 26,
133133
InaccessibleMemOnly = 27,
134+
SanitizeHWAddress = 28,
134135
}
135136

136137
/// LLVMIntPredicate
@@ -439,6 +440,8 @@ pub struct SanitizerOptions {
439440
pub sanitize_memory_recover: bool,
440441
pub sanitize_memory_track_origins: c_int,
441442
pub sanitize_thread: bool,
443+
pub sanitize_hwaddress: bool,
444+
pub sanitize_hwaddress_recover: bool,
442445
}
443446

444447
/// LLVMRelocMode
@@ -2128,6 +2131,7 @@ extern "C" {
21282131
Recover: bool,
21292132
) -> &'static mut Pass;
21302133
pub fn LLVMRustCreateThreadSanitizerPass() -> &'static mut Pass;
2134+
pub fn LLVMRustCreateHWAddressSanitizerPass(Recover: bool) -> &'static mut Pass;
21312135
pub fn LLVMRustAddPass(PM: &PassManager<'_>, Pass: &'static mut Pass);
21322136
pub fn LLVMRustAddLastExtensionPasses(
21332137
PMB: &PassManagerBuilder,

compiler/rustc_codegen_ssa/src/back/link.rs

+3
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,9 @@ fn link_sanitizers(sess: &Session, crate_type: CrateType, linker: &mut dyn Linke
893893
if sanitizer.contains(SanitizerSet::THREAD) {
894894
link_sanitizer_runtime(sess, linker, "tsan");
895895
}
896+
if sanitizer.contains(SanitizerSet::HWADDRESS) {
897+
link_sanitizer_runtime(sess, linker, "hwasan");
898+
}
896899
}
897900

898901
fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {

compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ enum LLVMRustAttribute {
8585
ReturnsTwice = 25,
8686
ReadNone = 26,
8787
InaccessibleMemOnly = 27,
88+
SanitizeHWAddress = 28,
8889
};
8990

9091
typedef struct OpaqueRustString *RustStringRef;

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "llvm/Support/TimeProfiler.h"
3434
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
3535
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
36+
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
3637
#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
3738
#include "llvm/Transforms/Utils/NameAnonGlobals.h"
3839

@@ -133,6 +134,12 @@ extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() {
133134
return wrap(createThreadSanitizerLegacyPassPass());
134135
}
135136

137+
extern "C" LLVMPassRef LLVMRustCreateHWAddressSanitizerPass(bool Recover) {
138+
const bool CompileKernel = false;
139+
140+
return wrap(createHWAddressSanitizerLegacyPassPass(CompileKernel, Recover));
141+
}
142+
136143
extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) {
137144
assert(RustPass);
138145
Pass *Pass = unwrap(RustPass);
@@ -722,6 +729,8 @@ struct LLVMRustSanitizerOptions {
722729
bool SanitizeMemoryRecover;
723730
int SanitizeMemoryTrackOrigins;
724731
bool SanitizeThread;
732+
bool SanitizeHWAddress;
733+
bool SanitizeHWAddressRecover;
725734
};
726735

727736
extern "C" void
@@ -886,6 +895,23 @@ LLVMRustOptimizeWithNewPassManager(
886895
/*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
887896
}
888897
);
898+
#endif
899+
}
900+
if (SanitizerOptions->SanitizeHWAddress) {
901+
#if LLVM_VERSION_GE(11, 0)
902+
OptimizerLastEPCallbacks.push_back(
903+
[SanitizerOptions](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
904+
MPM.addPass(HWAddressSanitizerPass(
905+
/*CompileKernel=*/false, SanitizerOptions->SanitizeHWAddressRecover));
906+
}
907+
);
908+
#else
909+
PipelineStartEPCallbacks.push_back(
910+
[SanitizerOptions](ModulePassManager &MPM) {
911+
MPM.addPass(HWAddressSanitizerPass(
912+
/*CompileKernel=*/false, SanitizerOptions->SanitizeHWAddressRecover));
913+
}
914+
);
889915
#endif
890916
}
891917
}

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
205205
return Attribute::ReadNone;
206206
case InaccessibleMemOnly:
207207
return Attribute::InaccessibleMemOnly;
208+
case SanitizeHWAddress:
209+
return Attribute::SanitizeHWAddress;
208210
}
209211
report_fatal_error("bad AttributeKind");
210212
}

compiler/rustc_mir/src/borrow_check/type_check/mod.rs

+24-15
Original file line numberDiff line numberDiff line change
@@ -2191,19 +2191,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21912191
CastKind::Pointer(PointerCast::ArrayToPointer) => {
21922192
let ty_from = op.ty(body, tcx);
21932193

2194-
let opt_ty_elem = match ty_from.kind() {
2195-
ty::RawPtr(ty::TypeAndMut {
2196-
mutbl: hir::Mutability::Not,
2197-
ty: array_ty,
2198-
}) => match array_ty.kind() {
2199-
ty::Array(ty_elem, _) => Some(ty_elem),
2200-
_ => None,
2201-
},
2194+
let opt_ty_elem_mut = match ty_from.kind() {
2195+
ty::RawPtr(ty::TypeAndMut { mutbl: array_mut, ty: array_ty }) => {
2196+
match array_ty.kind() {
2197+
ty::Array(ty_elem, _) => Some((ty_elem, *array_mut)),
2198+
_ => None,
2199+
}
2200+
}
22022201
_ => None,
22032202
};
22042203

2205-
let ty_elem = match opt_ty_elem {
2206-
Some(ty_elem) => ty_elem,
2204+
let (ty_elem, ty_mut) = match opt_ty_elem_mut {
2205+
Some(ty_elem_mut) => ty_elem_mut,
22072206
None => {
22082207
span_mirbug!(
22092208
self,
@@ -2215,11 +2214,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22152214
}
22162215
};
22172216

2218-
let ty_to = match ty.kind() {
2219-
ty::RawPtr(ty::TypeAndMut {
2220-
mutbl: hir::Mutability::Not,
2221-
ty: ty_to,
2222-
}) => ty_to,
2217+
let (ty_to, ty_to_mut) = match ty.kind() {
2218+
ty::RawPtr(ty::TypeAndMut { mutbl: ty_to_mut, ty: ty_to }) => {
2219+
(ty_to, *ty_to_mut)
2220+
}
22232221
_ => {
22242222
span_mirbug!(
22252223
self,
@@ -2231,6 +2229,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22312229
}
22322230
};
22332231

2232+
if ty_to_mut == Mutability::Mut && ty_mut == Mutability::Not {
2233+
span_mirbug!(
2234+
self,
2235+
rvalue,
2236+
"ArrayToPointer cast from const {:?} to mut {:?}",
2237+
ty,
2238+
ty_to
2239+
);
2240+
return;
2241+
}
2242+
22342243
if let Err(terr) = self.sub_types(
22352244
ty_elem,
22362245
ty_to,

compiler/rustc_session/src/config.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ bitflags! {
4343
const LEAK = 1 << 1;
4444
const MEMORY = 1 << 2;
4545
const THREAD = 1 << 3;
46+
const HWADDRESS = 1 << 4;
4647
}
4748
}
4849

@@ -56,6 +57,7 @@ impl fmt::Display for SanitizerSet {
5657
SanitizerSet::LEAK => "leak",
5758
SanitizerSet::MEMORY => "memory",
5859
SanitizerSet::THREAD => "thread",
60+
SanitizerSet::HWADDRESS => "hwaddress",
5961
_ => panic!("unrecognized sanitizer {:?}", s),
6062
};
6163
if !first {
@@ -73,12 +75,18 @@ impl IntoIterator for SanitizerSet {
7375
type IntoIter = std::vec::IntoIter<SanitizerSet>;
7476

7577
fn into_iter(self) -> Self::IntoIter {
76-
[SanitizerSet::ADDRESS, SanitizerSet::LEAK, SanitizerSet::MEMORY, SanitizerSet::THREAD]
77-
.iter()
78-
.copied()
79-
.filter(|&s| self.contains(s))
80-
.collect::<Vec<_>>()
81-
.into_iter()
78+
[
79+
SanitizerSet::ADDRESS,
80+
SanitizerSet::LEAK,
81+
SanitizerSet::MEMORY,
82+
SanitizerSet::THREAD,
83+
SanitizerSet::HWADDRESS,
84+
]
85+
.iter()
86+
.copied()
87+
.filter(|&s| self.contains(s))
88+
.collect::<Vec<_>>()
89+
.into_iter()
8290
}
8391
}
8492

compiler/rustc_session/src/options.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ macro_rules! options {
253253
pub const parse_passes: &str = "a space-separated list of passes, or `all`";
254254
pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
255255
pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
256-
pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `leak`, `memory` or `thread`";
256+
pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `hwaddress`, `leak`, `memory` or `thread`";
257257
pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
258258
pub const parse_cfguard: &str =
259259
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
@@ -476,6 +476,7 @@ macro_rules! options {
476476
"leak" => SanitizerSet::LEAK,
477477
"memory" => SanitizerSet::MEMORY,
478478
"thread" => SanitizerSet::THREAD,
479+
"hwaddress" => SanitizerSet::HWADDRESS,
479480
_ => return false,
480481
}
481482
}

compiler/rustc_session/src/session.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,8 @@ impl Session {
11261126
self.opts.optimize != config::OptLevel::No
11271127
// AddressSanitizer uses lifetimes to detect use after scope bugs.
11281128
// MemorySanitizer uses lifetimes to detect use of uninitialized stack variables.
1129-
|| self.opts.debugging_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY)
1129+
// HWAddressSanitizer will use lifetimes to detect use after scope bugs in the future.
1130+
|| self.opts.debugging_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS)
11301131
}
11311132

11321133
pub fn link_dead_code(&self) -> bool {
@@ -1562,6 +1563,8 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
15621563
"x86_64-unknown-freebsd",
15631564
"x86_64-unknown-linux-gnu",
15641565
];
1566+
const HWASAN_SUPPORTED_TARGETS: &[&str] =
1567+
&["aarch64-linux-android", "aarch64-unknown-linux-gnu"];
15651568

15661569
// Sanitizers can only be used on some tested platforms.
15671570
for s in sess.opts.debugging_opts.sanitizer {
@@ -1570,6 +1573,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
15701573
SanitizerSet::LEAK => LSAN_SUPPORTED_TARGETS,
15711574
SanitizerSet::MEMORY => MSAN_SUPPORTED_TARGETS,
15721575
SanitizerSet::THREAD => TSAN_SUPPORTED_TARGETS,
1576+
SanitizerSet::HWADDRESS => HWASAN_SUPPORTED_TARGETS,
15731577
_ => panic!("unrecognized sanitizer {}", s),
15741578
};
15751579
if !supported_targets.contains(&&*sess.opts.target_triple.triple()) {

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ symbols! {
593593
html_no_source,
594594
html_playground_url,
595595
html_root_url,
596+
hwaddress,
596597
i,
597598
i128,
598599
i128_type,

compiler/rustc_typeck/src/check/cast.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -765,9 +765,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
765765
m_expr: ty::TypeAndMut<'tcx>,
766766
m_cast: ty::TypeAndMut<'tcx>,
767767
) -> Result<CastKind, CastError> {
768-
// array-ptr-cast.
769-
770-
if m_expr.mutbl == hir::Mutability::Not && m_cast.mutbl == hir::Mutability::Not {
768+
// array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const
769+
if m_expr.mutbl == hir::Mutability::Mut || m_cast.mutbl == hir::Mutability::Not {
771770
if let ty::Array(ety, _) = m_expr.ty.kind() {
772771
// Due to the limitations of LLVM global constants,
773772
// region pointers end up pointing at copies of

compiler/rustc_typeck/src/check/upvar.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,7 @@ fn construct_place_string(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String {
12111211
ProjectionKind::Subslice => String::from("Subslice"),
12121212
};
12131213
if i != 0 {
1214-
projections_str.push_str(",");
1214+
projections_str.push(',');
12151215
}
12161216
projections_str.push_str(proj.as_str());
12171217
}
@@ -1382,14 +1382,8 @@ fn determine_place_ancestry_relation(
13821382
// Assume of length of projections_b = m
13831383
let projections_b = &place_b.projections;
13841384

1385-
let mut same_initial_projections = true;
1386-
1387-
for (proj_a, proj_b) in projections_a.iter().zip(projections_b.iter()) {
1388-
if proj_a != proj_b {
1389-
same_initial_projections = false;
1390-
break;
1391-
}
1392-
}
1385+
let same_initial_projections =
1386+
projections_a.iter().zip(projections_b.iter()).all(|(proj_a, proj_b)| proj_a == proj_b);
13931387

13941388
if same_initial_projections {
13951389
// First min(n, m) projections are the same

compiler/rustc_typeck/src/collect.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -2709,10 +2709,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
27092709
codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY;
27102710
} else if item.has_name(sym::thread) {
27112711
codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD;
2712+
} else if item.has_name(sym::hwaddress) {
2713+
codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS;
27122714
} else {
27132715
tcx.sess
27142716
.struct_span_err(item.span(), "invalid argument for `no_sanitize`")
2715-
.note("expected one of: `address`, `memory` or `thread`")
2717+
.note("expected one of: `address`, `hwaddress`, `memory` or `thread`")
27162718
.emit();
27172719
}
27182720
}

0 commit comments

Comments
 (0)