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
4 changed files with 59 additions and 21 deletions
|
@ -514,8 +514,10 @@ fn build_session_options(binary: ~str,
|
||||||
link::output_type_llvm_assembly | link::output_type_assembly => (),
|
link::output_type_llvm_assembly | link::output_type_assembly => (),
|
||||||
_ => debugging_opts |= session::no_asm_comments
|
_ => debugging_opts |= session::no_asm_comments
|
||||||
}
|
}
|
||||||
let opt_level =
|
let opt_level = {
|
||||||
if opt_present(matches, ~"O") {
|
if (debugging_opts & session::no_opt) != 0 {
|
||||||
|
No
|
||||||
|
} else if opt_present(matches, ~"O") {
|
||||||
if opt_present(matches, ~"opt-level") {
|
if opt_present(matches, ~"opt-level") {
|
||||||
early_error(demitter, ~"-O and --opt-level both provided");
|
early_error(demitter, ~"-O and --opt-level both provided");
|
||||||
}
|
}
|
||||||
|
@ -531,7 +533,8 @@ fn build_session_options(binary: ~str,
|
||||||
~"to be between 0-3")
|
~"to be between 0-3")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { No };
|
} else { No }
|
||||||
|
};
|
||||||
let target =
|
let target =
|
||||||
match target_opt {
|
match target_opt {
|
||||||
None => host_triple(),
|
None => host_triple(),
|
||||||
|
|
|
@ -38,25 +38,26 @@ type config =
|
||||||
uint_type: uint_ty,
|
uint_type: uint_ty,
|
||||||
float_type: float_ty};
|
float_type: float_ty};
|
||||||
|
|
||||||
const ppregions: uint = 1u;
|
const ppregions: uint = 1 << 0;
|
||||||
const time_passes: uint = 2u;
|
const time_passes: uint = 1 << 1;
|
||||||
const count_llvm_insns: uint = 4u;
|
const count_llvm_insns: uint = 1 << 2;
|
||||||
const time_llvm_passes: uint = 8u;
|
const time_llvm_passes: uint = 1 << 3;
|
||||||
const trans_stats: uint = 16u;
|
const trans_stats: uint = 1 << 4;
|
||||||
const no_asm_comments: uint = 32u;
|
const no_asm_comments: uint = 1 << 5;
|
||||||
const no_verify: uint = 64u;
|
const no_verify: uint = 1 << 6;
|
||||||
const trace: uint = 128u;
|
const trace: uint = 1 << 7;
|
||||||
// FIXME (#2377): This exists to transition to a Rust crate runtime
|
// FIXME (#2377): This exists to transition to a Rust crate runtime
|
||||||
// It should be removed
|
// It should be removed
|
||||||
const no_rt: uint = 256u;
|
const no_rt: uint = 1 << 8;
|
||||||
const coherence: uint = 512u;
|
const coherence: uint = 1 << 9;
|
||||||
const borrowck_stats: uint = 1024u;
|
const borrowck_stats: uint = 1 << 10;
|
||||||
const borrowck_note_pure: uint = 2048;
|
const borrowck_note_pure: uint = 1 << 11;
|
||||||
const borrowck_note_loan: uint = 4096;
|
const borrowck_note_loan: uint = 1 << 12;
|
||||||
const no_landing_pads: uint = 8192;
|
const no_landing_pads: uint = 1 << 13;
|
||||||
const debug_llvm: uint = 16384;
|
const debug_llvm: uint = 1 << 14;
|
||||||
const count_type_sizes: uint = 32768;
|
const count_type_sizes: uint = 1 << 15;
|
||||||
const meta_stats: uint = 65536;
|
const meta_stats: uint = 1 << 16;
|
||||||
|
const no_opt: uint = 1 << 17;
|
||||||
|
|
||||||
fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
|
fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
|
||||||
~[(~"ppregions", ~"prettyprint regions with \
|
~[(~"ppregions", ~"prettyprint regions with \
|
||||||
|
@ -82,7 +83,8 @@ fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
|
||||||
(~"debug-llvm", ~"enable debug output from LLVM", debug_llvm),
|
(~"debug-llvm", ~"enable debug output from LLVM", debug_llvm),
|
||||||
(~"count-type-sizes", ~"count the sizes of aggregate types",
|
(~"count-type-sizes", ~"count the sizes of aggregate types",
|
||||||
count_type_sizes),
|
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");
|
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)",
|
debug!("copy_to(self=%s, action=%?, dst=%s)",
|
||||||
self.to_str(bcx.ccx()), action, bcx.val_str(dst));
|
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…
Add table
Add a link
Reference in a new issue