Control LLVM's TrapUnreachable feature through rustc's TargetOptions.

This commit is contained in:
Dan Gohman 2017-11-11 07:08:00 -08:00
parent 365c159b80
commit 7b6b764917
4 changed files with 19 additions and 7 deletions

View File

@ -435,6 +435,10 @@ pub struct TargetOptions {
/// Default number of codegen units to use in debug mode
pub default_codegen_units: Option<u64>,
/// Whether to generate trap instructions in places where optimization would
/// otherwise produce control flow that falls through into unrelated memory.
pub trap_unreachable: bool,
}
impl Default for TargetOptions {
@ -498,6 +502,7 @@ impl Default for TargetOptions {
stack_probes: false,
min_global_align: None,
default_codegen_units: None,
trap_unreachable: true,
}
}
}
@ -739,6 +744,7 @@ impl Target {
key!(stack_probes, bool);
key!(min_global_align, Option<u64>);
key!(default_codegen_units, Option<u64>);
key!(trap_unreachable, bool);
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
for name in array.iter().filter_map(|abi| abi.as_string()) {
@ -932,6 +938,7 @@ impl ToJson for Target {
target_option_val!(stack_probes);
target_option_val!(min_global_align);
target_option_val!(default_codegen_units);
target_option_val!(trap_unreachable);
if default.abi_blacklist != self.options.abi_blacklist {
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()

View File

@ -1605,7 +1605,8 @@ extern "C" {
UseSoftFP: bool,
PositionIndependentExecutable: bool,
FunctionSections: bool,
DataSections: bool)
DataSections: bool,
TrapUnreachable: bool)
-> TargetMachineRef;
pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, M: ModuleRef);

View File

@ -196,6 +196,7 @@ pub fn target_machine_factory(sess: &Session)
let cpu = CString::new(cpu.as_bytes()).unwrap();
let features = CString::new(target_feature(sess).as_bytes()).unwrap();
let is_pie_binary = is_pie_binary(sess);
let trap_unreachable = sess.target.target.options.trap_unreachable;
Arc::new(move || {
let tm = unsafe {
@ -208,6 +209,7 @@ pub fn target_machine_factory(sess: &Session)
is_pie_binary,
ffunction_sections,
fdata_sections,
trap_unreachable,
)
};

View File

@ -366,7 +366,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc,
LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
bool PositionIndependentExecutable, bool FunctionSections,
bool DataSections) {
bool DataSections, bool TrapUnreachable) {
auto CM = fromRust(RustCM);
auto OptLevel = fromRust(RustOptLevel);
@ -398,11 +398,13 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
Options.DataSections = DataSections;
Options.FunctionSections = FunctionSections;
// Tell LLVM to translate `unreachable` into an explicit trap instruction.
// This limits the extent of possible undefined behavior in some cases, as it
// prevents control flow from "falling through" into whatever code happens to
// be laid out next in memory.
Options.TrapUnreachable = true;
if (TrapUnreachable) {
// Tell LLVM to translate `unreachable` into an explicit trap instruction.
// This limits the extent of possible undefined behavior in some cases, as
// it prevents control flow from "falling through" into whatever code
// happens to be laid out next in memory.
Options.TrapUnreachable = true;
}
TargetMachine *TM = TheTarget->createTargetMachine(
Trip.getTriple(), RealCPU, Feature, Options, RM, CM, OptLevel);