Auto merge of #124188 - scottmcm:implicit-switchint-unreachable, r= · rust-lang/rust@5ed2b42 (original) (raw)

`@@ -5,7 +5,8 @@ use rustc_ast as ast;

`

5

5

`use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};

`

6

6

`use rustc_hir::lang_items::LangItem;

`

7

7

`use rustc_middle::mir::{

`

8

``

`-

self, AssertKind, BasicBlock, InlineAsmMacro, SwitchTargets, UnwindTerminateReason,

`

``

8

`+

self, AssertKind, BasicBlock, InlineAsmMacro, SwitchAction, SwitchTargets,

`

``

9

`+

UnwindTerminateReason,

`

9

10

`};

`

10

11

`use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};

`

11

12

`use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};

`

`@@ -96,6 +97,17 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {

`

96

97

`}

`

97

98

`}

`

98

99

``

``

100

`+

fn llbb_with_cleanup_from_switch_action<Bx: BuilderMethods<'a, 'tcx>>(

`

``

101

`+

&self,

`

``

102

`+

fx: &mut FunctionCx<'a, 'tcx, Bx>,

`

``

103

`+

target: mir::SwitchAction,

`

``

104

`+

) -> Bx::BasicBlock {

`

``

105

`+

match target {

`

``

106

`+

mir::SwitchAction::Unreachable => fx.unreachable_block(),

`

``

107

`+

mir::SwitchAction::Goto(bb) => self.llbb_with_cleanup(fx, bb),

`

``

108

`+

}

`

``

109

`+

}

`

``

110

+

99

111

`fn llbb_characteristics<Bx: BuilderMethods<'a, 'tcx>>(

`

100

112

`&self,

`

101

113

`fx: &mut FunctionCx<'a, 'tcx, Bx>,

`

`@@ -368,7 +380,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

`

368

380

`// If our discriminant is a constant we can branch directly

`

369

381

`if let Some(const_discr) = bx.const_to_opt_u128(discr_value, false) {

`

370

382

`let target = targets.target_for_value(const_discr);

`

371

``

`-

bx.br(helper.llbb_with_cleanup(self, target));

`

``

383

`+

bx.br(helper.llbb_with_cleanup_from_switch_action(self, target));

`

372

384

`return;

`

373

385

`};

`

374

386

``

`@@ -379,9 +391,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

`

379

391

`let (test_value, target) = target_iter.next().unwrap();

`

380

392

`let otherwise = targets.otherwise();

`

381

393

`let lltarget = helper.llbb_with_cleanup(self, target);

`

382

``

`-

let llotherwise = helper.llbb_with_cleanup(self, otherwise);

`

``

394

`+

let llotherwise = helper.llbb_with_cleanup_from_switch_action(self, otherwise);

`

383

395

`let target_cold = self.cold_blocks[target];

`

384

``

`-

let otherwise_cold = self.cold_blocks[otherwise];

`

``

396

`+

let otherwise_cold = match otherwise {

`

``

397

`+

SwitchAction::Goto(otherwise) => self.cold_blocks[otherwise],

`

``

398

`+

SwitchAction::Unreachable => true,

`

``

399

`+

};

`

385

400

`` // If target_cold == otherwise_cold, the branches have the same weight

``

386

401

`` // so there is no expectation. If they differ, the target branch is expected

``

387

402

`` // when the otherwise branch is cold.

``

`@@ -406,7 +421,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

`

406

421

`}

`

407

422

`} else if self.cx.sess().opts.optimize == OptLevel::No

`

408

423

` && target_iter.len() == 2

`

409

``

`-

&& self.mir[targets.otherwise()].is_empty_unreachable()

`

``

424

`+

&& self.mir.basic_blocks.is_empty_unreachable(targets.otherwise())

`

410

425

`{

`

411

426

`` // In unoptimized builds, if there are two normal targets and the otherwise target is

``

412

427

`` // an unreachable BB, emit br instead of switch. This leaves behind the unreachable

``

`@@ -431,7 +446,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

`

431

446

`} else {

`

432

447

` bx.switch(

`

433

448

` discr_value,

`

434

``

`-

helper.llbb_with_cleanup(self, targets.otherwise()),

`

``

449

`+

helper.llbb_with_cleanup_from_switch_action(self, targets.otherwise()),

`

435

450

` target_iter.map(|(value, target)| (value, helper.llbb_with_cleanup(self, target))),

`

436

451

`);

`

437

452

`}

`

`@@ -1648,11 +1663,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

`

1648

1663

`}

`

1649

1664

``

1650

1665

`fn unreachable_block(&mut self) -> Bx::BasicBlock {

`

1651

``

`-

self.unreachable_block.unwrap_or_else(|| {

`

``

1666

`+

*self.unreachable_block.get_or_insert_with(|| {

`

1652

1667

`let llbb = Bx::append_block(self.cx, self.llfn, "unreachable");

`

1653

1668

`let mut bx = Bx::build(self.cx, llbb);

`

1654

1669

` bx.unreachable();

`

1655

``

`-

self.unreachable_block = Some(llbb);

`

1656

1670

` llbb

`

1657

1671

`})

`

1658

1672

`}

`