add tests for separate compilation

This commit is contained in:
Stuart Pernsteiner 2014-08-01 15:45:24 -07:00
parent 73f8adcbc8
commit 4b70269854
18 changed files with 502 additions and 0 deletions

View File

@ -0,0 +1,14 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[no_mangle]
pub extern "C" fn foo() -> uint {
1234
}

View File

@ -0,0 +1,17 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[inline]
pub fn cci_fn() -> uint {
1200
}
#[inline]
pub static CCI_STATIC: uint = 34;

View File

@ -0,0 +1,31 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -C codegen-units=3 --crate-type=rlib,dylib
pub mod a {
pub fn one() -> uint {
1
}
}
pub mod b {
pub fn two() -> uint {
2
}
}
pub mod c {
use a::one;
use b::two;
pub fn three() -> uint {
one() + two()
}
}

View File

@ -0,0 +1,28 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Make sure we give a sane error message when the user requests LTO with a
// library built with -C codegen-units > 1.
// aux-build:sepcomp_lib.rs
// compile-flags: -Z lto
// error-pattern:missing compressed bytecode
// no-prefer-dynamic
extern crate sepcomp_lib;
use sepcomp_lib::a::one;
use sepcomp_lib::b::two;
use sepcomp_lib::c::three;
fn main() {
assert_eq!(one(), 1);
assert_eq!(two(), 2);
assert_eq!(three(), 3);
}

View File

@ -0,0 +1,10 @@
-include ../tools.mk
# Check that cross-crate inlined items are inlined in all compilation units
# that refer to them, and not in any other compilation units.
all:
$(RUSTC) cci_lib.rs
$(RUSTC) foo.rs --emit=ir -C codegen-units=3
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ .*cci_fn)" -eq "2" ]
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c CCI_STATIC.*=.*constant)" -eq "2" ]

View File

@ -0,0 +1,19 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![crate_type = "rlib"]
#[inline]
pub fn cci_fn() -> uint {
1234
}
#[inline]
pub static CCI_STATIC: uint = 2345;

View File

@ -0,0 +1,36 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern crate cci_lib;
use cci_lib::{cci_fn, CCI_STATIC};
fn call1() -> uint {
cci_fn() + CCI_STATIC
}
mod a {
use cci_lib::cci_fn;
pub fn call2() -> uint {
cci_fn()
}
}
mod b {
use cci_lib::CCI_STATIC;
pub fn call3() -> uint {
CCI_STATIC
}
}
fn main() {
call1();
a::call2();
b::call3();
}

View File

@ -0,0 +1,13 @@
-include ../tools.mk
# Test that #[inline(always)] functions still get inlined across compilation
# unit boundaries. Compilation should produce three IR files, with each one
# containing a definition of the inlined function. Also, the non-#[inline]
# function should be defined in only one compilation unit.
all:
$(RUSTC) foo.rs --emit=ir -C codegen-units=3
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ i32\ .*inlined)" -eq "1" ]
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ available_externally\ i32\ .*inlined)" -eq "2" ]
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ i32\ .*normal)" -eq "1" ]
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c declare\ i32\ .*normal)" -eq "2" ]

View File

@ -0,0 +1,35 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[inline]
fn inlined() -> u32 {
1234
}
fn normal() -> u32 {
2345
}
mod a {
pub fn f() -> u32 {
::inlined() + ::normal()
}
}
mod b {
pub fn f() -> u32 {
::inlined() + ::normal()
}
}
fn main() {
a::f();
b::f();
}

View File

@ -0,0 +1,9 @@
-include ../tools.mk
# Test that separate compilation actually puts code into separate compilation
# units. `foo.rs` defines `magic_fn` in three different modules, which should
# wind up in three different compilation units.
all:
$(RUSTC) foo.rs --emit=ir -C codegen-units=3
[ "$$(cat "$(TMPDIR)"/foo.?.ll | grep -c define\ .*magic_fn)" -eq "3" ]

View File

@ -0,0 +1,27 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn magic_fn() -> uint {
1234
}
mod a {
pub fn magic_fn() -> uint {
2345
}
}
mod b {
pub fn magic_fn() -> uint {
3456
}
}
fn main() { }

View File

@ -0,0 +1,41 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -C codegen-units=3
// aux-build:sepcomp_cci_lib.rs
// Test accessing cross-crate inlined items from multiple compilation units.
extern crate sepcomp_cci_lib;
use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
fn call1() -> uint {
cci_fn() + CCI_STATIC
}
mod a {
use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
pub fn call2() -> uint {
cci_fn() + CCI_STATIC
}
}
mod b {
use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
pub fn call3() -> uint {
cci_fn() + CCI_STATIC
}
}
fn main() {
assert_eq!(call1(), 1234);
assert_eq!(a::call2(), 1234);
assert_eq!(b::call3(), 1234);
}

View File

@ -0,0 +1,42 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -C codegen-units=3
// aux-build:sepcomp-extern-lib.rs
// Test accessing external items from multiple compilation units.
#[link(name = "sepcomp-extern-lib")]
extern {
#[allow(ctypes)]
fn foo() -> uint;
}
fn call1() -> uint {
unsafe { foo() }
}
mod a {
pub fn call2() -> uint {
unsafe { ::foo() }
}
}
mod b {
pub fn call3() -> uint {
unsafe { ::foo() }
}
}
fn main() {
assert_eq!(call1(), 1234);
assert_eq!(a::call2(), 1234);
assert_eq!(b::call3(), 1234);
}

View File

@ -0,0 +1,41 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -C codegen-units=3
// Test references to items that haven't been translated yet.
// Generate some code in the first compilation unit before declaring any
// modules. This ensures that the first module doesn't go into the same
// compilation unit as the top-level module.
fn pad() -> uint { 0 }
mod b {
pub fn three() -> uint {
::one() + ::a::two()
}
}
mod a {
pub fn two() -> uint {
::one() + ::one()
}
}
fn one() -> uint {
1
}
fn main() {
assert_eq!(one(), 1);
assert_eq!(a::two(), 2);
assert_eq!(b::three(), 3);
}

View File

@ -0,0 +1,38 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -C codegen-units=3
// Test basic separate compilation functionality. The functions should be able
// to call each other even though they will be placed in different compilation
// units.
// Generate some code in the first compilation unit before declaring any
// modules. This ensures that the first module doesn't go into the same
// compilation unit as the top-level module.
fn one() -> uint { 1 }
mod a {
pub fn two() -> uint {
::one() + ::one()
}
}
mod b {
pub fn three() -> uint {
::one() + ::a::two()
}
}
fn main() {
assert_eq!(one(), 1);
assert_eq!(a::two(), 2);
assert_eq!(b::three(), 3);
}

View File

@ -0,0 +1,24 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:sepcomp_lib.rs
// Test linking against a library built with -C codegen-units > 1
extern crate sepcomp_lib;
use sepcomp_lib::a::one;
use sepcomp_lib::b::two;
use sepcomp_lib::c::three;
fn main() {
assert_eq!(one(), 1);
assert_eq!(two(), 2);
assert_eq!(three(), 3);
}

View File

@ -0,0 +1,39 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -C codegen-units=3
// Test references to static items across compilation units.
fn pad() -> uint { 0 }
static ONE: uint = 1;
mod b {
// Separate compilation always switches to the LLVM module with the fewest
// instructions. Make sure we have some instructions in this module so
// that `a` and `b` don't go into the same compilation unit.
fn pad() -> uint { 0 }
pub static THREE: uint = ::ONE + ::a::TWO;
}
mod a {
fn pad() -> uint { 0 }
pub static TWO: uint = ::ONE + ::ONE;
}
fn main() {
assert_eq!(ONE, 1);
assert_eq!(a::TWO, 2);
assert_eq!(b::THREE, 3);
}

View File

@ -0,0 +1,38 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -C codegen-units=3
// Test unwinding through multiple compilation units.
// According to acrichto, in the distant past `ld -r` (which is used during
// linking when codegen-units > 1) was known to produce object files with
// damaged unwinding tables. This may be related to GNU binutils bug #6893
// ("Partial linking results in corrupt .eh_frame_hdr"), but I'm not certain.
// In any case, this test should let us know if enabling parallel codegen ever
// breaks unwinding.
fn pad() -> uint { 0 }
mod a {
pub fn f() {
fail!();
}
}
mod b {
pub fn g() {
::a::f();
}
}
fn main() {
std::task::try(proc() { ::b::g() }).unwrap_err();
}