Skip to content

Commit b4d3873

Browse files
authored
Rollup merge of rust-lang#76263 - tmiasko:inline-codegen-fn-attrs, r=ecstatic-morse
inliner: Check for codegen fn attributes compatibility * Check for target features compatibility * Check for no_sanitize attribute compatibility Fixes rust-lang#76259.
2 parents 45bdee8 + c23151b commit b4d3873

6 files changed

+150
-5
lines changed

compiler/rustc_mir/src/transform/inline.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_attr as attr;
44
use rustc_hir::def_id::DefId;
55
use rustc_index::bit_set::BitSet;
66
use rustc_index::vec::{Idx, IndexVec};
7-
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
7+
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
88
use rustc_middle::mir::visit::*;
99
use rustc_middle::mir::*;
1010
use rustc_middle::ty::subst::{Subst, SubstsRef};
@@ -45,7 +45,8 @@ impl<'tcx> MirPass<'tcx> for Inline {
4545
// based function.
4646
debug!("function inlining is disabled when compiling with `instrument_coverage`");
4747
} else {
48-
Inliner { tcx, source }.run_pass(body);
48+
Inliner { tcx, source, codegen_fn_attrs: tcx.codegen_fn_attrs(source.def_id()) }
49+
.run_pass(body);
4950
}
5051
}
5152
}
@@ -54,6 +55,7 @@ impl<'tcx> MirPass<'tcx> for Inline {
5455
struct Inliner<'tcx> {
5556
tcx: TyCtxt<'tcx>,
5657
source: MirSource<'tcx>,
58+
codegen_fn_attrs: &'tcx CodegenFnAttrs,
5759
}
5860

5961
impl Inliner<'tcx> {
@@ -242,9 +244,19 @@ impl Inliner<'tcx> {
242244
return false;
243245
}
244246

245-
// Avoid inlining functions marked as no_sanitize if sanitizer is enabled,
246-
// since instrumentation might be enabled and performed on the caller.
247-
if self.tcx.sess.opts.debugging_opts.sanitizer.intersects(codegen_fn_attrs.no_sanitize) {
247+
let self_features = &self.codegen_fn_attrs.target_features;
248+
let callee_features = &codegen_fn_attrs.target_features;
249+
if callee_features.iter().any(|feature| !self_features.contains(feature)) {
250+
debug!("`callee has extra target features - not inlining");
251+
return false;
252+
}
253+
254+
let self_no_sanitize =
255+
self.codegen_fn_attrs.no_sanitize & self.tcx.sess.opts.debugging_opts.sanitizer;
256+
let callee_no_sanitize =
257+
codegen_fn_attrs.no_sanitize & self.tcx.sess.opts.debugging_opts.sanitizer;
258+
if self_no_sanitize != callee_no_sanitize {
259+
debug!("`callee has incompatible no_sanitize attribute - not inlining");
248260
return false;
249261
}
250262

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Checks that only functions with compatible attributes are inlined.
2+
//
3+
// only-x86_64
4+
// needs-sanitizer-address
5+
// compile-flags: -Zsanitizer=address
6+
7+
#![crate_type = "lib"]
8+
#![feature(no_sanitize)]
9+
#![feature(target_feature_11)]
10+
11+
// EMIT_MIR inline_compatibility.inlined_target_feature.Inline.diff
12+
#[target_feature(enable = "sse2")]
13+
pub unsafe fn inlined_target_feature() {
14+
target_feature();
15+
}
16+
17+
// EMIT_MIR inline_compatibility.not_inlined_target_feature.Inline.diff
18+
pub unsafe fn not_inlined_target_feature() {
19+
target_feature();
20+
}
21+
22+
// EMIT_MIR inline_compatibility.inlined_no_sanitize.Inline.diff
23+
#[no_sanitize(address)]
24+
pub unsafe fn inlined_no_sanitize() {
25+
no_sanitize();
26+
}
27+
28+
// EMIT_MIR inline_compatibility.not_inlined_no_sanitize.Inline.diff
29+
pub unsafe fn not_inlined_no_sanitize() {
30+
no_sanitize();
31+
}
32+
33+
#[inline]
34+
#[target_feature(enable = "sse2")]
35+
pub unsafe fn target_feature() {}
36+
37+
#[inline]
38+
#[no_sanitize(address, memory)]
39+
pub unsafe fn no_sanitize() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
- // MIR for `inlined_no_sanitize` before Inline
2+
+ // MIR for `inlined_no_sanitize` after Inline
3+
4+
fn inlined_no_sanitize() -> () {
5+
let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:24:37: 24:37
6+
let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:25:5: 25:18
7+
+ scope 1 {
8+
+ }
9+
10+
bb0: {
11+
StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:25:5: 25:18
12+
- _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:25:5: 25:18
13+
- // mir::Constant
14+
- // + span: $DIR/inline-compatibility.rs:25:5: 25:16
15+
- // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value(Scalar(<ZST>)) }
16+
- }
17+
-
18+
- bb1: {
19+
+ _1 = const (); // scope 1 at $DIR/inline-compatibility.rs:39:29: 39:31
20+
StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:25:18: 25:19
21+
_0 = const (); // scope 0 at $DIR/inline-compatibility.rs:24:37: 26:2
22+
return; // scope 0 at $DIR/inline-compatibility.rs:26:2: 26:2
23+
}
24+
}
25+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
- // MIR for `inlined_target_feature` before Inline
2+
+ // MIR for `inlined_target_feature` after Inline
3+
4+
fn inlined_target_feature() -> () {
5+
let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:13:40: 13:40
6+
let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:14:5: 14:21
7+
+ scope 1 {
8+
+ }
9+
10+
bb0: {
11+
StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:14:5: 14:21
12+
- _1 = target_feature() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:14:5: 14:21
13+
- // mir::Constant
14+
- // + span: $DIR/inline-compatibility.rs:14:5: 14:19
15+
- // + literal: Const { ty: unsafe fn() {target_feature}, val: Value(Scalar(<ZST>)) }
16+
- }
17+
-
18+
- bb1: {
19+
+ _1 = const (); // scope 1 at $DIR/inline-compatibility.rs:35:32: 35:34
20+
StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:14:21: 14:22
21+
_0 = const (); // scope 0 at $DIR/inline-compatibility.rs:13:40: 15:2
22+
return; // scope 0 at $DIR/inline-compatibility.rs:15:2: 15:2
23+
}
24+
}
25+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
- // MIR for `not_inlined_no_sanitize` before Inline
2+
+ // MIR for `not_inlined_no_sanitize` after Inline
3+
4+
fn not_inlined_no_sanitize() -> () {
5+
let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:29:41: 29:41
6+
let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:30:5: 30:18
7+
8+
bb0: {
9+
StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:30:5: 30:18
10+
_1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:30:5: 30:18
11+
// mir::Constant
12+
// + span: $DIR/inline-compatibility.rs:30:5: 30:16
13+
// + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value(Scalar(<ZST>)) }
14+
}
15+
16+
bb1: {
17+
StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:30:18: 30:19
18+
_0 = const (); // scope 0 at $DIR/inline-compatibility.rs:29:41: 31:2
19+
return; // scope 0 at $DIR/inline-compatibility.rs:31:2: 31:2
20+
}
21+
}
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
- // MIR for `not_inlined_target_feature` before Inline
2+
+ // MIR for `not_inlined_target_feature` after Inline
3+
4+
fn not_inlined_target_feature() -> () {
5+
let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:18:44: 18:44
6+
let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:19:5: 19:21
7+
8+
bb0: {
9+
StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:19:5: 19:21
10+
_1 = target_feature() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:19:5: 19:21
11+
// mir::Constant
12+
// + span: $DIR/inline-compatibility.rs:19:5: 19:19
13+
// + literal: Const { ty: unsafe fn() {target_feature}, val: Value(Scalar(<ZST>)) }
14+
}
15+
16+
bb1: {
17+
StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:19:21: 19:22
18+
_0 = const (); // scope 0 at $DIR/inline-compatibility.rs:18:44: 20:2
19+
return; // scope 0 at $DIR/inline-compatibility.rs:20:2: 20:2
20+
}
21+
}
22+

0 commit comments

Comments
 (0)