Skip to content

Commit 9e1e152

Browse files
committed
auto merge of #8596 : vadimcn/rust/master, r=alexcrichton
This resolves issue #908. Notable changes: - On Windows, LLVM integrated assembler emits bad stack unwind tables when segmented stacks are enabled. However, unwind info directives in the assembly output are correct, so we generate assembly first and then run it through an external assembler, just like it is already done for Android builds. - Linker is invoked via "g++" command instead of "gcc": g++ passes the appropriate magic parameters to the linker, which ensure correct registration of stack unwind tables in dynamic libraries.
2 parents 6f70377 + 651f382 commit 9e1e152

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+94
-166
lines changed

src/libextra/arc.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ mod tests {
612612
}
613613
}
614614
615-
#[test] #[should_fail] #[ignore(cfg(windows))]
615+
#[test] #[should_fail]
616616
fn test_arc_condvar_poison() {
617617
unsafe {
618618
let arc = ~MutexArc::new(1);
@@ -636,7 +636,7 @@ mod tests {
636636
}
637637
}
638638
}
639-
#[test] #[should_fail] #[ignore(cfg(windows))]
639+
#[test] #[should_fail]
640640
fn test_mutex_arc_poison() {
641641
unsafe {
642642
let arc = ~MutexArc::new(1);
@@ -651,7 +651,7 @@ mod tests {
651651
}
652652
}
653653
}
654-
#[test] #[should_fail] #[ignore(cfg(windows))]
654+
#[test] #[should_fail]
655655
pub fn test_mutex_arc_unwrap_poison() {
656656
let arc = MutexArc::new(1);
657657
let arc2 = ~(&arc).clone();
@@ -668,7 +668,7 @@ mod tests {
668668
let one = arc.unwrap();
669669
assert!(one == 1);
670670
}
671-
#[test] #[should_fail] #[ignore(cfg(windows))]
671+
#[test] #[should_fail]
672672
fn test_rw_arc_poison_wr() {
673673
let arc = ~RWArc::new(1);
674674
let arc2 = (*arc).clone();
@@ -681,7 +681,7 @@ mod tests {
681681
assert_eq!(*one, 1);
682682
}
683683
}
684-
#[test] #[should_fail] #[ignore(cfg(windows))]
684+
#[test] #[should_fail]
685685
fn test_rw_arc_poison_ww() {
686686
let arc = ~RWArc::new(1);
687687
let arc2 = (*arc).clone();
@@ -694,7 +694,7 @@ mod tests {
694694
assert_eq!(*one, 1);
695695
}
696696
}
697-
#[test] #[should_fail] #[ignore(cfg(windows))]
697+
#[test] #[should_fail]
698698
fn test_rw_arc_poison_dw() {
699699
let arc = ~RWArc::new(1);
700700
let arc2 = (*arc).clone();
@@ -709,7 +709,7 @@ mod tests {
709709
assert_eq!(*one, 1);
710710
}
711711
}
712-
#[test] #[ignore(cfg(windows))]
712+
#[test]
713713
fn test_rw_arc_no_poison_rr() {
714714
let arc = ~RWArc::new(1);
715715
let arc2 = (*arc).clone();
@@ -722,7 +722,7 @@ mod tests {
722722
assert_eq!(*one, 1);
723723
}
724724
}
725-
#[test] #[ignore(cfg(windows))]
725+
#[test]
726726
fn test_rw_arc_no_poison_rw() {
727727
let arc = ~RWArc::new(1);
728728
let arc2 = (*arc).clone();
@@ -735,7 +735,7 @@ mod tests {
735735
assert_eq!(*one, 1);
736736
}
737737
}
738-
#[test] #[ignore(cfg(windows))]
738+
#[test]
739739
fn test_rw_arc_no_poison_dr() {
740740
let arc = ~RWArc::new(1);
741741
let arc2 = (*arc).clone();

src/libextra/arena.rs

-1
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,6 @@ fn test_arena_destructors() {
291291

292292
#[test]
293293
#[should_fail]
294-
#[ignore(cfg(windows))]
295294
fn test_arena_destructors_fail() {
296295
let arena = Arena::new();
297296
// Put some stuff in the arena.

src/libextra/c_vec.rs

-2
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ mod tests {
185185

186186
#[test]
187187
#[should_fail]
188-
#[ignore(cfg(windows))]
189188
fn test_overrun_get() {
190189
let cv = malloc(16u as size_t);
191190

@@ -194,7 +193,6 @@ mod tests {
194193

195194
#[test]
196195
#[should_fail]
197-
#[ignore(cfg(windows))]
198196
fn test_overrun_set() {
199197
let cv = malloc(16u as size_t);
200198

src/libextra/flatpipes.rs

-2
Original file line numberDiff line numberDiff line change
@@ -967,12 +967,10 @@ mod test {
967967
}
968968

969969
#[test]
970-
#[ignore(cfg(windows))]
971970
fn test_try_recv_none4_reader() {
972971
test_try_recv_none4(reader_port_loader);
973972
}
974973
#[test]
975-
#[ignore(cfg(windows))]
976974
fn test_try_recv_none4_pipe() {
977975
test_try_recv_none4(pipe_port_loader);
978976
}

src/libextra/future.rs

-1
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@ mod test {
212212
213213
#[test]
214214
#[should_fail]
215-
#[ignore(cfg(target_os = "win32"))]
216215
fn test_futurefail() {
217216
let mut f = spawn(|| fail!());
218217
let _x: ~str = f.get();

src/libextra/priority_queue.rs

-3
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,6 @@ mod tests {
338338

339339
#[test]
340340
#[should_fail]
341-
#[ignore(cfg(windows))]
342341
fn test_empty_pop() { let mut heap = PriorityQueue::new::<int>(); heap.pop(); }
343342

344343
#[test]
@@ -349,7 +348,6 @@ mod tests {
349348

350349
#[test]
351350
#[should_fail]
352-
#[ignore(cfg(windows))]
353351
fn test_empty_top() { let empty = PriorityQueue::new::<int>(); empty.top(); }
354352

355353
#[test]
@@ -360,7 +358,6 @@ mod tests {
360358

361359
#[test]
362360
#[should_fail]
363-
#[ignore(cfg(windows))]
364361
fn test_empty_replace() { let mut heap = PriorityQueue::new(); heap.replace(5); }
365362

366363
#[test]

src/libextra/sync.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -921,7 +921,7 @@ mod tests {
921921
assert!(!cond.signal());
922922
}
923923
}
924-
#[test] #[ignore(cfg(windows))]
924+
#[test]
925925
fn test_mutex_killed_simple() {
926926
// Mutex must get automatically unlocked if failed/killed within.
927927
let m = ~Mutex::new();
@@ -937,7 +937,7 @@ mod tests {
937937
do m.lock { }
938938
}
939939
#[ignore(reason = "linked failure")]
940-
#[test] #[ignore(cfg(windows))]
940+
#[test]
941941
fn test_mutex_killed_cond() {
942942
// Getting killed during cond wait must not corrupt the mutex while
943943
// unwinding (e.g. double unlock).
@@ -964,7 +964,7 @@ mod tests {
964964
}
965965
}
966966
#[ignore(reason = "linked failure")]
967-
#[test] #[ignore(cfg(windows))]
967+
#[test]
968968
fn test_mutex_killed_broadcast() {
969969
use std::unstable::finally::Finally;
970970

@@ -1024,7 +1024,7 @@ mod tests {
10241024
cond.wait();
10251025
}
10261026
}
1027-
#[test] #[ignore(cfg(windows))]
1027+
#[test]
10281028
fn test_mutex_different_conds() {
10291029
let result = do task::try {
10301030
let m = ~Mutex::new_with_condvars(2);
@@ -1045,7 +1045,7 @@ mod tests {
10451045
};
10461046
assert!(result.is_err());
10471047
}
1048-
#[test] #[ignore(cfg(windows))]
1048+
#[test]
10491049
fn test_mutex_no_condvars() {
10501050
let result = do task::try {
10511051
let m = ~Mutex::new_with_condvars(0);
@@ -1275,7 +1275,7 @@ mod tests {
12751275
test_rwlock_cond_broadcast_helper(12, false, true);
12761276
test_rwlock_cond_broadcast_helper(12, false, false);
12771277
}
1278-
#[cfg(test)] #[ignore(cfg(windows))]
1278+
#[cfg(test)]
12791279
fn rwlock_kill_helper(mode1: RWLockMode, mode2: RWLockMode) {
12801280
// Mutex must get automatically unlocked if failed/killed within.
12811281
let x = ~RWLock::new();
@@ -1290,23 +1290,23 @@ mod tests {
12901290
// child task must have finished by the time try returns
12911291
do lock_rwlock_in_mode(x, mode2) { }
12921292
}
1293-
#[test] #[ignore(cfg(windows))]
1293+
#[test]
12941294
fn test_rwlock_reader_killed_writer() {
12951295
rwlock_kill_helper(Read, Write);
12961296
}
1297-
#[test] #[ignore(cfg(windows))]
1297+
#[test]
12981298
fn test_rwlock_writer_killed_reader() {
12991299
rwlock_kill_helper(Write,Read );
13001300
}
1301-
#[test] #[ignore(cfg(windows))]
1301+
#[test]
13021302
fn test_rwlock_reader_killed_reader() {
13031303
rwlock_kill_helper(Read, Read );
13041304
}
1305-
#[test] #[ignore(cfg(windows))]
1305+
#[test]
13061306
fn test_rwlock_writer_killed_writer() {
13071307
rwlock_kill_helper(Write,Write);
13081308
}
1309-
#[test] #[ignore(cfg(windows))]
1309+
#[test]
13101310
fn test_rwlock_kill_downgrader() {
13111311
rwlock_kill_helper(Downgrade, Read);
13121312
rwlock_kill_helper(Read, Downgrade);
@@ -1321,7 +1321,7 @@ mod tests {
13211321
rwlock_kill_helper(Downgrade, DowngradeRead);
13221322
rwlock_kill_helper(Downgrade, DowngradeRead);
13231323
}
1324-
#[test] #[should_fail] #[ignore(cfg(windows))]
1324+
#[test] #[should_fail]
13251325
fn test_rwlock_downgrade_cant_swap() {
13261326
// Tests that you can't downgrade with a different rwlock's token.
13271327
let x = ~RWLock::new();

src/libextra/test.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1163,7 +1163,6 @@ mod tests {
11631163
}
11641164

11651165
#[test]
1166-
#[ignore(cfg(windows))]
11671166
fn test_should_fail() {
11681167
fn f() { fail!(); }
11691168
let desc = TestDescAndFn {

src/librustc/back/link.rs

+19-22
Original file line numberDiff line numberDiff line change
@@ -419,16 +419,8 @@ pub mod write {
419419
}
420420
}
421421

422-
pub fn run_ndk(sess: Session, assembly: &Path, object: &Path) {
423-
let cc_prog: ~str = match &sess.opts.android_cross_path {
424-
&Some(ref path) => {
425-
fmt!("%s/bin/arm-linux-androideabi-gcc", *path)
426-
}
427-
&None => {
428-
sess.fatal("need Android NDK path for building \
429-
(--android-cross-path)")
430-
}
431-
};
422+
pub fn run_assembler(sess: Session, assembly: &Path, object: &Path) {
423+
let cc_prog = super::get_cc_prog(sess);
432424

433425
let cc_args = ~[
434426
~"-c",
@@ -813,18 +805,14 @@ pub fn output_dll_filename(os: session::os, lm: LinkMeta) -> ~str {
813805
fmt!("%s%s-%s-%s%s", dll_prefix, lm.name, lm.extras_hash, lm.vers, dll_suffix)
814806
}
815807

816-
// If the user wants an exe generated we need to invoke
817-
// cc to link the object file with some libs
818-
pub fn link_binary(sess: Session,
819-
obj_filename: &Path,
820-
out_filename: &Path,
821-
lm: LinkMeta) {
808+
pub fn get_cc_prog(sess: Session) -> ~str {
822809
// In the future, FreeBSD will use clang as default compiler.
823810
// It would be flexible to use cc (system's default C compiler)
824811
// instead of hard-coded gcc.
825-
// For win32, there is no cc command,
826-
// so we add a condition to make it use gcc.
827-
let cc_prog: ~str = match sess.opts.linker {
812+
// For win32, there is no cc command, so we add a condition to make it use g++.
813+
// We use g++ rather than gcc because it automatically adds linker options required
814+
// for generation of dll modules that correctly register stack unwind tables.
815+
match sess.opts.linker {
828816
Some(ref linker) => linker.to_str(),
829817
None => match sess.targ_cfg.os {
830818
session::os_android =>
@@ -837,12 +825,21 @@ pub fn link_binary(sess: Session,
837825
(--android-cross-path)")
838826
}
839827
},
840-
session::os_win32 => ~"gcc",
828+
session::os_win32 => ~"g++",
841829
_ => ~"cc"
842830
}
843-
};
844-
// The invocations of cc share some flags across platforms
831+
}
832+
}
833+
834+
// If the user wants an exe generated we need to invoke
835+
// cc to link the object file with some libs
836+
pub fn link_binary(sess: Session,
837+
obj_filename: &Path,
838+
out_filename: &Path,
839+
lm: LinkMeta) {
845840

841+
let cc_prog = get_cc_prog(sess);
842+
// The invocations of cc share some flags across platforms
846843

847844
let output = if *sess.building_library {
848845
let long_libname = output_dll_filename(sess.targ_cfg.os, lm);

src/librustc/driver/driver.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -333,21 +333,31 @@ pub fn phase_5_run_llvm_passes(sess: Session,
333333
trans: &CrateTranslation,
334334
outputs: &OutputFilenames) {
335335

336-
// NB: Android hack
337-
if sess.targ_cfg.os == session::os_android &&
336+
// On Windows, LLVM integrated assembler emits bad stack unwind tables when
337+
// segmented stacks are enabled. However, unwind info directives in assembly
338+
// output are OK, so we generate assembly first and then run it through
339+
// an external assembler.
340+
// Same for Android.
341+
if (sess.targ_cfg.os == session::os_android ||
342+
sess.targ_cfg.os == session::os_win32) &&
338343
(sess.opts.output_type == link::output_type_object ||
339344
sess.opts.output_type == link::output_type_exe) {
340345
let output_type = link::output_type_assembly;
341-
let obj_filename = outputs.obj_filename.with_filetype("s");
346+
let asm_filename = outputs.obj_filename.with_filetype("s");
342347

343348
time(sess.time_passes(), ~"LLVM passes", ||
344349
link::write::run_passes(sess,
345350
trans.context,
346351
trans.module,
347352
output_type,
348-
&obj_filename));
353+
&asm_filename));
349354

350-
link::write::run_ndk(sess, &obj_filename, &outputs.obj_filename);
355+
link::write::run_assembler(sess, &asm_filename, &outputs.obj_filename);
356+
357+
// Remove assembly source unless --save-temps was specified
358+
if !sess.opts.save_temps {
359+
os::remove_file(&asm_filename);
360+
}
351361
} else {
352362
time(sess.time_passes(), ~"LLVM passes", ||
353363
link::write::run_passes(sess,

src/libstd/c_str.rs

-2
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,6 @@ mod tests {
283283

284284
#[test]
285285
#[should_fail]
286-
#[ignore(cfg(windows))]
287286
fn test_with_ref_empty_fail() {
288287
let c_str = unsafe { CString::new(ptr::null(), false) };
289288
c_str.with_ref(|_| ());
@@ -306,7 +305,6 @@ mod tests {
306305
}
307306

308307
#[test]
309-
#[ignore(cfg(windows))]
310308
fn test_to_c_str_fail() {
311309
use c_str::null_byte::cond;
312310

src/libstd/cell.rs

-2
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,13 @@ fn test_basic() {
9393

9494
#[test]
9595
#[should_fail]
96-
#[ignore(cfg(windows))]
9796
fn test_take_empty() {
9897
let value_cell = Cell::new_empty::<~int>();
9998
value_cell.take();
10099
}
101100

102101
#[test]
103102
#[should_fail]
104-
#[ignore(cfg(windows))]
105103
fn test_put_back_non_empty() {
106104
let value_cell = Cell::new(~10);
107105
value_cell.put_back(~20);

src/libstd/io.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2017,7 +2017,6 @@ mod tests {
20172017
20182018
#[test]
20192019
#[should_fail]
2020-
#[ignore(cfg(windows))]
20212020
fn test_read_buffer_too_small() {
20222021
let path = &Path("tmp/lib-io-test-read-buffer-too-small.tmp");
20232022
// ensure the file exists

0 commit comments

Comments
 (0)