@@ -20,6 +20,8 @@ use rustc_mir_dataflow::{Analysis, ResultsCursor};
20
20
use rustc_target:: abi:: { Size , FIRST_VARIANT } ;
21
21
use rustc_target:: spec:: abi:: Abi ;
22
22
23
+ use crate :: util:: is_within_packed;
24
+
23
25
#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
24
26
enum EdgeKind {
25
27
Unwind ,
@@ -93,6 +95,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
93
95
cfg_checker. visit_body ( body) ;
94
96
cfg_checker. check_cleanup_control_flow ( ) ;
95
97
98
+ // Also run the TypeChecker.
96
99
for ( location, msg) in validate_types ( tcx, self . mir_phase , param_env, body) {
97
100
cfg_checker. fail ( location, msg) ;
98
101
}
@@ -427,22 +430,42 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
427
430
self . check_unwind_edge ( location, * unwind) ;
428
431
429
432
// The call destination place and Operand::Move place used as an argument might be
430
- // passed by a reference to the callee. Consequently they must be non-overlapping.
431
- // Currently this simply checks for duplicate places.
433
+ // passed by a reference to the callee. Consequently they must be non-overlapping
434
+ // and cannot be packed. Currently this simply checks for duplicate places.
432
435
self . place_cache . clear ( ) ;
433
436
self . place_cache . insert ( destination. as_ref ( ) ) ;
437
+ if is_within_packed ( self . tcx , & self . body . local_decls , * destination) . is_some ( ) {
438
+ // This is bad! The callee will expect the memory to be aligned.
439
+ self . fail (
440
+ location,
441
+ format ! (
442
+ "encountered packed place in `Call` terminator destination: {:?}" ,
443
+ terminator. kind,
444
+ ) ,
445
+ ) ;
446
+ }
434
447
let mut has_duplicates = false ;
435
448
for arg in args {
436
449
if let Operand :: Move ( place) = arg {
437
450
has_duplicates |= !self . place_cache . insert ( place. as_ref ( ) ) ;
451
+ if is_within_packed ( self . tcx , & self . body . local_decls , * place) . is_some ( ) {
452
+ // This is bad! The callee will expect the memory to be aligned.
453
+ self . fail (
454
+ location,
455
+ format ! (
456
+ "encountered `Move` of a packed place in `Call` terminator: {:?}" ,
457
+ terminator. kind,
458
+ ) ,
459
+ ) ;
460
+ }
438
461
}
439
462
}
440
463
441
464
if has_duplicates {
442
465
self . fail (
443
466
location,
444
467
format ! (
445
- "encountered overlapping memory in `Call` terminator: {:?}" ,
468
+ "encountered overlapping memory in `Move` arguments to ` Call` terminator: {:?}" ,
446
469
terminator. kind,
447
470
) ,
448
471
) ;
@@ -541,6 +564,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
541
564
}
542
565
}
543
566
567
+ /// A faster version of the validation pass that only checks those things which may break when apply
568
+ /// generic substitutions.
544
569
pub fn validate_types < ' tcx > (
545
570
tcx : TyCtxt < ' tcx > ,
546
571
mir_phase : MirPhase ,
0 commit comments