diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs index ecdd02b4697..04c71bdbe72 100644 --- a/src/rustc/driver/driver.rs +++ b/src/rustc/driver/driver.rs @@ -514,8 +514,10 @@ fn build_session_options(binary: ~str, link::output_type_llvm_assembly | link::output_type_assembly => (), _ => debugging_opts |= session::no_asm_comments } - let opt_level = - if opt_present(matches, ~"O") { + let opt_level = { + if (debugging_opts & session::no_opt) != 0 { + No + } else if opt_present(matches, ~"O") { if opt_present(matches, ~"opt-level") { early_error(demitter, ~"-O and --opt-level both provided"); } @@ -531,7 +533,8 @@ fn build_session_options(binary: ~str, ~"to be between 0-3") } } - } else { No }; + } else { No } + }; let target = match target_opt { None => host_triple(), diff --git a/src/rustc/driver/session.rs b/src/rustc/driver/session.rs index 66544d72db5..22946e556e8 100644 --- a/src/rustc/driver/session.rs +++ b/src/rustc/driver/session.rs @@ -38,25 +38,26 @@ type config = uint_type: uint_ty, float_type: float_ty}; -const ppregions: uint = 1u; -const time_passes: uint = 2u; -const count_llvm_insns: uint = 4u; -const time_llvm_passes: uint = 8u; -const trans_stats: uint = 16u; -const no_asm_comments: uint = 32u; -const no_verify: uint = 64u; -const trace: uint = 128u; +const ppregions: uint = 1 << 0; +const time_passes: uint = 1 << 1; +const count_llvm_insns: uint = 1 << 2; +const time_llvm_passes: uint = 1 << 3; +const trans_stats: uint = 1 << 4; +const no_asm_comments: uint = 1 << 5; +const no_verify: uint = 1 << 6; +const trace: uint = 1 << 7; // FIXME (#2377): This exists to transition to a Rust crate runtime // It should be removed -const no_rt: uint = 256u; -const coherence: uint = 512u; -const borrowck_stats: uint = 1024u; -const borrowck_note_pure: uint = 2048; -const borrowck_note_loan: uint = 4096; -const no_landing_pads: uint = 8192; -const debug_llvm: uint = 16384; -const count_type_sizes: uint = 32768; -const meta_stats: uint = 65536; +const no_rt: uint = 1 << 8; +const coherence: uint = 1 << 9; +const borrowck_stats: uint = 1 << 10; +const borrowck_note_pure: uint = 1 << 11; +const borrowck_note_loan: uint = 1 << 12; +const no_landing_pads: uint = 1 << 13; +const debug_llvm: uint = 1 << 14; +const count_type_sizes: uint = 1 << 15; +const meta_stats: uint = 1 << 16; +const no_opt: uint = 1 << 17; fn debugging_opts_map() -> ~[(~str, ~str, uint)] { ~[(~"ppregions", ~"prettyprint regions with \ @@ -82,7 +83,8 @@ fn debugging_opts_map() -> ~[(~str, ~str, uint)] { (~"debug-llvm", ~"enable debug output from LLVM", debug_llvm), (~"count-type-sizes", ~"count the sizes of aggregate types", count_type_sizes), - (~"meta-stats", ~"gather metadata statistics", meta_stats) + (~"meta-stats", ~"gather metadata statistics", meta_stats), + (~"no-opt", ~"do not optimize, even if -O is passed", no_opt), ] } diff --git a/src/rustc/middle/trans/datum.rs b/src/rustc/middle/trans/datum.rs index f2525ce90b0..f70284ba547 100644 --- a/src/rustc/middle/trans/datum.rs +++ b/src/rustc/middle/trans/datum.rs @@ -241,6 +241,10 @@ impl Datum { let _icx = bcx.insn_ctxt("copy_to"); + if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) { + return bcx; + } + debug!("copy_to(self=%s, action=%?, dst=%s)", self.to_str(bcx.ccx()), action, bcx.val_str(dst)); diff --git a/src/test/run-pass/capture_nil.rs b/src/test/run-pass/capture_nil.rs new file mode 100644 index 00000000000..41359ceec18 --- /dev/null +++ b/src/test/run-pass/capture_nil.rs @@ -0,0 +1,29 @@ +// compile-flags:-Z no-opt +use comm::*; + +// This test has to be setup just so to trigger +// the condition which was causing us a crash. +// The situation is that we are capturing a +// () value by ref. We generally feel free, +// however, to substitute NULL pointers and +// undefined values for values of () type, and +// so this caused a segfault when we copied into +// the closure. +// +// The fix is just to not emit any actual loads +// or stores for copies of () type (which is of +// course preferable, as the value itself is +// irrelevant). + +fn foo(&&x: ()) -> Port<()> { + let p = Port(); + let c = Chan(p); + do task::spawn() |copy c, copy x| { + c.send(x); + } + p +} + +fn main() { + foo(()).recv() +}