]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #43748 - RalfJung:mir-validate2, r=arielb1
authorbors <bors@rust-lang.org>
Fri, 11 Aug 2017 13:04:59 +0000 (13:04 +0000)
committerbors <bors@rust-lang.org>
Fri, 11 Aug 2017 13:04:59 +0000 (13:04 +0000)
AddValidation: handle Call terminators into blocks that have multiple incoming edges

The old code was just wrong: It would add validation on paths that don't even come from the call, and it would add multiple validations if multiple calls end return to the same block.

1  2 
src/librustc_driver/driver.rs

index c689b3d241c1f2a0c75cf46e92eb330b4d9c7b89,443bdf6a373ade70dbae53976e3644b0d437f807..cf36aef1c3083fd41aa2a1d5ceefb75361264f2c
@@@ -89,7 -89,7 +89,7 @@@ pub fn compile_input(sess: &Session
      // large chunks of memory alive and we want to free them as soon as
      // possible to keep the peak memory usage low
      let (outputs, trans) = {
 -        let krate = match phase_1_parse_input(sess, input) {
 +        let krate = match phase_1_parse_input(control, sess, input) {
              Ok(krate) => krate,
              Err(mut parse_error) => {
                  parse_error.emit();
@@@ -296,13 -296,9 +296,13 @@@ pub struct CompileController<'a> 
      pub after_llvm: PhaseController<'a>,
      pub compilation_done: PhaseController<'a>,
  
 +    // FIXME we probably want to group the below options together and offer a
 +    // better API, rather than this ad-hoc approach.
      pub make_glob_map: MakeGlobMap,
      // Whether the compiler should keep the ast beyond parsing.
      pub keep_ast: bool,
 +    // -Zcontinue-parse-after-error
 +    pub continue_parse_after_error: bool,
  }
  
  impl<'a> CompileController<'a> {
              compilation_done: PhaseController::basic(),
              make_glob_map: MakeGlobMap::No,
              keep_ast: false,
 +            continue_parse_after_error: false,
          }
      }
  }
@@@ -489,10 -484,10 +489,10 @@@ impl<'a, 'tcx> CompileState<'a, 'tcx> 
      }
  
      fn state_when_compilation_done(input: &'a Input,
 -                                    session: &'tcx Session,
 -                                    out_dir: &'a Option<PathBuf>,
 -                                    out_file: &'a Option<PathBuf>)
 -                                    -> Self {
 +                                   session: &'tcx Session,
 +                                   out_dir: &'a Option<PathBuf>,
 +                                   out_file: &'a Option<PathBuf>)
 +                                   -> Self {
          CompileState {
              out_file: out_file.as_ref().map(|s| &**s),
              ..CompileState::empty(input, session, out_dir)
      }
  }
  
 -pub fn phase_1_parse_input<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
 -    let continue_after_error = sess.opts.debugging_opts.continue_parse_after_error;
 -    sess.diagnostic().set_continue_after_error(continue_after_error);
 +pub fn phase_1_parse_input<'a>(control: &CompileController,
 +                               sess: &'a Session,
 +                               input: &Input)
 +                               -> PResult<'a, ast::Crate> {
 +    sess.diagnostic().set_continue_after_error(control.continue_parse_after_error);
  
      let krate = time(sess.time_passes(), "parsing", || {
          match *input {
@@@ -645,6 -638,7 +645,6 @@@ pub fn phase_2_configure_and_expand<F>(
          super::describe_lints(&sess.lint_store.borrow(), true);
          return Err(CompileIncomplete::Stopped);
      }
 -    sess.track_errors(|| sess.lint_store.borrow_mut().process_command_line(sess))?;
  
      // Currently, we ignore the name resolution data structures for the purposes of dependency
      // tracking. Instead we will run name resolution and include its output in the hash of each
          missing_fragment_specifiers.sort();
          for span in missing_fragment_specifiers {
              let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER;
 -            let msg = "missing fragment specifier".to_string();
 -            sess.add_lint(lint, ast::CRATE_NODE_ID, span, msg);
 +            let msg = "missing fragment specifier";
 +            sess.buffer_lint(lint, ast::CRATE_NODE_ID, span, msg);
          }
          if ecx.parse_sess.span_diagnostic.err_count() - ecx.resolve_err_count > err_count {
              ecx.parse_sess.span_diagnostic.abort_if_errors();
           "checking for inline asm in case the target doesn't support it",
           || no_asm::check_crate(sess, &krate));
  
 -    time(time_passes,
 -         "early lint checks",
 -         || lint::check_ast_crate(sess, &krate));
 -
      time(time_passes,
           "AST validation",
           || ast_validation::check_crate(sess, &krate));
          })
      })?;
  
 +    time(time_passes,
 +         "early lint checks",
 +         || lint::check_ast_crate(sess, &krate));
 +
      // Lower ast -> hir.
      let hir_forest = time(time_passes, "lowering ast -> hir", || {
          let hir_crate = lower_crate(sess, &krate, &mut resolver);
@@@ -914,7 -908,6 +914,7 @@@ pub fn phase_3_run_analysis_passes<'tcx
      rustc_const_eval::provide(&mut local_providers);
      middle::region::provide(&mut local_providers);
      cstore::provide_local(&mut local_providers);
 +    lint::provide(&mut local_providers);
  
      let mut extern_providers = ty::maps::Providers::default();
      cstore::provide(&mut extern_providers);
  
      // These next passes must be executed together
      passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
-     passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards);
+     passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::CriticalCallEdges);
      passes.push_pass(MIR_OPTIMIZED, mir::transform::elaborate_drops::ElaborateDrops);
      passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
+     // AddValidation needs to run after ElaborateDrops and before EraseRegions, and it needs
+     // an AllCallEdges pass right before it.
+     passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AllCallEdges);
+     passes.push_pass(MIR_OPTIMIZED, mir::transform::add_validation::AddValidation);
      passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyCfg::new("elaborate-drops"));
      // No lifetime analysis based on borrowing can be done from here on out.
  
-     // AddValidation needs to run after ElaborateDrops and before EraseRegions.
-     passes.push_pass(MIR_OPTIMIZED, mir::transform::add_validation::AddValidation);
      // From here on out, regions are gone.
      passes.push_pass(MIR_OPTIMIZED, mir::transform::erase_regions::EraseRegions);
  
      passes.push_pass(MIR_OPTIMIZED, mir::transform::deaggregator::Deaggregator);
      passes.push_pass(MIR_OPTIMIZED, mir::transform::copy_prop::CopyPropagation);
      passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyLocals);
-     passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards);
+     passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::CriticalCallEdges);
      passes.push_pass(MIR_OPTIMIZED, mir::transform::dump_mir::Marker("PreTrans"));
  
      TyCtxt::create_and_enter(sess,
@@@ -1201,10 -1195,10 +1202,10 @@@ pub fn collect_crate_types(session: &Se
                           }
                           Some(ref n) if *n == "bin" => Some(config::CrateTypeExecutable),
                           Some(_) => {
 -                             session.add_lint(lint::builtin::UNKNOWN_CRATE_TYPES,
 -                                              ast::CRATE_NODE_ID,
 -                                              a.span,
 -                                              "invalid `crate_type` value".to_string());
 +                             session.buffer_lint(lint::builtin::UNKNOWN_CRATE_TYPES,
 +                                                 ast::CRATE_NODE_ID,
 +                                                 a.span,
 +                                                 "invalid `crate_type` value");
                               None
                           }
                           _ => {