Do not copy values of type () or _|_
This can trigger a crash because we assume we can supply null ptrs and undefined values for values of those types, as we should be treated them as zero-size. Interestingly, this crash only shows up (atm) in non-optimized builds. Therefore, I added a -Z no-opt flag so that the new test (capture_nil) can specify that it should not run with optimizations enabled.
This commit is contained in:
parent
c21b3ff818
commit
14303bad89
@ -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(),
|
||||
|
@ -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),
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
29
src/test/run-pass/capture_nil.rs
Normal file
29
src/test/run-pass/capture_nil.rs
Normal file
@ -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()
|
||||
}
|
Loading…
Reference in New Issue
Block a user