Skip to content

Commit 8483d7e

Browse files
committed
Auto merge of #154144 - Human9000-bit:const-prop-transmute-async-fix, r=<try>
Fix dataflow const prop behavior when propagating malsized transmutes
2 parents 14196db + fec9c70 commit 8483d7e

6 files changed

Lines changed: 43 additions & 10 deletions

File tree

compiler/rustc_hir_typeck/src/intrinsicck.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_index::Idx;
88
use rustc_middle::bug;
99
use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
1010
use rustc_middle::ty::{self, Ty, TyCtxt};
11+
use rustc_span::ErrorGuaranteed;
1112
use rustc_span::def_id::LocalDefId;
1213
use tracing::trace;
1314

@@ -75,7 +76,7 @@ fn check_transmute<'tcx>(
7576
from: Ty<'tcx>,
7677
to: Ty<'tcx>,
7778
hir_id: HirId,
78-
) {
79+
) -> Result<(), ErrorGuaranteed> {
7980
let span = || tcx.hir_span(hir_id);
8081
let normalize = |ty| {
8182
if let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) {
@@ -95,7 +96,7 @@ fn check_transmute<'tcx>(
9596

9697
// Transmutes that are only changing lifetimes are always ok.
9798
if from == to {
98-
return;
99+
return Ok(());
99100
}
100101

101102
let sk_from = SizeSkeleton::compute(from, tcx, typing_env);
@@ -107,7 +108,7 @@ fn check_transmute<'tcx>(
107108
&& let Ok(sk_to) = sk_to
108109
{
109110
if sk_from.same_size(sk_to) {
110-
return;
111+
return Ok(());
111112
}
112113

113114
// Special-case transmuting from `typeof(function)` and
@@ -122,7 +123,7 @@ fn check_transmute<'tcx>(
122123
.with_note(format!("target type: {to}"))
123124
.with_help("cast with `as` to a pointer instead")
124125
.emit();
125-
return;
126+
return Ok(());
126127
}
127128
}
128129

@@ -134,21 +135,25 @@ fn check_transmute<'tcx>(
134135
);
135136
if from == to {
136137
err.note(format!("`{from}` does not have a fixed size"));
137-
err.emit();
138+
Err(err.emit())
138139
} else {
139140
err.note(format!("source type: `{}` ({})", from, skeleton_string(from, sk_from)));
140141
err.note(format!("target type: `{}` ({})", to, skeleton_string(to, sk_to)));
141-
err.emit();
142+
Err(err.emit())
142143
}
143144
}
144145

145-
pub(crate) fn check_transmutes(tcx: TyCtxt<'_>, owner: LocalDefId) {
146+
pub(crate) fn check_transmutes(tcx: TyCtxt<'_>, owner: LocalDefId) -> Result<(), ErrorGuaranteed> {
146147
assert!(!tcx.is_typeck_child(owner.to_def_id()));
147148
let typeck_results = tcx.typeck(owner);
148-
let None = typeck_results.tainted_by_errors else { return };
149+
if let Some(e) = typeck_results.tainted_by_errors {
150+
return Err(e);
151+
};
149152

150153
let typing_env = ty::TypingEnv::post_analysis(tcx, owner);
154+
let mut result = Ok(());
151155
for &(from, to, hir_id) in &typeck_results.transmutes_to_check {
152-
check_transmute(tcx, typing_env, from, to, hir_id);
156+
result = check_transmute(tcx, typing_env, from, to, hir_id);
153157
}
158+
result
154159
}

compiler/rustc_middle/src/queries.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,7 @@ rustc_queries! {
11341134
}
11351135

11361136
/// Unsafety-check this `LocalDefId`.
1137-
query check_transmutes(key: LocalDefId) {
1137+
query check_transmutes(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
11381138
desc { "check transmute calls inside `{}`", tcx.def_path_str(key) }
11391139
}
11401140

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,11 @@ fn try_write_constant<'tcx>(
861861
if layout.backend_repr.is_scalar()
862862
&& let Some(value) = propagatable_scalar(place, state, map)
863863
{
864+
// Size is always present for scalars
865+
if value.size() != layout.backend_repr.scalar_size(ecx).unwrap() {
866+
throw_machine_stop_str!("mismatched sizes");
867+
}
868+
864869
return ecx.write_immediate(Immediate::Scalar(value), dest);
865870
}
866871

compiler/rustc_mir_transform/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,11 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
827827
return body;
828828
}
829829

830+
// If check_transmutes found faulty transmutes, then return early to avoid ICEs during optimizations
831+
if !tcx.is_typeck_child(did.to_def_id()) && tcx.check_transmutes(did).is_err() {
832+
return body;
833+
}
834+
830835
run_optimization_passes(tcx, &mut body);
831836

832837
body
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//@compile-flags: -Zmir-enable-passes=+DataflowConstProp --crate-type lib
2+
//@ edition:2021
3+
pub async fn a() -> u32 {
4+
unsafe { std::mem::transmute(1u64) }
5+
//~^error: cannot transmute between types of different sizes, or dependently-sized types
6+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
2+
--> $DIR/transmute-in-async-fn.rs:4:14
3+
|
4+
LL | unsafe { std::mem::transmute(1u64) }
5+
| ^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: source type: `u64` (64 bits)
8+
= note: target type: `u32` (32 bits)
9+
10+
error: aborting due to 1 previous error
11+
12+
For more information about this error, try `rustc --explain E0512`.

0 commit comments

Comments
 (0)