Skip to content

Commit 9143c3c

Browse files
author
Jonathan Turner
authored
Rollup merge of rust-lang#36794 - japaric:target-panic, r=alexcrichton
add a panic-strategy field to the target specification Now a target can define its panic strategy in its specification. If a user doesn't specify a panic strategy via the command line, i.e. '-C panic', then the compiler will use the panic strategy defined by the target specification. Custom targets can pick their panic strategy via the "panic-strategy" field of their target specification JSON file. If omitted in the specification, the strategy defaults to "unwind". closes rust-lang#36647 --- I checked that compiling an executable for a custom target with "panic-strategy" set to "abort" doesn't need the "eh_personality" lang item and also that standard crates compiled for that custom target didn't contained undefined symbols to _Unwind_Resume. But this needs an actual unit test, any suggestion on how to test this? Most of the noise in the diff is due to moving `PanicStrategy` from the `rustc` to the `rustc_back` crate. r? @alexcrichton cc @phil-opp
2 parents f1ea5cc + 8a46e78 commit 9143c3c

File tree

12 files changed

+83
-37
lines changed

12 files changed

+83
-37
lines changed

src/librustc/middle/cstore.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ use ty::{self, Ty, TyCtxt};
3232
use mir::repr::Mir;
3333
use mir::mir_map::MirMap;
3434
use session::Session;
35-
use session::config::PanicStrategy;
3635
use session::search_paths::PathKind;
3736
use util::nodemap::{NodeSet, DefIdMap};
3837
use std::path::PathBuf;
@@ -46,6 +45,7 @@ use syntax_pos::Span;
4645
use rustc_back::target::Target;
4746
use hir;
4847
use hir::intravisit::Visitor;
48+
use rustc_back::PanicStrategy;
4949

5050
pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown};
5151

src/librustc/middle/dependency_format.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@
6464
use hir::def_id::CrateNum;
6565

6666
use session;
67-
use session::config::{self, PanicStrategy};
67+
use session::config;
6868
use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic};
6969
use util::nodemap::FnvHashMap;
70+
use rustc_back::PanicStrategy;
7071

7172
/// A list of dependencies for a certain crate type.
7273
///
@@ -357,7 +358,7 @@ fn verify_ok(sess: &session::Session, list: &[Linkage]) {
357358
// only one, but we perform validation here that all the panic strategy
358359
// compilation modes for the whole DAG are valid.
359360
if let Some((cnum, found_strategy)) = panic_runtime {
360-
let desired_strategy = sess.opts.cg.panic.clone();
361+
let desired_strategy = sess.panic_strategy();
361362

362363
// First up, validate that our selected panic runtime is indeed exactly
363364
// our same strategy.

src/librustc/middle/weak_lang_items.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010

1111
//! Validity checking for weak lang items
1212
13-
use session::config::{self, PanicStrategy};
13+
use session::config;
1414
use session::Session;
1515
use middle::lang_items;
1616

17+
use rustc_back::PanicStrategy;
1718
use syntax::ast;
1819
use syntax::parse::token::InternedString;
1920
use syntax_pos::Span;
@@ -92,7 +93,7 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
9293
// symbols. Other panic runtimes ensure that the relevant symbols are
9394
// available to link things together, but they're never exercised.
9495
let mut whitelisted = HashSet::new();
95-
if sess.opts.cg.panic != PanicStrategy::Unwind {
96+
if sess.panic_strategy() != PanicStrategy::Unwind {
9697
whitelisted.insert(lang_items::EhPersonalityLangItem);
9798
whitelisted.insert(lang_items::EhUnwindResumeLangItem);
9899
}

src/librustc/session/config.rs

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub use self::DebugInfoLevel::*;
1919
use session::{early_error, early_warn, Session};
2020
use session::search_paths::SearchPaths;
2121

22+
use rustc_back::PanicStrategy;
2223
use rustc_back::target::Target;
2324
use lint;
2425
use middle::cstore;
@@ -492,21 +493,6 @@ impl Passes {
492493
}
493494
}
494495

495-
#[derive(Clone, PartialEq, Hash, RustcEncodable, RustcDecodable)]
496-
pub enum PanicStrategy {
497-
Unwind,
498-
Abort,
499-
}
500-
501-
impl PanicStrategy {
502-
pub fn desc(&self) -> &str {
503-
match *self {
504-
PanicStrategy::Unwind => "unwind",
505-
PanicStrategy::Abort => "abort",
506-
}
507-
}
508-
}
509-
510496
/// Declare a macro that will define all CodegenOptions/DebuggingOptions fields and parsers all
511497
/// at once. The goal of this macro is to define an interface that can be
512498
/// programmatically used by the option parser in order to initialize the struct
@@ -620,7 +606,8 @@ macro_rules! options {
620606

621607
#[allow(dead_code)]
622608
mod $mod_set {
623-
use super::{$struct_name, Passes, SomePasses, AllPasses, PanicStrategy};
609+
use super::{$struct_name, Passes, SomePasses, AllPasses};
610+
use rustc_back::PanicStrategy;
624611

625612
$(
626613
pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
@@ -732,10 +719,10 @@ macro_rules! options {
732719
}
733720
}
734721

735-
fn parse_panic_strategy(slot: &mut PanicStrategy, v: Option<&str>) -> bool {
722+
fn parse_panic_strategy(slot: &mut Option<PanicStrategy>, v: Option<&str>) -> bool {
736723
match v {
737-
Some("unwind") => *slot = PanicStrategy::Unwind,
738-
Some("abort") => *slot = PanicStrategy::Abort,
724+
Some("unwind") => *slot = Some(PanicStrategy::Unwind),
725+
Some("abort") => *slot = Some(PanicStrategy::Abort),
739726
_ => return false
740727
}
741728
true
@@ -809,7 +796,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
809796
"explicitly enable the cfg(debug_assertions) directive"),
810797
inline_threshold: Option<usize> = (None, parse_opt_uint, [TRACKED],
811798
"set the inlining threshold for"),
812-
panic: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy,
799+
panic: Option<PanicStrategy> = (None, parse_panic_strategy,
813800
[TRACKED], "panic strategy to compile crate with"),
814801
}
815802

@@ -1665,9 +1652,10 @@ mod dep_tracking {
16651652
use std::collections::BTreeMap;
16661653
use std::hash::{Hash, SipHasher};
16671654
use std::path::PathBuf;
1668-
use super::{Passes, PanicStrategy, CrateType, OptLevel, DebugInfoLevel,
1655+
use super::{Passes, CrateType, OptLevel, DebugInfoLevel,
16691656
OutputTypes, Externs, ErrorOutputType};
16701657
use syntax::feature_gate::UnstableFeatures;
1658+
use rustc_back::PanicStrategy;
16711659

16721660
pub trait DepTrackingHash {
16731661
fn hash(&self, &mut SipHasher, ErrorOutputType);
@@ -1706,6 +1694,7 @@ mod dep_tracking {
17061694
impl_dep_tracking_hash_via_hash!(Option<bool>);
17071695
impl_dep_tracking_hash_via_hash!(Option<usize>);
17081696
impl_dep_tracking_hash_via_hash!(Option<String>);
1697+
impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
17091698
impl_dep_tracking_hash_via_hash!(Option<lint::Level>);
17101699
impl_dep_tracking_hash_via_hash!(Option<PathBuf>);
17111700
impl_dep_tracking_hash_via_hash!(CrateType);
@@ -1772,7 +1761,8 @@ mod tests {
17721761
use std::iter::FromIterator;
17731762
use std::path::PathBuf;
17741763
use std::rc::Rc;
1775-
use super::{OutputType, OutputTypes, Externs, PanicStrategy};
1764+
use super::{OutputType, OutputTypes, Externs};
1765+
use rustc_back::PanicStrategy;
17761766
use syntax::{ast, attr};
17771767
use syntax::parse::token::InternedString;
17781768
use syntax::codemap::dummy_spanned;
@@ -2318,7 +2308,7 @@ mod tests {
23182308
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
23192309

23202310
opts = reference.clone();
2321-
opts.cg.panic = PanicStrategy::Abort;
2311+
opts.cg.panic = Some(PanicStrategy::Abort);
23222312
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
23232313
}
23242314

src/librustc/session/mod.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use lint;
1515
use middle::cstore::CrateStore;
1616
use middle::dependency_format;
1717
use session::search_paths::PathKind;
18-
use session::config::{DebugInfoLevel, PanicStrategy};
18+
use session::config::DebugInfoLevel;
1919
use ty::tls;
2020
use util::nodemap::{NodeMap, FnvHashMap};
2121
use util::common::duration_to_secs_str;
@@ -33,6 +33,7 @@ use syntax::{ast, codemap};
3333
use syntax::feature_gate::AttributeType;
3434
use syntax_pos::{Span, MultiSpan};
3535

36+
use rustc_back::PanicStrategy;
3637
use rustc_back::target::Target;
3738
use rustc_data_structures::flock;
3839
use llvm;
@@ -307,9 +308,13 @@ impl Session {
307308
pub fn lto(&self) -> bool {
308309
self.opts.cg.lto
309310
}
311+
/// Returns the panic strategy for this compile session. If the user explicitly selected one
312+
/// using '-C panic', use that, otherwise use the panic strategy defined by the target.
313+
pub fn panic_strategy(&self) -> PanicStrategy {
314+
self.opts.cg.panic.unwrap_or(self.target.target.options.panic_strategy)
315+
}
310316
pub fn no_landing_pads(&self) -> bool {
311-
self.opts.debugging_opts.no_landing_pads ||
312-
self.opts.cg.panic == PanicStrategy::Abort
317+
self.opts.debugging_opts.no_landing_pads || self.panic_strategy() == PanicStrategy::Abort
313318
}
314319
pub fn unstable_options(&self) -> bool {
315320
self.opts.debugging_opts.unstable_options

src/librustc_back/lib.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,36 @@ extern crate libc;
4545
extern crate serialize;
4646
#[macro_use] extern crate log;
4747

48+
extern crate serialize as rustc_serialize; // used by deriving
49+
4850
pub mod tempdir;
4951
pub mod sha2;
5052
pub mod target;
5153
pub mod slice;
5254
pub mod dynamic_lib;
55+
56+
use serialize::json::{Json, ToJson};
57+
58+
#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
59+
pub enum PanicStrategy {
60+
Unwind,
61+
Abort,
62+
}
63+
64+
impl PanicStrategy {
65+
pub fn desc(&self) -> &str {
66+
match *self {
67+
PanicStrategy::Unwind => "unwind",
68+
PanicStrategy::Abort => "abort",
69+
}
70+
}
71+
}
72+
73+
impl ToJson for PanicStrategy {
74+
fn to_json(&self) -> Json {
75+
match *self {
76+
PanicStrategy::Abort => "abort".to_json(),
77+
PanicStrategy::Unwind => "unwind".to_json(),
78+
}
79+
}
80+
}

src/librustc_back/target/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ use std::default::Default;
5050
use std::io::prelude::*;
5151
use syntax::abi::Abi;
5252

53+
use PanicStrategy;
54+
5355
mod android_base;
5456
mod apple_base;
5557
mod apple_ios_base;
@@ -347,6 +349,9 @@ pub struct TargetOptions {
347349
/// Maximum integer size in bits that this target can perform atomic
348350
/// operations on.
349351
pub max_atomic_width: u64,
352+
353+
/// Panic strategy: "unwind" or "abort"
354+
pub panic_strategy: PanicStrategy,
350355
}
351356

352357
impl Default for TargetOptions {
@@ -396,6 +401,7 @@ impl Default for TargetOptions {
396401
has_elf_tls: false,
397402
obj_is_bitcode: false,
398403
max_atomic_width: 0,
404+
panic_strategy: PanicStrategy::Unwind,
399405
}
400406
}
401407
}
@@ -474,6 +480,19 @@ impl Target {
474480
.map(|o| o.as_u64()
475481
.map(|s| base.options.$key_name = s));
476482
} );
483+
($key_name:ident, PanicStrategy) => ( {
484+
let name = (stringify!($key_name)).replace("_", "-");
485+
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
486+
match s {
487+
"unwind" => base.options.$key_name = PanicStrategy::Unwind,
488+
"abort" => base.options.$key_name = PanicStrategy::Abort,
489+
_ => return Some(Err(format!("'{}' is not a valid value for \
490+
panic-strategy. Use 'unwind' or 'abort'.",
491+
s))),
492+
}
493+
Some(Ok(()))
494+
})).unwrap_or(Ok(()))
495+
} );
477496
($key_name:ident, list) => ( {
478497
let name = (stringify!($key_name)).replace("_", "-");
479498
obj.find(&name[..]).map(|o| o.as_array()
@@ -534,6 +553,7 @@ impl Target {
534553
key!(has_elf_tls, bool);
535554
key!(obj_is_bitcode, bool);
536555
key!(max_atomic_width, u64);
556+
try!(key!(panic_strategy, PanicStrategy));
537557

538558
Ok(base)
539559
}
@@ -676,6 +696,7 @@ impl ToJson for Target {
676696
target_option_val!(has_elf_tls);
677697
target_option_val!(obj_is_bitcode);
678698
target_option_val!(max_atomic_width);
699+
target_option_val!(panic_strategy);
679700

680701
Json::Object(d)
681702
}

src/librustc_metadata/creader.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc::hir::def_id::{CrateNum, DefIndex};
1919
use rustc::hir::svh::Svh;
2020
use rustc::middle::cstore::LoadedMacro;
2121
use rustc::session::{config, Session};
22-
use rustc::session::config::PanicStrategy;
22+
use rustc_back::PanicStrategy;
2323
use rustc::session::search_paths::PathKind;
2424
use rustc::middle;
2525
use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
@@ -710,7 +710,7 @@ impl<'a> CrateReader<'a> {
710710
// The logic for finding the panic runtime here is pretty much the same
711711
// as the allocator case with the only addition that the panic strategy
712712
// compilation mode also comes into play.
713-
let desired_strategy = self.sess.opts.cg.panic.clone();
713+
let desired_strategy = self.sess.panic_strategy();
714714
let mut runtime_found = false;
715715
let mut needs_panic_runtime = attr::contains_name(&krate.attrs,
716716
"needs_panic_runtime");

src/librustc_metadata/csearch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rustc::hir::map::DefKey;
2626
use rustc::mir::repr::Mir;
2727
use rustc::mir::mir_map::MirMap;
2828
use rustc::util::nodemap::{NodeSet, DefIdMap};
29-
use rustc::session::config::PanicStrategy;
29+
use rustc_back::PanicStrategy;
3030

3131
use std::path::PathBuf;
3232
use syntax::ast;

src/librustc_metadata/cstore.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex, DefId};
1919
use rustc::hir::map::DefKey;
2020
use rustc::hir::svh::Svh;
2121
use rustc::middle::cstore::ExternCrate;
22-
use rustc::session::config::PanicStrategy;
22+
use rustc_back::PanicStrategy;
2323
use rustc_data_structures::indexed_vec::IndexVec;
2424
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap, FnvHashSet};
2525

src/librustc_metadata/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
12931293
triple: tcx.sess.opts.target_triple.clone(),
12941294
hash: link_meta.crate_hash,
12951295
disambiguator: tcx.sess.local_crate_disambiguator().to_string(),
1296-
panic_strategy: tcx.sess.opts.cg.panic.clone(),
1296+
panic_strategy: tcx.sess.panic_strategy(),
12971297
plugin_registrar_fn: tcx.sess.plugin_registrar_fn.get().map(|id| {
12981298
tcx.map.local_def_id(id).index
12991299
}),

src/librustc_metadata/schema.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc::middle::cstore::{LinkagePreference, NativeLibraryKind};
1818
use rustc::middle::lang_items;
1919
use rustc::mir;
2020
use rustc::ty::{self, Ty};
21-
use rustc::session::config::PanicStrategy;
21+
use rustc_back::PanicStrategy;
2222

2323
use rustc_serialize as serialize;
2424
use syntax::{ast, attr};

0 commit comments

Comments
 (0)