about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJorge Aparicio <japaricious@gmail.com>2016-09-27 21:26:08 -0500
committerJorge Aparicio <japaricious@gmail.com>2016-09-27 21:26:08 -0500
commitcbb967f3169181f2afdd4bdcd3af4ff448008b2c (patch)
tree4571dac026513a36b9f0f8f8f096eb684634c363 /src
parent49dd95b07807a26f94bf11eb4771bbb7d79ef02c (diff)
downloadrust-cbb967f3169181f2afdd4bdcd3af4ff448008b2c.tar.gz
rust-cbb967f3169181f2afdd4bdcd3af4ff448008b2c.zip
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 #36647
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/cstore.rs2
-rw-r--r--src/librustc/middle/dependency_format.rs5
-rw-r--r--src/librustc/middle/weak_lang_items.rs5
-rw-r--r--src/librustc/session/config.rs34
-rw-r--r--src/librustc/session/mod.rs11
-rw-r--r--src/librustc_back/lib.rs28
-rw-r--r--src/librustc_back/target/mod.rs21
-rw-r--r--src/librustc_metadata/creader.rs4
-rw-r--r--src/librustc_metadata/csearch.rs2
-rw-r--r--src/librustc_metadata/cstore.rs2
-rw-r--r--src/librustc_metadata/encoder.rs2
-rw-r--r--src/librustc_metadata/schema.rs2
12 files changed, 82 insertions, 36 deletions
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 62e0de1ba67..d4a69627109 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -32,7 +32,6 @@ use ty::{self, Ty, TyCtxt};
 use mir::repr::Mir;
 use mir::mir_map::MirMap;
 use session::Session;
-use session::config::PanicStrategy;
 use session::search_paths::PathKind;
 use util::nodemap::{NodeSet, DefIdMap};
 use std::path::PathBuf;
@@ -45,6 +44,7 @@ use syntax_pos::Span;
 use rustc_back::target::Target;
 use hir;
 use hir::intravisit::Visitor;
+use rustc_back::PanicStrategy;
 
 pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown};
 
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index c6908e11ed2..159b7256c7a 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -64,9 +64,10 @@
 use hir::def_id::CrateNum;
 
 use session;
-use session::config::{self, PanicStrategy};
+use session::config;
 use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic};
 use util::nodemap::FnvHashMap;
+use rustc_back::PanicStrategy;
 
 /// A list of dependencies for a certain crate type.
 ///
@@ -357,7 +358,7 @@ fn verify_ok(sess: &session::Session, list: &[Linkage]) {
     // only one, but we perform validation here that all the panic strategy
     // compilation modes for the whole DAG are valid.
     if let Some((cnum, found_strategy)) = panic_runtime {
-        let desired_strategy = sess.opts.cg.panic.clone();
+        let desired_strategy = sess.panic_strategy();
 
         // First up, validate that our selected panic runtime is indeed exactly
         // our same strategy.
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index c2f275e6dea..aa75c7a572b 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -10,10 +10,11 @@
 
 //! Validity checking for weak lang items
 
-use session::config::{self, PanicStrategy};
+use session::config;
 use session::Session;
 use middle::lang_items;
 
+use rustc_back::PanicStrategy;
 use syntax::ast;
 use syntax::parse::token::InternedString;
 use syntax_pos::Span;
@@ -92,7 +93,7 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
     // symbols. Other panic runtimes ensure that the relevant symbols are
     // available to link things together, but they're never exercised.
     let mut whitelisted = HashSet::new();
-    if sess.opts.cg.panic != PanicStrategy::Unwind {
+    if sess.panic_strategy() != PanicStrategy::Unwind {
         whitelisted.insert(lang_items::EhPersonalityLangItem);
         whitelisted.insert(lang_items::EhUnwindResumeLangItem);
     }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 2e01ec9b0a7..d4fa0f7d1f0 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -19,6 +19,7 @@ pub use self::DebugInfoLevel::*;
 use session::{early_error, early_warn, Session};
 use session::search_paths::SearchPaths;
 
+use rustc_back::PanicStrategy;
 use rustc_back::target::Target;
 use lint;
 use middle::cstore;
@@ -493,21 +494,6 @@ impl Passes {
     }
 }
 
-#[derive(Clone, PartialEq, Hash, RustcEncodable, RustcDecodable)]
-pub enum PanicStrategy {
-    Unwind,
-    Abort,
-}
-
-impl PanicStrategy {
-    pub fn desc(&self) -> &str {
-        match *self {
-            PanicStrategy::Unwind => "unwind",
-            PanicStrategy::Abort => "abort",
-        }
-    }
-}
-
 /// Declare a macro that will define all CodegenOptions/DebuggingOptions fields and parsers all
 /// at once. The goal of this macro is to define an interface that can be
 /// programmatically used by the option parser in order to initialize the struct
@@ -620,7 +606,8 @@ macro_rules! options {
 
     #[allow(dead_code)]
     mod $mod_set {
-        use super::{$struct_name, Passes, SomePasses, AllPasses, PanicStrategy};
+        use super::{$struct_name, Passes, SomePasses, AllPasses};
+        use rustc_back::PanicStrategy;
 
         $(
             pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
@@ -725,10 +712,10 @@ macro_rules! options {
             }
         }
 
-        fn parse_panic_strategy(slot: &mut PanicStrategy, v: Option<&str>) -> bool {
+        fn parse_panic_strategy(slot: &mut Option<PanicStrategy>, v: Option<&str>) -> bool {
             match v {
-                Some("unwind") => *slot = PanicStrategy::Unwind,
-                Some("abort") => *slot = PanicStrategy::Abort,
+                Some("unwind") => *slot = Some(PanicStrategy::Unwind),
+                Some("abort") => *slot = Some(PanicStrategy::Abort),
                 _ => return false
             }
             true
@@ -800,7 +787,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
         "explicitly enable the cfg(debug_assertions) directive"),
     inline_threshold: Option<usize> = (None, parse_opt_uint, [TRACKED],
         "set the inlining threshold for"),
-    panic: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy,
+    panic: Option<PanicStrategy> = (None, parse_panic_strategy,
         [TRACKED], "panic strategy to compile crate with"),
 }
 
@@ -1676,9 +1663,10 @@ mod dep_tracking {
     use std::collections::BTreeMap;
     use std::hash::{Hash, SipHasher};
     use std::path::PathBuf;
-    use super::{Passes, PanicStrategy, CrateType, OptLevel, DebugInfoLevel,
+    use super::{Passes, CrateType, OptLevel, DebugInfoLevel,
                 OutputTypes, Externs, ErrorOutputType};
     use syntax::feature_gate::UnstableFeatures;
+    use rustc_back::PanicStrategy;
 
     pub trait DepTrackingHash {
         fn hash(&self, &mut SipHasher, ErrorOutputType);
@@ -1717,6 +1705,7 @@ mod dep_tracking {
     impl_dep_tracking_hash_via_hash!(Option<bool>);
     impl_dep_tracking_hash_via_hash!(Option<usize>);
     impl_dep_tracking_hash_via_hash!(Option<String>);
+    impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
     impl_dep_tracking_hash_via_hash!(Option<lint::Level>);
     impl_dep_tracking_hash_via_hash!(Option<PathBuf>);
     impl_dep_tracking_hash_via_hash!(CrateType);
@@ -1783,7 +1772,8 @@ mod tests {
     use std::iter::FromIterator;
     use std::path::PathBuf;
     use std::rc::Rc;
-    use super::{OutputType, OutputTypes, Externs, PanicStrategy};
+    use super::{OutputType, OutputTypes, Externs};
+    use rustc_back::PanicStrategy;
     use syntax::{ast, attr};
     use syntax::parse::token::InternedString;
     use syntax::codemap::dummy_spanned;
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 268dbd70bb5..f048da49777 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -15,7 +15,7 @@ use lint;
 use middle::cstore::CrateStore;
 use middle::dependency_format;
 use session::search_paths::PathKind;
-use session::config::{DebugInfoLevel, PanicStrategy};
+use session::config::DebugInfoLevel;
 use ty::tls;
 use util::nodemap::{NodeMap, FnvHashMap};
 use util::common::duration_to_secs_str;
@@ -33,6 +33,7 @@ use syntax::{ast, codemap};
 use syntax::feature_gate::AttributeType;
 use syntax_pos::{Span, MultiSpan};
 
+use rustc_back::PanicStrategy;
 use rustc_back::target::Target;
 use rustc_data_structures::flock;
 use llvm;
@@ -306,9 +307,13 @@ impl Session {
     pub fn lto(&self) -> bool {
         self.opts.cg.lto
     }
+    /// Returns the panic strategy for this compile session. If the user explicitly selected one
+    /// using '-C panic', use that, otherwise use the panic strategy defined by the target.
+    pub fn panic_strategy(&self) -> PanicStrategy {
+        self.opts.cg.panic.unwrap_or(self.target.target.options.panic_strategy)
+    }
     pub fn no_landing_pads(&self) -> bool {
-        self.opts.debugging_opts.no_landing_pads ||
-            self.opts.cg.panic == PanicStrategy::Abort
+        self.opts.debugging_opts.no_landing_pads || self.panic_strategy() == PanicStrategy::Abort
     }
     pub fn unstable_options(&self) -> bool {
         self.opts.debugging_opts.unstable_options
diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs
index f7ae47d2e5e..c0f358ca801 100644
--- a/src/librustc_back/lib.rs
+++ b/src/librustc_back/lib.rs
@@ -45,8 +45,36 @@ extern crate libc;
 extern crate serialize;
 #[macro_use] extern crate log;
 
+extern crate serialize as rustc_serialize; // used by deriving
+
 pub mod tempdir;
 pub mod sha2;
 pub mod target;
 pub mod slice;
 pub mod dynamic_lib;
+
+use serialize::json::{Json, ToJson};
+
+#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+pub enum PanicStrategy {
+    Unwind,
+    Abort,
+}
+
+impl PanicStrategy {
+    pub fn desc(&self) -> &str {
+        match *self {
+            PanicStrategy::Unwind => "unwind",
+            PanicStrategy::Abort => "abort",
+        }
+    }
+}
+
+impl ToJson for PanicStrategy {
+    fn to_json(&self) -> Json {
+        match *self {
+            PanicStrategy::Abort => "abort".to_json(),
+            PanicStrategy::Unwind => "unwind".to_json(),
+        }
+    }
+}
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index 756586602b4..f085023de0f 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -50,6 +50,8 @@ use std::default::Default;
 use std::io::prelude::*;
 use syntax::abi::Abi;
 
+use PanicStrategy;
+
 mod android_base;
 mod apple_base;
 mod apple_ios_base;
@@ -343,6 +345,9 @@ pub struct TargetOptions {
     /// Maximum integer size in bits that this target can perform atomic
     /// operations on.
     pub max_atomic_width: u64,
+
+    /// Panic strategy: "unwind" or "abort"
+    pub panic_strategy: PanicStrategy,
 }
 
 impl Default for TargetOptions {
@@ -392,6 +397,7 @@ impl Default for TargetOptions {
             has_elf_tls: false,
             obj_is_bitcode: false,
             max_atomic_width: 0,
+            panic_strategy: PanicStrategy::Unwind,
         }
     }
 }
@@ -470,6 +476,19 @@ impl Target {
                     .map(|o| o.as_u64()
                          .map(|s| base.options.$key_name = s));
             } );
+            ($key_name:ident, PanicStrategy) => ( {
+                let name = (stringify!($key_name)).replace("_", "-");
+                obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
+                    match s {
+                        "unwind" => base.options.$key_name = PanicStrategy::Unwind,
+                        "abort" => base.options.$key_name = PanicStrategy::Abort,
+                        _ => return Some(Err(format!("'{}' is not a valid value for \
+                                                      panic-strategy. Use 'unwind' or 'abort'.",
+                                                     s))),
+                }
+                Some(Ok(()))
+            })).unwrap_or(Ok(()))
+            } );
             ($key_name:ident, list) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.find(&name[..]).map(|o| o.as_array()
@@ -530,6 +549,7 @@ impl Target {
         key!(has_elf_tls, bool);
         key!(obj_is_bitcode, bool);
         key!(max_atomic_width, u64);
+        try!(key!(panic_strategy, PanicStrategy));
 
         Ok(base)
     }
@@ -672,6 +692,7 @@ impl ToJson for Target {
         target_option_val!(has_elf_tls);
         target_option_val!(obj_is_bitcode);
         target_option_val!(max_atomic_width);
+        target_option_val!(panic_strategy);
 
         Json::Object(d)
     }
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 71cc13aebb3..be908ff9d19 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -18,7 +18,7 @@ use schema::CrateRoot;
 use rustc::hir::def_id::{CrateNum, DefIndex};
 use rustc::hir::svh::Svh;
 use rustc::session::{config, Session};
-use rustc::session::config::PanicStrategy;
+use rustc_back::PanicStrategy;
 use rustc::session::search_paths::PathKind;
 use rustc::middle;
 use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
@@ -710,7 +710,7 @@ impl<'a> CrateReader<'a> {
         // The logic for finding the panic runtime here is pretty much the same
         // as the allocator case with the only addition that the panic strategy
         // compilation mode also comes into play.
-        let desired_strategy = self.sess.opts.cg.panic.clone();
+        let desired_strategy = self.sess.panic_strategy();
         let mut runtime_found = false;
         let mut needs_panic_runtime = attr::contains_name(&krate.attrs,
                                                           "needs_panic_runtime");
diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs
index 1f25136ffe1..16a5b5402fb 100644
--- a/src/librustc_metadata/csearch.rs
+++ b/src/librustc_metadata/csearch.rs
@@ -26,7 +26,7 @@ use rustc::hir::map::DefKey;
 use rustc::mir::repr::Mir;
 use rustc::mir::mir_map::MirMap;
 use rustc::util::nodemap::{NodeSet, DefIdMap};
-use rustc::session::config::PanicStrategy;
+use rustc_back::PanicStrategy;
 
 use std::path::PathBuf;
 use syntax::ast;
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 0a1ff70a049..038d0f73d5c 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -19,7 +19,7 @@ use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex, DefId};
 use rustc::hir::map::DefKey;
 use rustc::hir::svh::Svh;
 use rustc::middle::cstore::ExternCrate;
-use rustc::session::config::PanicStrategy;
+use rustc_back::PanicStrategy;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap, FnvHashSet};
 
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 0f067270b80..ca4fb77d95a 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1293,7 +1293,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             triple: tcx.sess.opts.target_triple.clone(),
             hash: link_meta.crate_hash,
             disambiguator: tcx.sess.local_crate_disambiguator().to_string(),
-            panic_strategy: tcx.sess.opts.cg.panic.clone(),
+            panic_strategy: tcx.sess.panic_strategy(),
             plugin_registrar_fn: tcx.sess.plugin_registrar_fn.get().map(|id| {
                 tcx.map.local_def_id(id).index
             }),
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index f4d1e8e17f8..58e18bc709e 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -18,7 +18,7 @@ use rustc::middle::cstore::{LinkagePreference, NativeLibraryKind};
 use rustc::middle::lang_items;
 use rustc::mir;
 use rustc::ty::{self, Ty};
-use rustc::session::config::PanicStrategy;
+use rustc_back::PanicStrategy;
 
 use rustc_serialize as serialize;
 use syntax::{ast, attr};