Move almost all run-make-fulldeps to run-make

They pass fine.
This commit is contained in:
Joshua Nelson 2023-03-30 07:34:55 -05:00
parent f2d9a3d077
commit 433da1fc04
696 changed files with 2 additions and 2 deletions

View file

@ -0,0 +1,15 @@
include ../tools.mk
# Test that if we build `b` against a version of `a` that has one set
# of types, it will not run with a dylib that has a different set of
# types.
# NOTE(eddyb) this test only works with the `legacy` mangling,
# and will probably get removed once `legacy` is gone.
all:
$(RUSTC) a.rs --cfg x -C prefer-dynamic -Z unstable-options -C symbol-mangling-version=legacy
$(RUSTC) b.rs -C prefer-dynamic -Z unstable-options -C symbol-mangling-version=legacy
$(call RUN,b)
$(RUSTC) a.rs --cfg y -C prefer-dynamic -Z unstable-options -C symbol-mangling-version=legacy
$(call FAIL,b)

View file

@ -0,0 +1,8 @@
#![crate_name = "a"]
#![crate_type = "dylib"]
#[cfg(x)]
pub fn foo(x: u32) { }
#[cfg(y)]
pub fn foo(x: i32) { }

View file

@ -0,0 +1,7 @@
#![crate_name = "b"]
extern crate a;
fn main() {
a::foo(22_u32);
}

View file

@ -0,0 +1,4 @@
include ../tools.mk
all:
$(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../library/alloc/src/lib.rs --cfg no_global_oom_handling

View file

@ -0,0 +1,4 @@
include ../tools.mk
all:
$(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../library/alloc/src/lib.rs --cfg no_rc

View file

@ -0,0 +1,4 @@
include ../tools.mk
all:
$(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../library/alloc/src/lib.rs --cfg no_sync

View file

@ -0,0 +1,11 @@
include ../tools.mk
# Test that -A warnings makes the 'empty trait list for derive' warning go away
OUT=$(shell $(RUSTC) foo.rs -A warnings 2>&1 | grep "warning" )
all: foo
test -z '$(OUT)'
# This is just to make sure the above command actually succeeds
foo:
$(RUSTC) foo.rs -A warnings

View file

@ -0,0 +1,5 @@
#[derive()]
#[derive(Copy, Clone)]
pub struct Foo;
pub fn main() { }

View file

@ -0,0 +1,15 @@
include ../tools.mk
# Test that -A warnings makes the 'empty trait list for derive' warning go away
DEP=$(shell $(RUSTC) bar.rs)
OUT=$(shell $(RUSTC) foo.rs -A warnings 2>&1 | grep "warning" )
all: foo bar
test -z '$(OUT)'
# These are just to ensure that the above commands actually work
bar:
$(RUSTC) bar.rs
foo: bar
$(RUSTC) foo.rs -A warnings

View file

@ -0,0 +1,5 @@
#![crate_type = "lib"]
#![feature(staged_api)]
#![unstable(feature = "unstable_test_feature", issue = "none")]
pub fn baz() {}

View file

@ -0,0 +1,5 @@
#![feature(unstable_test_feature)]
extern crate bar;
pub fn main() { bar::baz() }

View file

@ -0,0 +1,11 @@
include ../tools.mk
all:
mkdir $(TMPDIR)/a
mkdir $(TMPDIR)/b
$(call COMPILE_OBJ,$(TMPDIR)/a/foo.o,foo.c)
$(call COMPILE_OBJ,$(TMPDIR)/b/foo.o,bar.c)
$(AR) crus $(TMPDIR)/libfoo.a $(TMPDIR)/a/foo.o $(TMPDIR)/b/foo.o
$(RUSTC) foo.rs
$(RUSTC) bar.rs
$(call RUN,bar)

View file

@ -0,0 +1 @@
void bar() {}

View file

@ -0,0 +1,5 @@
extern crate foo;
fn main() {
foo::baz();
}

View file

@ -0,0 +1 @@
void foo() {}

View file

@ -0,0 +1,14 @@
#![crate_type = "rlib"]
#[link(name = "foo", kind = "static")]
extern "C" {
fn foo();
fn bar();
}
pub fn baz() {
unsafe {
foo();
bar();
}
}

View file

@ -0,0 +1,7 @@
include ../tools.mk
all:
$(RUSTC) --crate-type=staticlib nonclike.rs
$(CC) test.c $(call STATICLIB,nonclike) $(call OUT_EXE,test) \
$(EXTRACFLAGS) $(EXTRACXXFLAGS)
$(call RUN,test)

View file

@ -0,0 +1,31 @@
#[repr(C, u8)]
pub enum TT {
AA(u64, u64),
BB,
}
#[no_mangle]
pub extern "C" fn tt_add(a: TT, b: TT) -> u64 {
match (a, b) {
(TT::AA(a1, b1), TT::AA(a2, b2)) => a1 + a2 + b1 + b2,
(TT::AA(a1, b1), TT::BB) => a1 + b1,
(TT::BB, TT::AA(a1, b1)) => a1 + b1,
_ => 0,
}
}
#[repr(C, u8)]
pub enum T {
A(u64),
B,
}
#[no_mangle]
pub extern "C" fn t_add(a: T, b: T) -> u64 {
match (a, b) {
(T::A(a), T::A(b)) => a + b,
(T::A(a), T::B) => a,
(T::B, T::A(b)) => b,
_ => 0,
}
}

View file

@ -0,0 +1,66 @@
#include <stdint.h>
#include <assert.h>
#include <stdio.h>
/* This is the code generated by cbindgen 0.12.1 for the `enum TT`
* type in nonclike.rs . */
enum TT_Tag {
AA,
BB,
};
typedef uint8_t TT_Tag;
typedef struct {
uint64_t _0;
uint64_t _1;
} AA_Body;
typedef struct {
TT_Tag tag;
union {
AA_Body aa;
};
} TT;
/* This is the code generated by cbindgen 0.12.1 for the `enum T` type
* in nonclike.rs . */
enum T_Tag {
A,
B,
};
typedef uint8_t T_Tag;
typedef struct {
uint64_t _0;
} A_Body;
typedef struct {
T_Tag tag;
union {
A_Body a;
};
} T;
/* These symbols are defined by the Rust staticlib built from
* nonclike.rs. */
extern uint64_t t_add(T a, T b);
extern uint64_t tt_add(TT a, TT b);
int main(int argc, char *argv[]) {
(void)argc; (void)argv;
/* This example works. */
TT xx = { .tag = AA, .aa = { ._0 = 1, ._1 = 2 } };
TT yy = { .tag = AA, .aa = { ._0 = 10, ._1 = 20 } };
uint64_t rr = tt_add(xx, yy);
assert(33 == rr);
/* This one used to return an incorrect result (see issue #68190). */
T x = { .tag = A, .a = { ._0 = 1 } };
T y = { .tag = A, .a = { ._0 = 10 } };
uint64_t r = t_add(x, y);
assert(11 == r);
return 0;
}

View file

@ -0,0 +1,48 @@
include ../tools.mk
# This tests ensure that atomic types are never lowered into runtime library calls that are not
# guaranteed to be lock-free.
all:
ifeq ($(UNAME),Linux)
ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86)
$(RUSTC) --target=i686-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=x86_64-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
endif
ifeq ($(filter arm,$(LLVM_COMPONENTS)),arm)
$(RUSTC) --target=arm-unknown-linux-gnueabi atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=arm-unknown-linux-gnueabihf atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=armv7-unknown-linux-gnueabihf atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=thumbv7neon-unknown-linux-gnueabihf atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
endif
ifeq ($(filter aarch64,$(LLVM_COMPONENTS)),aarch64)
$(RUSTC) --target=aarch64-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
endif
ifeq ($(filter mips,$(LLVM_COMPONENTS)),mips)
$(RUSTC) --target=mips-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=mipsel-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
endif
ifeq ($(filter powerpc,$(LLVM_COMPONENTS)),powerpc)
$(RUSTC) --target=powerpc-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=powerpc-unknown-linux-gnuspe atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=powerpc64-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=powerpc64le-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
endif
ifeq ($(filter systemz,$(LLVM_COMPONENTS)),systemz)
$(RUSTC) --target=s390x-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
endif
endif

View file

@ -0,0 +1,66 @@
#![feature(no_core, intrinsics, lang_items)]
#![crate_type="rlib"]
#![no_core]
extern "rust-intrinsic" {
fn atomic_xadd_seqcst<T>(dst: *mut T, src: T) -> T;
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
#[lang = "freeze"]
trait Freeze {}
impl<T: ?Sized> Copy for *mut T {}
#[cfg(target_has_atomic = "8")]
pub unsafe fn atomic_u8(x: *mut u8) {
atomic_xadd_seqcst(x, 1);
atomic_xadd_seqcst(x, 1);
}
#[cfg(target_has_atomic = "8")]
pub unsafe fn atomic_i8(x: *mut i8) {
atomic_xadd_seqcst(x, 1);
}
#[cfg(target_has_atomic = "16")]
pub unsafe fn atomic_u16(x: *mut u16) {
atomic_xadd_seqcst(x, 1);
}
#[cfg(target_has_atomic = "16")]
pub unsafe fn atomic_i16(x: *mut i16) {
atomic_xadd_seqcst(x, 1);
}
#[cfg(target_has_atomic = "32")]
pub unsafe fn atomic_u32(x: *mut u32) {
atomic_xadd_seqcst(x, 1);
}
#[cfg(target_has_atomic = "32")]
pub unsafe fn atomic_i32(x: *mut i32) {
atomic_xadd_seqcst(x, 1);
}
#[cfg(target_has_atomic = "64")]
pub unsafe fn atomic_u64(x: *mut u64) {
atomic_xadd_seqcst(x, 1);
}
#[cfg(target_has_atomic = "64")]
pub unsafe fn atomic_i64(x: *mut i64) {
atomic_xadd_seqcst(x, 1);
}
#[cfg(target_has_atomic = "128")]
pub unsafe fn atomic_u128(x: *mut u128) {
atomic_xadd_seqcst(x, 1);
}
#[cfg(target_has_atomic = "128")]
pub unsafe fn atomic_i128(x: *mut i128) {
atomic_xadd_seqcst(x, 1);
}
#[cfg(target_has_atomic = "ptr")]
pub unsafe fn atomic_usize(x: *mut usize) {
atomic_xadd_seqcst(x, 1);
}
#[cfg(target_has_atomic = "ptr")]
pub unsafe fn atomic_isize(x: *mut isize) {
atomic_xadd_seqcst(x, 1);
}

View file

@ -0,0 +1,6 @@
include ../tools.mk
all:
cp foo.rs $(TMPDIR)
cd $(TMPDIR) && $(RUSTC) -o foo foo.rs
$(call RUN,foo)

View file

@ -0,0 +1,2 @@
fn main() {
}

View file

@ -0,0 +1,12 @@
include ../tools.mk
# ignore-macos
#
# This hits an assertion in the linker on older versions of osx apparently
all: $(call DYLIB,cfoo)
$(RUSTC) foo.rs -C prefer-dynamic
$(RUSTC) bar.rs
$(call RUN,bar)
$(call REMOVE_DYLIBS,cfoo)
$(call FAIL,bar)

View file

@ -0,0 +1,5 @@
extern crate foo;
fn main() {
foo::rsfoo();
}

View file

@ -0,0 +1,4 @@
#ifdef _WIN32
__declspec(dllexport)
#endif
int foo() { return 0; }

View file

@ -0,0 +1,10 @@
#![crate_type = "dylib"]
#[link(name = "cfoo")]
extern "C" {
fn foo();
}
pub fn rsfoo() {
unsafe { foo() }
}

View file

@ -0,0 +1,15 @@
include ../tools.mk
# ignore-macos
#
# This hits an assertion in the linker on older versions of osx apparently
# This overrides the LD_LIBRARY_PATH for RUN
TARGET_RPATH_DIR:=$(TARGET_RPATH_DIR):$(TMPDIR)
all: $(call DYLIB,cfoo)
$(RUSTC) foo.rs
$(RUSTC) bar.rs
$(call RUN,bar)
$(call REMOVE_DYLIBS,cfoo)
$(call FAIL,bar)

View file

@ -0,0 +1,5 @@
extern crate foo;
fn main() {
foo::rsfoo();
}

View file

@ -0,0 +1,4 @@
#ifdef _WIN32
__declspec(dllexport)
#endif
int foo() { return 0; }

View file

@ -0,0 +1,10 @@
#![crate_type = "rlib"]
#[link(name = "cfoo")]
extern "C" {
fn foo();
}
pub fn rsfoo() {
unsafe { foo() }
}

View file

@ -0,0 +1,17 @@
include ../tools.mk
all: $(TMPDIR)/$(call BIN,bar)
$(call RUN,bar)
$(call REMOVE_DYLIBS,foo)
$(call FAIL,bar)
ifdef IS_MSVC
$(TMPDIR)/$(call BIN,bar): $(call DYLIB,foo)
$(CC) bar.c $(TMPDIR)/foo.dll.lib $(call OUT_EXE,bar)
else
$(TMPDIR)/$(call BIN,bar): $(call DYLIB,foo)
$(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) -L $(TMPDIR)
endif
$(call DYLIB,foo): foo.rs
$(RUSTC) foo.rs

View file

@ -0,0 +1,6 @@
void foo();
int main() {
foo();
return 0;
}

View file

@ -0,0 +1,4 @@
#![crate_type = "dylib"]
#[no_mangle]
pub extern "C" fn foo() {}

View file

@ -0,0 +1,12 @@
include ../tools.mk
# ignore-freebsd
# FIXME
all:
$(RUSTC) foo.rs
$(CC) bar.c $(call STATICLIB,foo) $(call OUT_EXE,bar) \
$(EXTRACFLAGS) $(EXTRACXXFLAGS)
$(call RUN,bar)
rm $(call STATICLIB,foo)
$(call RUN,bar)

View file

@ -0,0 +1,6 @@
void foo();
int main() {
foo();
return 0;
}

View file

@ -0,0 +1,4 @@
#![crate_type = "staticlib"]
#[no_mangle]
pub extern "C" fn foo() {}

View file

@ -0,0 +1,6 @@
include ../tools.mk
all:
$(RUSTC) checkrust.rs
$(CC) test.c $(call STATICLIB,checkrust) $(call OUT_EXE,test) $(EXTRACFLAGS)
$(call RUN,test)

View file

@ -0,0 +1,148 @@
#![crate_type = "staticlib"]
#![feature(c_variadic)]
#![feature(rustc_private)]
extern crate libc;
use libc::{c_char, c_double, c_int, c_long, c_longlong};
use std::ffi::VaList;
use std::ffi::{CString, CStr};
macro_rules! continue_if {
($cond:expr) => {
if !($cond) {
return 0xff;
}
}
}
unsafe fn compare_c_str(ptr: *const c_char, val: &str) -> bool {
let cstr0 = CStr::from_ptr(ptr);
match CString::new(val) {
Ok(cstr1) => &*cstr1 == cstr0,
Err(_) => false,
}
}
#[no_mangle]
pub unsafe extern "C" fn check_list_0(mut ap: VaList) -> usize {
continue_if!(ap.arg::<c_longlong>() == 1);
continue_if!(ap.arg::<c_int>() == 2);
continue_if!(ap.arg::<c_longlong>() == 3);
0
}
#[no_mangle]
pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize {
continue_if!(ap.arg::<c_int>() == -1);
continue_if!(ap.arg::<c_char>() == 'A' as c_char);
continue_if!(ap.arg::<c_char>() == '4' as c_char);
continue_if!(ap.arg::<c_char>() == ';' as c_char);
continue_if!(ap.arg::<c_int>() == 0x32);
continue_if!(ap.arg::<c_int>() == 0x10000001);
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Valid!"));
0
}
#[no_mangle]
pub unsafe extern "C" fn check_list_2(mut ap: VaList) -> usize {
continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor());
continue_if!(ap.arg::<c_long>() == 12);
continue_if!(ap.arg::<c_char>() == 'a' as c_char);
continue_if!(ap.arg::<c_double>().floor() == 6.18f64.floor());
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello"));
continue_if!(ap.arg::<c_int>() == 42);
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "World"));
0
}
#[no_mangle]
pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize {
continue_if!(ap.arg::<c_double>().floor() == 6.28f64.floor());
continue_if!(ap.arg::<c_int>() == 16);
continue_if!(ap.arg::<c_char>() == 'A' as c_char);
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!"));
ap.with_copy(|mut ap| {
if compare_c_str(ap.arg::<*const c_char>(), "Correct") {
0
} else {
0xff
}
})
}
#[no_mangle]
pub unsafe extern "C" fn check_varargs_0(_: c_int, mut ap: ...) -> usize {
continue_if!(ap.arg::<c_int>() == 42);
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello, World!"));
0
}
#[no_mangle]
pub unsafe extern "C" fn check_varargs_1(_: c_int, mut ap: ...) -> usize {
continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor());
continue_if!(ap.arg::<c_long>() == 12);
continue_if!(ap.arg::<c_char>() == 'A' as c_char);
continue_if!(ap.arg::<c_longlong>() == 1);
0
}
#[no_mangle]
pub unsafe extern "C" fn check_varargs_2(_: c_int, _ap: ...) -> usize {
0
}
#[no_mangle]
pub unsafe extern "C" fn check_varargs_3(_: c_int, mut ap: ...) -> usize {
continue_if!(ap.arg::<c_int>() == 1);
continue_if!(ap.arg::<c_int>() == 2);
continue_if!(ap.arg::<c_int>() == 3);
continue_if!(ap.arg::<c_int>() == 4);
continue_if!(ap.arg::<c_int>() == 5);
continue_if!(ap.arg::<c_int>() == 6);
continue_if!(ap.arg::<c_int>() == 7);
continue_if!(ap.arg::<c_int>() == 8);
continue_if!(ap.arg::<c_int>() == 9);
continue_if!(ap.arg::<c_int>() == 10);
0
}
#[no_mangle]
pub unsafe extern "C" fn check_varargs_4(_: c_double, mut ap: ...) -> usize {
continue_if!(ap.arg::<c_double>() == 1.0);
continue_if!(ap.arg::<c_double>() == 2.0);
continue_if!(ap.arg::<c_double>() == 3.0);
continue_if!(ap.arg::<c_double>() == 4.0);
continue_if!(ap.arg::<c_double>() == 5.0);
continue_if!(ap.arg::<c_double>() == 6.0);
continue_if!(ap.arg::<c_double>() == 7.0);
continue_if!(ap.arg::<c_double>() == 8.0);
continue_if!(ap.arg::<c_double>() == 9.0);
continue_if!(ap.arg::<c_double>() == 10.0);
0
}
#[no_mangle]
pub unsafe extern "C" fn check_varargs_5(_: c_int, mut ap: ...) -> usize {
continue_if!(ap.arg::<c_double>() == 1.0);
continue_if!(ap.arg::<c_int>() == 1);
continue_if!(ap.arg::<c_double>() == 2.0);
continue_if!(ap.arg::<c_int>() == 2);
continue_if!(ap.arg::<c_double>() == 3.0);
continue_if!(ap.arg::<c_int>() == 3);
continue_if!(ap.arg::<c_double>() == 4.0);
continue_if!(ap.arg::<c_int>() == 4);
continue_if!(ap.arg::<c_int>() == 5);
continue_if!(ap.arg::<c_double>() == 5.0);
continue_if!(ap.arg::<c_int>() == 6);
continue_if!(ap.arg::<c_double>() == 6.0);
continue_if!(ap.arg::<c_int>() == 7);
continue_if!(ap.arg::<c_double>() == 7.0);
continue_if!(ap.arg::<c_int>() == 8);
continue_if!(ap.arg::<c_double>() == 8.0);
continue_if!(ap.arg::<c_int>() == 9);
continue_if!(ap.arg::<c_double>() == 9.0);
continue_if!(ap.arg::<c_int>() == 10);
continue_if!(ap.arg::<c_double>() == 10.0);
0
}

View file

@ -0,0 +1,50 @@
#include <stdarg.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
extern size_t check_list_0(va_list ap);
extern size_t check_list_1(va_list ap);
extern size_t check_list_2(va_list ap);
extern size_t check_list_copy_0(va_list ap);
extern size_t check_varargs_0(int fixed, ...);
extern size_t check_varargs_1(int fixed, ...);
extern size_t check_varargs_2(int fixed, ...);
extern size_t check_varargs_3(int fixed, ...);
extern size_t check_varargs_4(double fixed, ...);
extern size_t check_varargs_5(int fixed, ...);
int test_rust(size_t (*fn)(va_list), ...) {
size_t ret = 0;
va_list ap;
va_start(ap, fn);
ret = fn(ap);
va_end(ap);
return ret;
}
int main(int argc, char* argv[]) {
assert(test_rust(check_list_0, 0x01LL, 0x02, 0x03LL) == 0);
assert(test_rust(check_list_1, -1, 'A', '4', ';', 0x32, 0x10000001, "Valid!") == 0);
assert(test_rust(check_list_2, 3.14, 12l, 'a', 6.28, "Hello", 42, "World") == 0);
assert(test_rust(check_list_copy_0, 6.28, 16, 'A', "Skip Me!", "Correct") == 0);
assert(check_varargs_0(0, 42, "Hello, World!") == 0);
assert(check_varargs_1(0, 3.14, 12l, 'A', 0x1LL) == 0);
assert(check_varargs_2(0, "All", "of", "these", "are", "ignored", ".") == 0);
assert(check_varargs_3(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) == 0);
assert(check_varargs_4(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) == 0);
assert(check_varargs_5(0, 1.0, 1, 2.0, 2, 3.0, 3, 4.0, 4, 5, 5.0, 6, 6.0, 7, 7.0, 8, 8.0,
9, 9.0, 10, 10.0) == 0);
return 0;
}

View file

@ -0,0 +1,9 @@
include ../tools.mk
all: $(call NATIVE_STATICLIB,cfoo)
$(RUSTC) foo.rs -C prefer-dynamic
$(RUSTC) bar.rs
rm $(call NATIVE_STATICLIB,cfoo)
$(call RUN,bar)
$(call REMOVE_DYLIBS,foo)
$(call FAIL,bar)

View file

@ -0,0 +1,5 @@
extern crate foo;
fn main() {
foo::rsfoo();
}

View file

@ -0,0 +1 @@
int foo() { return 0; }

View file

@ -0,0 +1,10 @@
#![crate_type = "dylib"]
#[link(name = "cfoo", kind = "static")]
extern "C" {
fn foo();
}
pub fn rsfoo() {
unsafe { foo() }
}

View file

@ -0,0 +1,8 @@
include ../tools.mk
all: $(call NATIVE_STATICLIB,cfoo)
$(RUSTC) foo.rs
$(RUSTC) bar.rs
$(call REMOVE_RLIBS,foo)
rm $(call NATIVE_STATICLIB,cfoo)
$(call RUN,bar)

View file

@ -0,0 +1,5 @@
extern crate foo;
fn main() {
foo::rsfoo();
}

View file

@ -0,0 +1 @@
int foo() { return 0; }

View file

@ -0,0 +1,10 @@
#![crate_type = "rlib"]
#[link(name = "cfoo", kind = "static")]
extern "C" {
fn foo();
}
pub fn rsfoo() {
unsafe { foo() }
}

View file

@ -0,0 +1,30 @@
include ../tools.mk
all: archive
# Compile `main.rs`, which will link into our library, and run it.
$(RUSTC) main.rs
$(call RUN,main)
ifdef IS_MSVC
archive: add.o panic.o
# Now, create an archive using these two objects.
$(AR) crus $(TMPDIR)/add.lib $(TMPDIR)/add.o $(TMPDIR)/panic.o
else
archive: add.o panic.o
# Now, create an archive using these two objects.
$(AR) crus $(TMPDIR)/libadd.a $(TMPDIR)/add.o $(TMPDIR)/panic.o
endif
# Compile `panic.rs` into an object file.
#
# Note that we invoke `rustc` directly, so we may emit an object rather
# than an archive. We'll do that later.
panic.o:
$(BARE_RUSTC) $(RUSTFLAGS) \
--out-dir $(TMPDIR) \
--emit=obj panic.rs
# Compile `add.c` into an object file.
add.o:
$(call COMPILE_OBJ,$(TMPDIR)/add.o,add.c)

View file

@ -0,0 +1,12 @@
#ifdef _WIN32
__declspec(dllexport)
#endif
// An external function, defined in Rust.
extern void panic_if_greater_than_10(unsigned x);
unsigned add_small_numbers(unsigned a, unsigned b) {
unsigned c = a + b;
panic_if_greater_than_10(c);
return c;
}

View file

@ -0,0 +1,35 @@
//! A test for calling `C-unwind` functions across foreign function boundaries.
//!
//! This test triggers a panic in a Rust library that our foreign function invokes. This shows
//! that we can unwind through the C code in that library, and catch the underlying panic.
#![feature(c_unwind)]
use std::panic::{catch_unwind, AssertUnwindSafe};
fn main() {
// Call `add_small_numbers`, passing arguments that will NOT trigger a panic.
let (a, b) = (9, 1);
let c = unsafe { add_small_numbers(a, b) };
assert_eq!(c, 10);
// Call `add_small_numbers`, passing arguments that will trigger a panic, and catch it.
let caught_unwind = catch_unwind(AssertUnwindSafe(|| {
let (a, b) = (10, 1);
let _c = unsafe { add_small_numbers(a, b) };
unreachable!("should have unwound instead of returned");
}));
// Assert that we did indeed panic, then unwrap and downcast the panic into the sum.
assert!(caught_unwind.is_err());
let panic_obj = caught_unwind.unwrap_err();
let msg = panic_obj.downcast_ref::<String>().unwrap();
assert_eq!(msg, "11");
}
#[link(name = "add", kind = "static")]
extern "C-unwind" {
/// An external function, defined in C.
///
/// Returns the sum of two numbers, or panics if the sum is greater than 10.
fn add_small_numbers(a: u32, b: u32) -> u32;
}

View file

@ -0,0 +1,12 @@
#![crate_type = "staticlib"]
#![feature(c_unwind)]
/// This function will panic if `x` is greater than 10.
///
/// This function is called by `add_small_numbers`.
#[no_mangle]
pub extern "C-unwind" fn panic_if_greater_than_10(x: u32) {
if x > 10 {
panic!("{}", x); // That is too big!
}
}

View file

@ -0,0 +1,5 @@
include ../tools.mk
all: $(call NATIVE_STATICLIB,add)
$(RUSTC) main.rs
$(call RUN,main) || exit 1

View file

@ -0,0 +1,12 @@
#ifdef _WIN32
__declspec(dllexport)
#endif
// An external function, defined in Rust.
extern void panic_if_greater_than_10(unsigned x);
unsigned add_small_numbers(unsigned a, unsigned b) {
unsigned c = a + b;
panic_if_greater_than_10(c);
return c;
}

View file

@ -0,0 +1,44 @@
//! A test for calling `C-unwind` functions across foreign function boundaries.
//!
//! This test triggers a panic when calling a foreign function that calls *back* into Rust.
#![feature(c_unwind)]
use std::panic::{catch_unwind, AssertUnwindSafe};
fn main() {
// Call `add_small_numbers`, passing arguments that will NOT trigger a panic.
let (a, b) = (9, 1);
let c = unsafe { add_small_numbers(a, b) };
assert_eq!(c, 10);
// Call `add_small_numbers`, passing arguments that will trigger a panic, and catch it.
let caught_unwind = catch_unwind(AssertUnwindSafe(|| {
let (a, b) = (10, 1);
let _c = unsafe { add_small_numbers(a, b) };
unreachable!("should have unwound instead of returned");
}));
// Assert that we did indeed panic, then unwrap and downcast the panic into the sum.
assert!(caught_unwind.is_err());
let panic_obj = caught_unwind.unwrap_err();
let msg = panic_obj.downcast_ref::<String>().unwrap();
assert_eq!(msg, "11");
}
#[link(name = "add", kind = "static")]
extern "C-unwind" {
/// An external function, defined in C.
///
/// Returns the sum of two numbers, or panics if the sum is greater than 10.
fn add_small_numbers(a: u32, b: u32) -> u32;
}
/// This function will panic if `x` is greater than 10.
///
/// This function is called by `add_small_numbers`.
#[no_mangle]
pub extern "C-unwind" fn panic_if_greater_than_10(x: u32) {
if x > 10 {
panic!("{}", x); // That is too big!
}
}

View file

@ -0,0 +1,46 @@
include ../tools.mk
all:
echo a | $(CGREP) a
! echo b | $(CGREP) a
echo xyz | $(CGREP) x y z
! echo abc | $(CGREP) b c d
printf "x\ny\nz" | $(CGREP) x y z
echo AbCd | $(CGREP) -i a b C D
! echo AbCd | $(CGREP) a b C D
true | $(CGREP) -v nothing
! echo nothing | $(CGREP) -v nothing
! echo xyz | $(CGREP) -v w x y
! echo xyz | $(CGREP) -v x y z
echo xyz | $(CGREP) -v a b c
! echo 'foo bar baz' | $(CGREP) 'foo baz'
echo 'foo bar baz' | $(CGREP) foo baz
echo 'x a `b` c y z' | $(CGREP) 'a `b` c'
echo baaac | $(CGREP) -e 'ba*c'
echo bc | $(CGREP) -e 'ba*c'
! echo aaac | $(CGREP) -e 'ba*c'
echo aaa | $(CGREP) -e 'a+'
! echo bbb | $(CGREP) -e 'a+'
echo abc | $(CGREP) -e 'a|e|i|o|u'
! echo fgh | $(CGREP) -e 'a|e|i|o|u'
echo abc | $(CGREP) -e '[aeiou]'
! echo fgh | $(CGREP) -e '[aeiou]'
! echo abc | $(CGREP) -e '[^aeiou]{3}'
echo fgh | $(CGREP) -e '[^aeiou]{3}'
echo ab cd ef gh | $(CGREP) -e '\bcd\b'
! echo abcdefgh | $(CGREP) -e '\bcd\b'
echo xyz | $(CGREP) -e '...'
! echo xy | $(CGREP) -e '...'
! echo xyz | $(CGREP) -e '\.\.\.'
echo ... | $(CGREP) -e '\.\.\.'
echo foo bar baz | $(CGREP) -e 'foo.*baz'
! echo foo bar baz | $(CGREP) -ve 'foo.*baz'
! echo foo bar baz | $(CGREP) -e 'baz.*foo'
echo foo bar baz | $(CGREP) -ve 'baz.*foo'

View file

@ -0,0 +1,27 @@
include ../tools.mk
TARGET_SYSROOT := $(shell $(RUSTC) --print sysroot)/lib/rustlib/$(TARGET)/lib
ifdef IS_MSVC
LIBSTD := $(wildcard $(TARGET_SYSROOT)/libstd-*.dll.lib)
else
LIBSTD := $(wildcard $(TARGET_SYSROOT)/$(call DYLIB_GLOB,std))
STD := $(basename $(patsubst lib%,%, $(notdir $(LIBSTD))))
endif
all: $(call RUN_BINFILE,foo)
$(call RUN,foo)
ifdef IS_MSVC
CLIBS := $(TMPDIR)/foo.dll.lib $(TMPDIR)/bar.dll.lib $(LIBSTD)
$(call RUN_BINFILE,foo): $(call DYLIB,foo)
$(CC) $(CFLAGS) foo.c $(CLIBS) $(call OUT_EXE,foo)
else
CLIBS := -lfoo -lbar -l$(STD) -L $(TMPDIR) -L $(TARGET_SYSROOT)
$(call RUN_BINFILE,foo): $(call DYLIB,foo)
$(CC) $(CFLAGS) foo.c $(CLIBS) -o $(call RUN_BINFILE,foo)
endif
$(call DYLIB,foo):
$(RUSTC) -C prefer-dynamic bar.rs
$(RUSTC) foo.rs

View file

@ -0,0 +1,5 @@
#![crate_type = "dylib"]
pub fn bar() {
println!("hello!");
}

View file

@ -0,0 +1,10 @@
#include <assert.h>
extern void foo();
extern unsigned bar(unsigned a, unsigned b);
int main() {
foo();
assert(bar(1, 2) == 3);
return 0;
}

View file

@ -0,0 +1,13 @@
#![crate_type = "cdylib"]
extern crate bar;
#[no_mangle]
pub extern "C" fn foo() {
bar::bar();
}
#[no_mangle]
pub extern "C" fn bar(a: u32, b: u32) -> u32 {
a + b
}

View file

@ -0,0 +1,12 @@
# Test that allocator-related symbols don't show up as exported from a cdylib as
# they're internal to Rust and not part of the public ABI.
include ../tools.mk
# ignore-windows
# FIXME: The __rdl_ and __rust_ symbol still remains, no matter using MSVC or GNU
# See https://github.com/rust-lang/rust/pull/46207#issuecomment-347561753
all:
$(RUSTC) foo.rs
nm -g "$(call DYLIB,foo)" | $(CGREP) -v __rdl_ __rde_ __rg_ __rust_

View file

@ -0,0 +1,6 @@
#![crate_type = "cdylib"]
#[no_mangle]
pub extern "C" fn foo() -> u32 {
3
}

View file

@ -0,0 +1,19 @@
include ../tools.mk
all: $(call RUN_BINFILE,foo)
$(call RUN,foo)
rm $(call DYLIB,foo)
$(RUSTC) foo.rs -C lto
$(call RUN,foo)
ifdef IS_MSVC
$(call RUN_BINFILE,foo): $(call DYLIB,foo)
$(CC) $(CFLAGS) foo.c $(TMPDIR)/foo.dll.lib $(call OUT_EXE,foo)
else
$(call RUN_BINFILE,foo): $(call DYLIB,foo)
$(CC) $(CFLAGS) foo.c -lfoo -o $(call RUN_BINFILE,foo) -L $(TMPDIR)
endif
$(call DYLIB,foo):
$(RUSTC) bar.rs
$(RUSTC) foo.rs

View file

@ -0,0 +1,5 @@
#![crate_type = "rlib"]
pub fn bar() {
println!("hello!");
}

View file

@ -0,0 +1,10 @@
#include <assert.h>
extern void foo();
extern unsigned bar(unsigned a, unsigned b);
int main() {
foo();
assert(bar(1, 2) == 3);
return 0;
}

View file

@ -0,0 +1,13 @@
#![crate_type = "cdylib"]
extern crate bar;
#[no_mangle]
pub extern "C" fn foo() {
bar::bar();
}
#[no_mangle]
pub extern "C" fn bar(a: u32, b: u32) -> u32 {
a + b
}

View file

@ -0,0 +1,31 @@
include ../tools.mk
all:
#Option taking a number
$(RUSTC) -C codegen-units dummy.rs 2>&1 | \
$(CGREP) 'codegen option `codegen-units` requires a number'
$(RUSTC) -C codegen-units= dummy.rs 2>&1 | \
$(CGREP) 'incorrect value `` for codegen option `codegen-units` - a number was expected'
$(RUSTC) -C codegen-units=foo dummy.rs 2>&1 | \
$(CGREP) 'incorrect value `foo` for codegen option `codegen-units` - a number was expected'
$(RUSTC) -C codegen-units=1 dummy.rs
#Option taking a string
$(RUSTC) -C extra-filename dummy.rs 2>&1 | \
$(CGREP) 'codegen option `extra-filename` requires a string'
$(RUSTC) -C extra-filename= dummy.rs 2>&1
$(RUSTC) -C extra-filename=foo dummy.rs 2>&1
#Option taking no argument
$(RUSTC) -C lto= dummy.rs 2>&1 | \
$(CGREP) 'codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted'
$(RUSTC) -C lto=1 dummy.rs 2>&1 | \
$(CGREP) 'codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted'
$(RUSTC) -C lto=foo dummy.rs 2>&1 | \
$(CGREP) 'codegen option `lto` - either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted'
$(RUSTC) -C lto dummy.rs
# Should not link dead code...
$(RUSTC) --print link-args dummy.rs 2>&1 | \
$(CGREP) -e '--gc-sections|-z[^ ]* [^ ]*<ignore>|-dead_strip|/OPT:REF'
# ... unless you specifically ask to keep it
$(RUSTC) --print link-args -C link-dead-code dummy.rs 2>&1 | \
$(CGREP) -ve '--gc-sections|-z[^ ]* [^ ]*<ignore>|-dead_strip|/OPT:REF'

View file

@ -0,0 +1 @@
fn main() {}

View file

@ -0,0 +1,5 @@
include ../tools.mk
all:
echo 'fn main(){}' | $(RUSTC) -
$(call RUN,rust_out)

View file

@ -0,0 +1,8 @@
include ../tools.mk
all:
mkdir -p $(TMPDIR)/a $(TMPDIR)/b
$(RUSTC) a.rs && mv $(TMPDIR)/liba.rlib $(TMPDIR)/a
$(RUSTC) b.rs -L $(TMPDIR)/a && mv $(TMPDIR)/libb.rlib $(TMPDIR)/b
$(RUSTC) c.rs -L crate=$(TMPDIR)/b -L dependency=$(TMPDIR)/a \
&& exit 1 || exit 0

View file

@ -0,0 +1 @@
#![crate_type = "lib"]

View file

@ -0,0 +1,2 @@
#![crate_type = "lib"]
extern crate a;

View file

@ -0,0 +1,3 @@
#![crate_type = "lib"]
extern crate b;
extern crate a;

View file

@ -0,0 +1,38 @@
include ../tools.mk
all: $(TMPDIR)/libnative.a
mkdir -p $(TMPDIR)/crate
mkdir -p $(TMPDIR)/native
mv $(TMPDIR)/libnative.a $(TMPDIR)/native
$(RUSTC) a.rs
mv $(TMPDIR)/liba.rlib $(TMPDIR)/crate
$(RUSTC) b.rs -L native=$(TMPDIR)/crate && exit 1 || exit 0
$(RUSTC) b.rs -L dependency=$(TMPDIR)/crate && exit 1 || exit 0
$(RUSTC) b.rs -L crate=$(TMPDIR)/crate
$(RUSTC) b.rs -L all=$(TMPDIR)/crate
$(RUSTC) c.rs -L native=$(TMPDIR)/crate && exit 1 || exit 0
$(RUSTC) c.rs -L crate=$(TMPDIR)/crate && exit 1 || exit 0
$(RUSTC) c.rs -L dependency=$(TMPDIR)/crate
$(RUSTC) c.rs -L all=$(TMPDIR)/crate
$(RUSTC) d.rs -L dependency=$(TMPDIR)/native && exit 1 || exit 0
$(RUSTC) d.rs -L crate=$(TMPDIR)/native && exit 1 || exit 0
$(RUSTC) d.rs -L native=$(TMPDIR)/native
$(RUSTC) d.rs -L all=$(TMPDIR)/native
# Deduplication tests:
# Same hash, no errors.
mkdir -p $(TMPDIR)/e1
mkdir -p $(TMPDIR)/e2
$(RUSTC) e.rs -o $(TMPDIR)/e1/libe.rlib
$(RUSTC) e.rs -o $(TMPDIR)/e2/libe.rlib
$(RUSTC) f.rs -L $(TMPDIR)/e1 -L $(TMPDIR)/e2
$(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L $(TMPDIR)/e2
$(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L crate=$(TMPDIR)/e2
# Different hash, errors.
$(RUSTC) e2.rs -o $(TMPDIR)/e2/libe.rlib
$(RUSTC) f.rs -L $(TMPDIR)/e1 -L $(TMPDIR)/e2 && exit 1 || exit 0
$(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L $(TMPDIR)/e2 && exit 1 || exit 0
$(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L crate=$(TMPDIR)/e2 && exit 1 || exit 0
# Native/dependency paths don't cause errors.
$(RUSTC) f.rs -L native=$(TMPDIR)/e1 -L $(TMPDIR)/e2
$(RUSTC) f.rs -L dependency=$(TMPDIR)/e1 -L $(TMPDIR)/e2
$(RUSTC) f.rs -L dependency=$(TMPDIR)/e1 -L crate=$(TMPDIR)/e2

View file

@ -0,0 +1 @@
#![crate_type = "lib"]

View file

@ -0,0 +1,2 @@
#![crate_type = "lib"]
extern crate a;

View file

@ -0,0 +1,2 @@
#![crate_type = "lib"]
extern crate b;

View file

@ -0,0 +1,4 @@
#![crate_type = "rlib"]
#[link(name = "native", kind = "static")]
extern "C" {}

View file

@ -0,0 +1,2 @@
#![crate_name = "e"]
#![crate_type = "rlib"]

View file

@ -0,0 +1,4 @@
#![crate_name = "e"]
#![crate_type = "rlib"]
pub fn f() {}

View file

@ -0,0 +1,2 @@
#![crate_type = "rlib"]
extern crate e;

View file

@ -0,0 +1 @@
// intentionally empty

View file

@ -0,0 +1,9 @@
include ../tools.mk
# only-windows-gnu
all:
$(CXX) foo.cpp -c -o $(TMPDIR)/foo.o
$(AR) crus $(TMPDIR)/libfoo.a $(TMPDIR)/foo.o
$(RUSTC) foo.rs -lfoo -lstdc++
$(call RUN,foo)

View file

@ -0,0 +1,4 @@
extern "C" void foo() {
int *a = new int(3);
delete a;
}

View file

@ -0,0 +1,10 @@
extern "C" {
fn foo();
}
pub fn main() {
unsafe {
foo();
}
assert_eq!(7f32.powi(3), 343f32);
}

View file

@ -0,0 +1,4 @@
include ../tools.mk
all:
$(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../library/core/src/lib.rs --cfg no_fp_fmt_parse

View file

@ -0,0 +1,10 @@
include ../tools.mk
all:
[ `$(RUSTC) --print crate-name crate.rs` = "foo" ]
[ `$(RUSTC) --print file-names crate.rs` = "$(call BIN,foo)" ]
[ `$(RUSTC) --print file-names --crate-type=lib \
--test crate.rs` = "$(call BIN,foo)" ]
[ `$(RUSTC) --print file-names --test lib.rs` = "$(call BIN,mylib)" ]
$(RUSTC) --print file-names lib.rs
$(RUSTC) --print file-names rlib.rs

View file

@ -0,0 +1,7 @@
#![crate_name = "foo"]
// Querying about the crate metadata should *not* parse the entire crate, it
// only needs the crate attributes (which are guaranteed to be at the top) be
// sure that if we have an error like a missing module that we can still query
// about the crate id.
mod error;

View file

@ -0,0 +1,2 @@
#![crate_name = "mylib"]
#![crate_type = "lib"]

View file

@ -0,0 +1,2 @@
#![crate_name = "mylib"]
#![crate_type = "rlib"]

View file

@ -0,0 +1,37 @@
include ../../run-make-fulldeps/tools.mk
# Ensure that crates compiled with different rustc versions cannot
# be dynamically linked.
FLAGS := -Cprefer-dynamic -Zsymbol-mangling-version=v0
UNAME := $(shell uname)
ifeq ($(UNAME),Linux)
EXT=".so"
NM_CMD := nm -D
endif
ifeq ($(UNAME),Darwin)
EXT=".dylib"
NM_CMD := nm
endif
ifndef NM_CMD
all:
exit 0
else
all:
# a.rs is a dylib
$(RUSTC) a.rs --crate-type=dylib $(FLAGS)
# Write symbols to disk.
$(NM_CMD) $(call DYLIB,a) > $(TMPDIR)/symbolsbefore
# b.rs is a binary
$(RUSTC) b.rs --extern a=$(TMPDIR)/liba$(EXT) --crate-type=bin -Crpath $(FLAGS)
$(call RUN,b)
# Now re-compile a.rs with another rustc version
RUSTC_FORCE_RUSTC_VERSION=deadfeed $(RUSTC) a.rs --crate-type=dylib $(FLAGS)
# After compiling with a different rustc version, write symbols to disk again.
$(NM_CMD) $(call DYLIB,a) > $(TMPDIR)/symbolsafter
# As a sanity check, test if the symbols changed:
# If the symbols are identical, there's been an error.
if diff $(TMPDIR)/symbolsbefore $(TMPDIR)/symbolsafter; then exit 1; fi
$(call FAIL,b)
endif

View file

@ -0,0 +1,4 @@
pub fn foo(mut x: String) -> String {
x.push_str(", world!");
x
}

View file

@ -0,0 +1,8 @@
extern crate a;
use a::foo;
fn main() {
let x = String::from("Hello");
println!("{}", foo(x));
}

View file

@ -0,0 +1,11 @@
include ../tools.mk
all:
$(RUSTC) foo.rs
rm $(TMPDIR)/$(call BIN,foo)
$(RUSTC) foo.rs --crate-name bar
rm $(TMPDIR)/$(call BIN,bar)
$(RUSTC) foo1.rs
rm $(TMPDIR)/$(call BIN,foo)
$(RUSTC) foo1.rs -o $(TMPDIR)/$(call BIN,bar1)
rm $(TMPDIR)/$(call BIN,bar1)

View file

@ -0,0 +1 @@
fn main() {}

View file

@ -0,0 +1,3 @@
#![crate_name = "foo"]
fn main() {}

View file

@ -0,0 +1,25 @@
# needs-matching-clang
# This test makes sure that cross-language inlining actually works by checking
# the generated machine code.
include ../tools.mk
all: cpp-executable rust-executable
cpp-executable:
$(RUSTC) -Clinker-plugin-lto=on -o $(TMPDIR)/librustlib-xlto.a -Copt-level=2 -Ccodegen-units=1 ./rustlib.rs
$(CLANG) -flto=thin -fuse-ld=lld -L $(TMPDIR) -lrustlib-xlto -o $(TMPDIR)/cmain ./cmain.c -O3
# Make sure we don't find a call instruction to the function we expect to
# always be inlined.
"$(LLVM_BIN_DIR)"/llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -v -e "call.*rust_always_inlined"
# As a sanity check, make sure we do find a call instruction to a
# non-inlined function
"$(LLVM_BIN_DIR)"/llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -e "call.*rust_never_inlined"
rust-executable:
$(CLANG) ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2
(cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o)
$(RUSTC) -Clinker-plugin-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=$(CLANG) -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain
"$(LLVM_BIN_DIR)"/llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -e "call.*c_never_inlined"
"$(LLVM_BIN_DIR)"/llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined"

View file

@ -0,0 +1,9 @@
#include <stdint.h>
uint32_t c_always_inlined() {
return 1234;
}
__attribute__((noinline)) uint32_t c_never_inlined() {
return 12345;
}

View file

@ -0,0 +1,12 @@
#include <stdint.h>
// A trivial function defined in Rust, returning a constant value. This should
// always be inlined.
uint32_t rust_always_inlined();
uint32_t rust_never_inlined();
int main(int argc, char** argv) {
return rust_never_inlined() + rust_always_inlined();
}

View file

@ -0,0 +1,11 @@
#[link(name = "xyz")]
extern "C" {
fn c_always_inlined() -> u32;
fn c_never_inlined() -> u32;
}
fn main() {
unsafe {
println!("blub: {}", c_always_inlined() + c_never_inlined());
}
}

Some files were not shown because too many files have changed in this diff Show more