Skip to content

Commit f993ddc

Browse files
committed
give extra context to ABI mismatch errors
1 parent 897a658 commit f993ddc

File tree

10 files changed

+66
-38
lines changed

10 files changed

+66
-38
lines changed

compiler/rustc_const_eval/src/errors.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,9 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
482482
use UndefinedBehaviorInfo::*;
483483
match self {
484484
Ub(msg) => msg.clone().into(),
485+
Custom(x) => (x.msg)(),
486+
ValidationError(e) => e.diagnostic_message(),
487+
485488
Unreachable => const_eval_unreachable,
486489
BoundsCheckFailed { .. } => const_eval_bounds_check_failed,
487490
DivisionByZero => const_eval_division_by_zero,
@@ -513,8 +516,8 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
513516
ScalarSizeMismatch(_) => const_eval_scalar_size_mismatch,
514517
UninhabitedEnumVariantWritten(_) => const_eval_uninhabited_enum_variant_written,
515518
UninhabitedEnumVariantRead(_) => const_eval_uninhabited_enum_variant_read,
516-
ValidationError(e) => e.diagnostic_message(),
517-
Custom(x) => (x.msg)(),
519+
AbiMismatchArgument { .. } => const_eval_incompatible_types,
520+
AbiMismatchReturn { .. } => const_eval_incompatible_return_types,
518521
}
519522
}
520523

@@ -525,8 +528,15 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
525528
) {
526529
use UndefinedBehaviorInfo::*;
527530
match self {
528-
Ub(_)
529-
| Unreachable
531+
Ub(_) => {}
532+
Custom(custom) => {
533+
(custom.add_args)(&mut |name, value| {
534+
builder.set_arg(name, value);
535+
});
536+
}
537+
ValidationError(e) => e.add_args(handler, builder),
538+
539+
Unreachable
530540
| DivisionByZero
531541
| RemainderByZero
532542
| DivisionOverflow
@@ -593,11 +603,10 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
593603
builder.set_arg("target_size", info.target_size);
594604
builder.set_arg("data_size", info.data_size);
595605
}
596-
ValidationError(e) => e.add_args(handler, builder),
597-
Custom(custom) => {
598-
(custom.add_args)(&mut |name, value| {
599-
builder.set_arg(name, value);
600-
});
606+
AbiMismatchArgument { caller_ty, callee_ty }
607+
| AbiMismatchReturn { caller_ty, callee_ty } => {
608+
builder.set_arg("caller_ty", caller_ty.to_string());
609+
builder.set_arg("callee_ty", callee_ty.to_string());
601610
}
602611
}
603612
}

compiler/rustc_const_eval/src/interpret/terminator.rs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -439,13 +439,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
439439

440440
// Check compatibility
441441
if !self.check_argument_compat(caller_abi, callee_abi)? {
442-
let callee_ty = format!("{}", callee_ty);
443-
let caller_ty = format!("{}", caller_arg.layout().ty);
444-
throw_ub_custom!(
445-
fluent::const_eval_incompatible_types,
446-
callee_ty = callee_ty,
447-
caller_ty = caller_ty,
448-
)
442+
throw_ub!(AbiMismatchArgument {
443+
caller_ty: caller_abi.layout.ty,
444+
callee_ty: callee_abi.layout.ty
445+
});
449446
}
450447
// We work with a copy of the argument for now; if this is in-place argument passing, we
451448
// will later protect the source it comes from. This means the callee cannot observe if we
@@ -712,13 +709,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
712709
}
713710
// Don't forget to check the return type!
714711
if !self.check_argument_compat(&caller_fn_abi.ret, &callee_fn_abi.ret)? {
715-
let callee_ty = format!("{}", callee_fn_abi.ret.layout.ty);
716-
let caller_ty = format!("{}", caller_fn_abi.ret.layout.ty);
717-
throw_ub_custom!(
718-
fluent::const_eval_incompatible_return_types,
719-
callee_ty = callee_ty,
720-
caller_ty = caller_ty,
721-
)
712+
throw_ub!(AbiMismatchReturn {
713+
caller_ty: caller_fn_abi.ret.layout.ty,
714+
callee_ty: callee_fn_abi.ret.layout.ty
715+
});
722716
}
723717
// Ensure the return place is aligned and dereferenceable, and protect it for
724718
// in-place return value passing.

compiler/rustc_middle/src/mir/interpret/error.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,16 @@ impl_into_diagnostic_arg_through_debug! {
255255

256256
/// Error information for when the program caused Undefined Behavior.
257257
#[derive(Debug)]
258-
pub enum UndefinedBehaviorInfo<'a> {
258+
pub enum UndefinedBehaviorInfo<'tcx> {
259259
/// Free-form case. Only for errors that are never caught! Used by miri
260260
Ub(String),
261+
// FIXME(fee1-dead) these should all be actual variants of the enum instead of dynamically
262+
// dispatched
263+
/// A custom (free-form) fluent-translated error, created by `err_ub_custom!`.
264+
Custom(crate::error::CustomSubdiagnostic<'tcx>),
265+
/// Validation error.
266+
ValidationError(ValidationErrorInfo<'tcx>),
267+
261268
/// Unreachable code was executed.
262269
Unreachable,
263270
/// A slice/array index projection went out-of-bounds.
@@ -319,12 +326,10 @@ pub enum UndefinedBehaviorInfo<'a> {
319326
UninhabitedEnumVariantWritten(VariantIdx),
320327
/// An uninhabited enum variant is projected.
321328
UninhabitedEnumVariantRead(VariantIdx),
322-
/// Validation error.
323-
ValidationError(ValidationErrorInfo<'a>),
324-
// FIXME(fee1-dead) these should all be actual variants of the enum instead of dynamically
325-
// dispatched
326-
/// A custom (free-form) error, created by `err_ub_custom!`.
327-
Custom(crate::error::CustomSubdiagnostic<'a>),
329+
/// ABI-incompatible argument types.
330+
AbiMismatchArgument { caller_ty: Ty<'tcx>, callee_ty: Ty<'tcx> },
331+
/// ABI-incompatible return types.
332+
AbiMismatchReturn { caller_ty: Ty<'tcx>, callee_ty: Ty<'tcx> },
328333
}
329334

330335
#[derive(Debug, Clone, Copy)]

src/tools/miri/src/diagnostics.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ pub fn report_error<'tcx, 'mir>(
199199
e: InterpErrorInfo<'tcx>,
200200
) -> Option<(i64, bool)> {
201201
use InterpError::*;
202+
use UndefinedBehaviorInfo::*;
202203

203204
let mut msg = vec![];
204205

@@ -271,7 +272,7 @@ pub fn report_error<'tcx, 'mir>(
271272
(title, helps)
272273
} else {
273274
let title = match e.kind() {
274-
UndefinedBehavior(UndefinedBehaviorInfo::ValidationError(validation_err))
275+
UndefinedBehavior(ValidationError(validation_err))
275276
if matches!(
276277
validation_err.kind,
277278
ValidationErrorKind::PointerAsInt { .. } | ValidationErrorKind::PartialPointer
@@ -299,7 +300,7 @@ pub fn report_error<'tcx, 'mir>(
299300
let helps = match e.kind() {
300301
Unsupported(_) =>
301302
vec![(None, format!("this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support"))],
302-
UndefinedBehavior(UndefinedBehaviorInfo::AlignmentCheckFailed { .. })
303+
UndefinedBehavior(AlignmentCheckFailed { .. })
303304
if ecx.machine.check_alignment == AlignmentCheck::Symbolic
304305
=>
305306
vec![
@@ -311,13 +312,20 @@ pub fn report_error<'tcx, 'mir>(
311312
(None, format!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior")),
312313
(None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")),
313314
];
314-
if let UndefinedBehaviorInfo::PointerUseAfterFree(alloc_id, _) | UndefinedBehaviorInfo::PointerOutOfBounds { alloc_id, .. } = info {
315-
if let Some(span) = ecx.machine.allocated_span(*alloc_id) {
316-
helps.push((Some(span), format!("{:?} was allocated here:", alloc_id)));
315+
match info {
316+
PointerUseAfterFree(alloc_id, _) | PointerOutOfBounds { alloc_id, .. } => {
317+
if let Some(span) = ecx.machine.allocated_span(*alloc_id) {
318+
helps.push((Some(span), format!("{:?} was allocated here:", alloc_id)));
319+
}
320+
if let Some(span) = ecx.machine.deallocated_span(*alloc_id) {
321+
helps.push((Some(span), format!("{:?} was deallocated here:", alloc_id)));
322+
}
317323
}
318-
if let Some(span) = ecx.machine.deallocated_span(*alloc_id) {
319-
helps.push((Some(span), format!("{:?} was deallocated here:", alloc_id)));
324+
AbiMismatchArgument { .. } | AbiMismatchReturn { .. } => {
325+
helps.push((None, format!("this means these two types are not *guaranteed* to be ABI-compatible across all targets")));
326+
helps.push((None, format!("if you think this code should be accepted anyway, please report an issue")));
320327
}
328+
_ => {},
321329
}
322330
helps
323331
}
@@ -339,7 +347,7 @@ pub fn report_error<'tcx, 'mir>(
339347
// We want to dump the allocation if this is `InvalidUninitBytes`. Since `format_error` consumes `e`, we compute the outut early.
340348
let mut extra = String::new();
341349
match e.kind() {
342-
UndefinedBehavior(UndefinedBehaviorInfo::InvalidUninitBytes(Some((alloc_id, access)))) => {
350+
UndefinedBehavior(InvalidUninitBytes(Some((alloc_id, access)))) => {
343351
writeln!(
344352
extra,
345353
"Uninitialized memory occurred at {alloc_id:?}{range:?}, in this allocation:",

src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ LL | g(Default::default())
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
10+
= help: if you think this code should be accepted anyway, please report an issue
911
= note: BACKTRACE:
1012
= note: inside `main` at $DIR/abi_mismatch_array_vs_struct.rs:LL:CC
1113

src/tools/miri/tests/fail/function_pointers/abi_mismatch_int_vs_float.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ LL | g(42)
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
10+
= help: if you think this code should be accepted anyway, please report an issue
911
= note: BACKTRACE:
1012
= note: inside `main` at $DIR/abi_mismatch_int_vs_float.rs:LL:CC
1113

src/tools/miri/tests/fail/function_pointers/abi_mismatch_raw_pointer.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ LL | g(&42 as *const i32)
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
10+
= help: if you think this code should be accepted anyway, please report an issue
911
= note: BACKTRACE:
1012
= note: inside `main` at $DIR/abi_mismatch_raw_pointer.rs:LL:CC
1113

src/tools/miri/tests/fail/function_pointers/abi_mismatch_return_type.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ LL | g()
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
10+
= help: if you think this code should be accepted anyway, please report an issue
911
= note: BACKTRACE:
1012
= note: inside `main` at $DIR/abi_mismatch_return_type.rs:LL:CC
1113

src/tools/miri/tests/fail/function_pointers/abi_mismatch_simple.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ LL | g(42)
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
10+
= help: if you think this code should be accepted anyway, please report an issue
911
= note: BACKTRACE:
1012
= note: inside `main` at $DIR/abi_mismatch_simple.rs:LL:CC
1113

src/tools/miri/tests/fail/function_pointers/abi_mismatch_vector.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ LL | g(Default::default())
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
10+
= help: if you think this code should be accepted anyway, please report an issue
911
= note: BACKTRACE:
1012
= note: inside `main` at $DIR/abi_mismatch_vector.rs:LL:CC
1113

0 commit comments

Comments
 (0)