rustc: Implement the #[global_allocator] attribute
This PR is an implementation of [RFC 1974] which specifies a new method of defining a global allocator for a program. This obsoletes the old `#![allocator]` attribute and also removes support for it. [RFC 1974]: https://github.com/rust-lang/rfcs/pull/197 The new `#[global_allocator]` attribute solves many issues encountered with the `#![allocator]` attribute such as composition and restrictions on the crate graph itself. The compiler now has much more control over the ABI of the allocator and how it's implemented, allowing much more freedom in terms of how this feature is implemented. cc #27389
This commit is contained in:
parent
4c225c4d17
commit
695dee063b
115 changed files with 2860 additions and 1201 deletions
|
|
@ -11,7 +11,7 @@
|
|||
// compile-flags: -C no-prepopulate-passes
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(allocator)]
|
||||
#![feature(custom_attribute)]
|
||||
|
||||
pub struct S {
|
||||
_field: [i64; 4],
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// error-pattern: `allocator3` cannot depend on a crate that needs an allocator
|
||||
// aux-build:needs_allocator.rs
|
||||
// aux-build:allocator3.rs
|
||||
|
||||
// The needs_allocator crate is a dependency of the allocator crate allocator3,
|
||||
// which is not allowed
|
||||
|
||||
extern crate allocator3;
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// ignore-musl no dylibs
|
||||
// aux-build:allocator-dylib.rs
|
||||
// aux-build:allocator1.rs
|
||||
// no-prefer-dynamic
|
||||
// error-pattern: cannot link together two allocators
|
||||
|
||||
// Verify that the allocator for statically linked dynamic libraries is the
|
||||
// system allocator. Do this by linking in jemalloc and making sure that we get
|
||||
// an error.
|
||||
|
||||
// ignore-emscripten FIXME: What "other allocator" should we use for emcc?
|
||||
|
||||
#![feature(alloc_jemalloc)]
|
||||
|
||||
extern crate allocator_dylib;
|
||||
|
||||
// The main purpose of this test is to ensure that `alloc_jemalloc` **fails**
|
||||
// here (specifically the jemalloc allocator), but currently jemalloc is
|
||||
// disabled on quite a few platforms (bsds, emscripten, msvc, etc). To ensure
|
||||
// that this just passes on those platforms we link in some other allocator to
|
||||
// ensure we get the same error.
|
||||
//
|
||||
// So long as we CI linux/macOS we should be good.
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
extern crate alloc_jemalloc;
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
|
||||
extern crate allocator1;
|
||||
|
||||
fn main() {
|
||||
allocator_dylib::foo();
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// ignore-musl no dylibs
|
||||
// aux-build:allocator-dylib2.rs
|
||||
// aux-build:allocator1.rs
|
||||
// error-pattern: cannot link together two allocators
|
||||
|
||||
// Ensure that rust dynamic libraries use jemalloc as their allocator, verifying
|
||||
// by linking in the system allocator here and ensuring that we get a complaint.
|
||||
|
||||
// ignore-emscripten FIXME: What "other allocator" is correct for emscripten?
|
||||
|
||||
#![feature(alloc_system)]
|
||||
|
||||
extern crate allocator_dylib2;
|
||||
|
||||
// The main purpose of this test is to ensure that `alloc_system` **fails**
|
||||
// here (specifically the system allocator), but currently system is
|
||||
// disabled on quite a few platforms (bsds, emscripten, msvc, etc). To ensure
|
||||
// that this just passes on those platforms we link in some other allocator to
|
||||
// ensure we get the same error.
|
||||
//
|
||||
// So long as we CI linux/macOS we should be good.
|
||||
#[cfg(any(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")),
|
||||
target_os = "macos"))]
|
||||
extern crate alloc_system;
|
||||
#[cfg(not(any(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")),
|
||||
target_os = "macos")))]
|
||||
extern crate allocator1;
|
||||
|
||||
fn main() {
|
||||
allocator_dylib2::foo();
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -10,10 +10,10 @@
|
|||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(allocator)]
|
||||
#![no_std]
|
||||
#![allocator]
|
||||
#![feature(global_allocator, allocator_api)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
extern crate needs_allocator;
|
||||
use std::heap::System;
|
||||
|
||||
#[global_allocator]
|
||||
static A: System = System;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -10,7 +10,10 @@
|
|||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(allocator)]
|
||||
#![allocator]
|
||||
#![feature(global_allocator, allocator_api)]
|
||||
#![crate_type = "rlib"]
|
||||
#![no_std]
|
||||
|
||||
use std::heap::System;
|
||||
|
||||
#[global_allocator]
|
||||
static A: System = System;
|
||||
16
src/test/compile-fail/allocator/function-allocator.rs
Normal file
16
src/test/compile-fail/allocator/function-allocator.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#![feature(global_allocator)]
|
||||
|
||||
#[global_allocator]
|
||||
fn foo() {} //~ ERROR: allocators must be statics
|
||||
|
||||
fn main() {}
|
||||
26
src/test/compile-fail/allocator/not-an-allocator.rs
Normal file
26
src/test/compile-fail/allocator/not-an-allocator.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#![feature(global_allocator, heap_api)]
|
||||
|
||||
#[global_allocator]
|
||||
static A: usize = 0;
|
||||
//~^ the trait bound `&usize:
|
||||
//~| the trait bound `&usize:
|
||||
//~| the trait bound `&usize:
|
||||
//~| the trait bound `&usize:
|
||||
//~| the trait bound `&usize:
|
||||
//~| the trait bound `&usize:
|
||||
//~| the trait bound `&usize:
|
||||
//~| the trait bound `&usize:
|
||||
//~| the trait bound `&usize:
|
||||
//~| the trait bound `&usize:
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -8,12 +8,15 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: cannot link together two allocators
|
||||
#![feature(global_allocator, allocator_api)]
|
||||
|
||||
// aux-build:allocator1.rs
|
||||
// aux-build:allocator2.rs
|
||||
use std::heap::System;
|
||||
|
||||
extern crate allocator1;
|
||||
extern crate allocator2;
|
||||
#[global_allocator]
|
||||
static A: System = System;
|
||||
#[global_allocator]
|
||||
static B: System = System;
|
||||
//~^ ERROR: cannot define more than one #[global_allocator]
|
||||
|
||||
fn main() {}
|
||||
|
||||
25
src/test/compile-fail/allocator/two-allocators2.rs
Normal file
25
src/test/compile-fail/allocator/two-allocators2.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2016 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:system-allocator.rs
|
||||
// no-prefer-dynamic
|
||||
// error-pattern: the #[global_allocator] in
|
||||
|
||||
#![feature(global_allocator, allocator_api)]
|
||||
|
||||
extern crate system_allocator;
|
||||
|
||||
use std::heap::System;
|
||||
|
||||
#[global_allocator]
|
||||
static A: System = System;
|
||||
|
||||
fn main() {}
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -8,12 +8,14 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:system-allocator.rs
|
||||
// aux-build:system-allocator2.rs
|
||||
// no-prefer-dynamic
|
||||
// error-pattern: the #[global_allocator] in
|
||||
|
||||
#![feature(alloc_system)]
|
||||
#![feature(global_allocator)]
|
||||
|
||||
extern crate alloc_system;
|
||||
extern crate system_allocator;
|
||||
extern crate system_allocator2;
|
||||
|
||||
fn main() {
|
||||
println!("{:?}", Box::new(3));
|
||||
}
|
||||
fn main() {}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -8,8 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// no-prefer-dynamic
|
||||
#![default_lib_allocator] //~ ERROR: attribute is an experimental feature
|
||||
|
||||
#![crate_type = "dylib"]
|
||||
fn main() {}
|
||||
|
||||
pub fn foo() {}
|
||||
14
src/test/compile-fail/feature-gate-global_allocator.rs
Normal file
14
src/test/compile-fail/feature-gate-global_allocator.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#[global_allocator] //~ ERROR: attribute is an experimental feature
|
||||
static A: usize = 0;
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// error-pattern: cannot link together two allocators: allocator1 and allocator2
|
||||
// aux-build:allocator1.rs
|
||||
// aux-build:allocator2.rs
|
||||
|
||||
// Make sure we can't link together two explicit allocators.
|
||||
|
||||
extern crate allocator1;
|
||||
extern crate allocator2;
|
||||
|
||||
fn main() {}
|
||||
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2015 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:allocator1.rs
|
||||
// error-pattern: cannot link together two allocators
|
||||
// ignore-musl no dylibs on musl yet
|
||||
// ignore-emscripten
|
||||
|
||||
// We're linking std dynamically (via -C prefer-dynamic for this test) which
|
||||
// has an allocator and then we're also linking in a new allocator (allocator1)
|
||||
// and this should be an error
|
||||
|
||||
extern crate allocator1;
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -4,9 +4,7 @@ ifdef IS_MSVC
|
|||
# FIXME(#27979)
|
||||
all:
|
||||
else
|
||||
all:
|
||||
$(RUSTC) foo.rs
|
||||
$(RUSTC) bar.rs
|
||||
all: $(call STATICLIB,foo) $(call STATICLIB,bar)
|
||||
$(RUSTC) main.rs
|
||||
$(call RUN,main)
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -8,6 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allocator] //~ ERROR: experimental feature
|
||||
extern void foo();
|
||||
|
||||
fn main() {}
|
||||
void bar() {
|
||||
foo();
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#![feature(lang_items, alloc_system, compiler_builtins_lib)]
|
||||
#![crate_type = "dylib"]
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc_system;
|
||||
extern crate compiler_builtins;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn bar() {}
|
||||
|
||||
#[lang = "eh_personality"] fn eh_personality() {}
|
||||
#[lang = "eh_unwind_resume"] fn eh_unwind_resume() {}
|
||||
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
|
||||
#[no_mangle] pub extern fn rust_eh_register_frames () {}
|
||||
#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -8,5 +8,4 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn foo() {}
|
||||
|
||||
void foo() {}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#![feature(lang_items, alloc_system, compiler_builtins_lib)]
|
||||
#![no_std]
|
||||
#![crate_type = "dylib"]
|
||||
|
||||
extern crate alloc_system;
|
||||
extern crate compiler_builtins;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn foo() {}
|
||||
|
||||
#[lang = "eh_personality"] fn eh_personality() {}
|
||||
#[lang = "eh_unwind_resume"] fn eh_unwind_resume() {}
|
||||
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
|
||||
#[no_mangle] pub extern fn rust_eh_register_frames () {}
|
||||
#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
|
||||
|
|
@ -8,9 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[link(name = "foo")]
|
||||
#[link(name = "bar")]
|
||||
#[link(name = "foo")]
|
||||
#[link(name = "foo")] // linker should drop this library, no symbols used
|
||||
#[link(name = "bar")] // symbol comes from this library
|
||||
#[link(name = "foo")] // now linker picks up `foo` b/c `bar` library needs it
|
||||
extern {
|
||||
fn bar();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,20 +8,17 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(alloc, allocator_api, heap_api, unique)]
|
||||
#![feature(allocator_api, unique)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::heap::HeapAlloc;
|
||||
use alloc::allocator::Alloc;
|
||||
use std::heap::{Heap, Alloc};
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let ptr = HeapAlloc.alloc_one::<i32>().unwrap_or_else(|e| {
|
||||
HeapAlloc.oom(e)
|
||||
let ptr = Heap.alloc_one::<i32>().unwrap_or_else(|e| {
|
||||
Heap.oom(e)
|
||||
});
|
||||
*ptr.as_ptr() = 4;
|
||||
assert_eq!(*ptr.as_ptr(), 4);
|
||||
HeapAlloc.dealloc_one(ptr);
|
||||
Heap.dealloc_one(ptr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
#![feature(alloc_jemalloc)]
|
||||
|
||||
#[cfg(any(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")),
|
||||
target_os = "macos"))]
|
||||
extern crate alloc_jemalloc;
|
||||
|
||||
fn main() {
|
||||
println!("{:?}", Box::new(3));
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright 2015 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-prefer-dynamic
|
||||
// aux-build:allocator-dummy.rs
|
||||
// ignore-emscripten
|
||||
|
||||
#![feature(test)]
|
||||
|
||||
extern crate allocator_dummy;
|
||||
extern crate test;
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let before = allocator_dummy::HITS;
|
||||
let mut b = Box::new(3);
|
||||
test::black_box(&mut b); // Make sure the allocation is not optimized away
|
||||
assert_eq!(allocator_dummy::HITS - before, 1);
|
||||
drop(b);
|
||||
assert_eq!(allocator_dummy::HITS - before, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -10,7 +10,18 @@
|
|||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(needs_allocator)]
|
||||
#![no_std]
|
||||
#![needs_allocator]
|
||||
#![feature(global_allocator)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
extern crate custom;
|
||||
|
||||
use std::sync::atomic::{ATOMIC_USIZE_INIT, Ordering};
|
||||
|
||||
use custom::A;
|
||||
|
||||
#[global_allocator]
|
||||
static ALLOCATOR: A = A(ATOMIC_USIZE_INIT);
|
||||
|
||||
pub fn get() -> usize {
|
||||
ALLOCATOR.0.load(Ordering::SeqCst)
|
||||
}
|
||||
31
src/test/run-pass/allocator/auxiliary/custom.rs
Normal file
31
src/test/run-pass/allocator/auxiliary/custom.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2017 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-prefer-dynamic
|
||||
|
||||
#![feature(heap_api, allocator_api)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
use std::heap::{Alloc, System, AllocErr, Layout};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
pub struct A(pub AtomicUsize);
|
||||
|
||||
unsafe impl<'a> Alloc for &'a A {
|
||||
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
|
||||
self.0.fetch_add(1, Ordering::SeqCst);
|
||||
System.alloc(layout)
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
|
||||
self.0.fetch_add(1, Ordering::SeqCst);
|
||||
System.dealloc(ptr, layout)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -10,7 +10,10 @@
|
|||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(allocator)]
|
||||
#![allocator]
|
||||
#![crate_type = "rlib"]
|
||||
#![no_std]
|
||||
|
||||
use std::fmt;
|
||||
|
||||
pub fn work_with(p: &fmt::Debug) {
|
||||
drop(p);
|
||||
}
|
||||
68
src/test/run-pass/allocator/custom.rs
Normal file
68
src/test/run-pass/allocator/custom.rs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright 2017 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:helper.rs
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(global_allocator, heap_api, allocator_api)]
|
||||
|
||||
extern crate helper;
|
||||
|
||||
use std::env;
|
||||
use std::heap::{Heap, Alloc, System, Layout, AllocErr};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
|
||||
|
||||
static HITS: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||
|
||||
struct A;
|
||||
|
||||
unsafe impl<'a> Alloc for &'a A {
|
||||
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
|
||||
HITS.fetch_add(1, Ordering::SeqCst);
|
||||
System.alloc(layout)
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
|
||||
HITS.fetch_add(1, Ordering::SeqCst);
|
||||
System.dealloc(ptr, layout)
|
||||
}
|
||||
}
|
||||
|
||||
#[global_allocator]
|
||||
static GLOBAL: A = A;
|
||||
|
||||
fn main() {
|
||||
env::set_var("FOO", "bar");
|
||||
drop(env::var("FOO"));
|
||||
|
||||
let n = HITS.load(Ordering::SeqCst);
|
||||
assert!(n > 0);
|
||||
unsafe {
|
||||
let layout = Layout::from_size_align(4, 2).unwrap();
|
||||
|
||||
let ptr = Heap.alloc(layout.clone()).unwrap();
|
||||
helper::work_with(&ptr);
|
||||
assert_eq!(HITS.load(Ordering::SeqCst), n + 1);
|
||||
Heap.dealloc(ptr, layout.clone());
|
||||
assert_eq!(HITS.load(Ordering::SeqCst), n + 2);
|
||||
|
||||
let s = String::with_capacity(10);
|
||||
helper::work_with(&s);
|
||||
assert_eq!(HITS.load(Ordering::SeqCst), n + 3);
|
||||
drop(s);
|
||||
assert_eq!(HITS.load(Ordering::SeqCst), n + 4);
|
||||
|
||||
let ptr = System.alloc(layout.clone()).unwrap();
|
||||
assert_eq!(HITS.load(Ordering::SeqCst), n + 4);
|
||||
helper::work_with(&ptr);
|
||||
System.dealloc(ptr, layout);
|
||||
assert_eq!(HITS.load(Ordering::SeqCst), n + 4);
|
||||
}
|
||||
}
|
||||
44
src/test/run-pass/allocator/xcrate-use.rs
Normal file
44
src/test/run-pass/allocator/xcrate-use.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2017 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:custom.rs
|
||||
// aux-build:helper.rs
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(global_allocator, heap_api, allocator_api)]
|
||||
|
||||
extern crate custom;
|
||||
extern crate helper;
|
||||
|
||||
use std::env;
|
||||
use std::heap::{Heap, Alloc, System, Layout};
|
||||
use std::sync::atomic::{Ordering, ATOMIC_USIZE_INIT};
|
||||
|
||||
#[global_allocator]
|
||||
static GLOBAL: custom::A = custom::A(ATOMIC_USIZE_INIT);
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let n = GLOBAL.0.load(Ordering::SeqCst);
|
||||
let layout = Layout::from_size_align(4, 2).unwrap();
|
||||
|
||||
let ptr = Heap.alloc(layout.clone()).unwrap();
|
||||
helper::work_with(&ptr);
|
||||
assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1);
|
||||
Heap.dealloc(ptr, layout.clone());
|
||||
assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
|
||||
|
||||
let ptr = System.alloc(layout.clone()).unwrap();
|
||||
assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
|
||||
helper::work_with(&ptr);
|
||||
System.dealloc(ptr, layout);
|
||||
assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
|
||||
}
|
||||
}
|
||||
57
src/test/run-pass/allocator/xcrate-use2.rs
Normal file
57
src/test/run-pass/allocator/xcrate-use2.rs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright 2017 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:custom.rs
|
||||
// aux-build:custom-as-global.rs
|
||||
// aux-build:helper.rs
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(heap_api, allocator_api)]
|
||||
|
||||
extern crate custom;
|
||||
extern crate custom_as_global;
|
||||
extern crate helper;
|
||||
|
||||
use std::env;
|
||||
use std::heap::{Heap, Alloc, System, Layout};
|
||||
use std::sync::atomic::{Ordering, ATOMIC_USIZE_INIT};
|
||||
|
||||
static GLOBAL: custom::A = custom::A(ATOMIC_USIZE_INIT);
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let n = custom_as_global::get();
|
||||
let layout = Layout::from_size_align(4, 2).unwrap();
|
||||
|
||||
// Global allocator routes to the `custom_as_global` global
|
||||
let ptr = Heap.alloc(layout.clone()).unwrap();
|
||||
helper::work_with(&ptr);
|
||||
assert_eq!(custom_as_global::get(), n + 1);
|
||||
Heap.dealloc(ptr, layout.clone());
|
||||
assert_eq!(custom_as_global::get(), n + 2);
|
||||
|
||||
// Usage of the system allocator avoids all globals
|
||||
let ptr = System.alloc(layout.clone()).unwrap();
|
||||
helper::work_with(&ptr);
|
||||
assert_eq!(custom_as_global::get(), n + 2);
|
||||
System.dealloc(ptr, layout.clone());
|
||||
assert_eq!(custom_as_global::get(), n + 2);
|
||||
|
||||
// Usage of our personal allocator doesn't affect other instances
|
||||
let ptr = (&GLOBAL).alloc(layout.clone()).unwrap();
|
||||
helper::work_with(&ptr);
|
||||
assert_eq!(custom_as_global::get(), n + 2);
|
||||
assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 1);
|
||||
(&GLOBAL).dealloc(ptr, layout);
|
||||
assert_eq!(custom_as_global::get(), n + 2);
|
||||
assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8,16 +8,15 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:clibrary.rs
|
||||
// compile-flags: -lclibrary
|
||||
// compile-flags: -lrust_test_helpers
|
||||
|
||||
#[link(name = "clibrary", kind = "static")]
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern "C" {
|
||||
pub fn foo(x:i32) -> i32;
|
||||
pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
foo(42);
|
||||
rust_dbg_extern_identity_u32(42);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,11 +13,9 @@
|
|||
// Ideally this would be revised to use no_std, but for now it serves
|
||||
// well enough to reproduce (and illustrate) the bug from #16687.
|
||||
|
||||
#![feature(heap_api, alloc, oom)]
|
||||
#![feature(heap_api, allocator_api)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::heap;
|
||||
use std::heap::{Heap, Alloc, Layout};
|
||||
use std::ptr;
|
||||
|
||||
fn main() {
|
||||
|
|
@ -47,38 +45,39 @@ unsafe fn test_triangle() -> bool {
|
|||
|
||||
static PRINT : bool = false;
|
||||
|
||||
unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
|
||||
if PRINT { println!("allocate(size={} align={})", size, align); }
|
||||
unsafe fn allocate(layout: Layout) -> *mut u8 {
|
||||
if PRINT {
|
||||
println!("allocate({:?})", layout);
|
||||
}
|
||||
|
||||
let ret = heap::allocate(size, align);
|
||||
if ret.is_null() { alloc::oom() }
|
||||
let ret = Heap.alloc(layout.clone()).unwrap_or_else(|e| Heap.oom(e));
|
||||
|
||||
if PRINT { println!("allocate(size={} align={}) ret: 0x{:010x}",
|
||||
size, align, ret as usize);
|
||||
if PRINT {
|
||||
println!("allocate({:?}) = {:?}", layout, ret);
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
unsafe fn deallocate(ptr: *mut u8, size: usize, align: usize) {
|
||||
if PRINT { println!("deallocate(ptr=0x{:010x} size={} align={})",
|
||||
ptr as usize, size, align);
|
||||
|
||||
unsafe fn deallocate(ptr: *mut u8, layout: Layout) {
|
||||
if PRINT {
|
||||
println!("deallocate({:?}, {:?}", ptr, layout);
|
||||
}
|
||||
|
||||
heap::deallocate(ptr, size, align);
|
||||
Heap.dealloc(ptr, layout);
|
||||
}
|
||||
unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
|
||||
|
||||
unsafe fn reallocate(ptr: *mut u8, old: Layout, new: Layout) -> *mut u8 {
|
||||
if PRINT {
|
||||
println!("reallocate(ptr=0x{:010x} old_size={} size={} align={})",
|
||||
ptr as usize, old_size, size, align);
|
||||
println!("reallocate({:?}, old={:?}, new={:?})", ptr, old, new);
|
||||
}
|
||||
|
||||
let ret = heap::reallocate(ptr, old_size, size, align);
|
||||
if ret.is_null() { alloc::oom() }
|
||||
let ret = Heap.realloc(ptr, old.clone(), new.clone())
|
||||
.unwrap_or_else(|e| Heap.oom(e));
|
||||
|
||||
if PRINT {
|
||||
println!("reallocate(ptr=0x{:010x} old_size={} size={} align={}) \
|
||||
ret: 0x{:010x}",
|
||||
ptr as usize, old_size, size, align, ret as usize);
|
||||
println!("reallocate({:?}, old={:?}, new={:?}) = {:?}",
|
||||
ptr, old, new, ret);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
|
@ -91,8 +90,8 @@ unsafe fn test_triangle() -> bool {
|
|||
// way.)
|
||||
for i in 0..COUNT / 2 {
|
||||
let size = idx_to_size(i);
|
||||
ascend[2*i] = allocate(size, ALIGN);
|
||||
ascend[2*i+1] = allocate(size, ALIGN);
|
||||
ascend[2*i] = allocate(Layout::from_size_align(size, ALIGN).unwrap());
|
||||
ascend[2*i+1] = allocate(Layout::from_size_align(size, ALIGN).unwrap());
|
||||
}
|
||||
|
||||
// Initialize each pair of rows to distinct value.
|
||||
|
|
@ -112,8 +111,8 @@ unsafe fn test_triangle() -> bool {
|
|||
|
||||
for i in 0..COUNT / 2 {
|
||||
let size = idx_to_size(i);
|
||||
deallocate(ascend[2*i], size, ALIGN);
|
||||
deallocate(ascend[2*i+1], size, ALIGN);
|
||||
deallocate(ascend[2*i], Layout::from_size_align(size, ALIGN).unwrap());
|
||||
deallocate(ascend[2*i+1], Layout::from_size_align(size, ALIGN).unwrap());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -124,14 +123,16 @@ unsafe fn test_triangle() -> bool {
|
|||
// rows as we go.
|
||||
unsafe fn test_1(ascend: &mut [*mut u8]) {
|
||||
let new_size = idx_to_size(COUNT-1);
|
||||
let new = Layout::from_size_align(new_size, ALIGN).unwrap();
|
||||
for i in 0..COUNT / 2 {
|
||||
let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
|
||||
assert!(old_size < new_size);
|
||||
let old = Layout::from_size_align(old_size, ALIGN).unwrap();
|
||||
|
||||
ascend[2*i] = reallocate(p0, old_size, new_size, ALIGN);
|
||||
ascend[2*i] = reallocate(p0, old.clone(), new.clone());
|
||||
sanity_check(&*ascend);
|
||||
|
||||
ascend[2*i+1] = reallocate(p1, old_size, new_size, ALIGN);
|
||||
ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
|
||||
sanity_check(&*ascend);
|
||||
}
|
||||
}
|
||||
|
|
@ -139,14 +140,16 @@ unsafe fn test_triangle() -> bool {
|
|||
// Test 2: turn the square back into a triangle, top to bottom.
|
||||
unsafe fn test_2(ascend: &mut [*mut u8]) {
|
||||
let old_size = idx_to_size(COUNT-1);
|
||||
let old = Layout::from_size_align(old_size, ALIGN).unwrap();
|
||||
for i in 0..COUNT / 2 {
|
||||
let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
|
||||
assert!(new_size < old_size);
|
||||
let new = Layout::from_size_align(new_size, ALIGN).unwrap();
|
||||
|
||||
ascend[2*i] = reallocate(p0, old_size, new_size, ALIGN);
|
||||
ascend[2*i] = reallocate(p0, old.clone(), new.clone());
|
||||
sanity_check(&*ascend);
|
||||
|
||||
ascend[2*i+1] = reallocate(p1, old_size, new_size, ALIGN);
|
||||
ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
|
||||
sanity_check(&*ascend);
|
||||
}
|
||||
}
|
||||
|
|
@ -154,14 +157,16 @@ unsafe fn test_triangle() -> bool {
|
|||
// Test 3: turn triangle into a square, bottom to top.
|
||||
unsafe fn test_3(ascend: &mut [*mut u8]) {
|
||||
let new_size = idx_to_size(COUNT-1);
|
||||
let new = Layout::from_size_align(new_size, ALIGN).unwrap();
|
||||
for i in (0..COUNT / 2).rev() {
|
||||
let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
|
||||
assert!(old_size < new_size);
|
||||
let old = Layout::from_size_align(old_size, ALIGN).unwrap();
|
||||
|
||||
ascend[2*i+1] = reallocate(p1, old_size, new_size, ALIGN);
|
||||
ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
|
||||
sanity_check(&*ascend);
|
||||
|
||||
ascend[2*i] = reallocate(p0, old_size, new_size, ALIGN);
|
||||
ascend[2*i] = reallocate(p0, old.clone(), new.clone());
|
||||
sanity_check(&*ascend);
|
||||
}
|
||||
}
|
||||
|
|
@ -169,14 +174,16 @@ unsafe fn test_triangle() -> bool {
|
|||
// Test 4: turn the square back into a triangle, bottom to top.
|
||||
unsafe fn test_4(ascend: &mut [*mut u8]) {
|
||||
let old_size = idx_to_size(COUNT-1);
|
||||
let old = Layout::from_size_align(old_size, ALIGN).unwrap();
|
||||
for i in (0..COUNT / 2).rev() {
|
||||
let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
|
||||
assert!(new_size < old_size);
|
||||
let new = Layout::from_size_align(new_size, ALIGN).unwrap();
|
||||
|
||||
ascend[2*i+1] = reallocate(p1, old_size, new_size, ALIGN);
|
||||
ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
|
||||
sanity_check(&*ascend);
|
||||
|
||||
ascend[2*i] = reallocate(p0, old_size, new_size, ALIGN);
|
||||
ascend[2*i] = reallocate(p0, old.clone(), new.clone());
|
||||
sanity_check(&*ascend);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,16 +8,15 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:clibrary.rs
|
||||
// compile-flags: -lstatic=wronglibrary:clibrary
|
||||
// compile-flags: -lstatic=wronglibrary:rust_test_helpers
|
||||
|
||||
#[link(name = "wronglibrary", kind = "dylib")]
|
||||
extern "C" {
|
||||
pub fn foo(x:i32) -> i32;
|
||||
pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
foo(42);
|
||||
rust_dbg_extern_identity_u32(42);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,32 +10,32 @@
|
|||
|
||||
// Smallest "hello world" with a libc runtime
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
// ignore-windows
|
||||
// ignore-android
|
||||
|
||||
#![feature(intrinsics, lang_items, start, no_core, alloc_system)]
|
||||
#![no_core]
|
||||
#![feature(global_allocator, allocator_api)]
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc_system;
|
||||
|
||||
extern { fn puts(s: *const u8); }
|
||||
extern "rust-intrinsic" { fn transmute<T, U>(t: T) -> U; }
|
||||
use alloc_system::System;
|
||||
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
#[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {}
|
||||
#[global_allocator]
|
||||
static A: System = System;
|
||||
|
||||
extern {
|
||||
fn puts(s: *const u8);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[lang = "eh_personality"] pub extern fn rust_eh_personality() {}
|
||||
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
|
||||
#[no_mangle] pub extern fn rust_eh_register_frames () {}
|
||||
#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
|
||||
|
||||
#[start]
|
||||
fn main(_: isize, _: *const *const u8) -> isize {
|
||||
unsafe {
|
||||
let (ptr, _): (*const u8, usize) = transmute("Hello!\0");
|
||||
puts(ptr);
|
||||
puts("Hello!\0".as_ptr() as *const u8);
|
||||
}
|
||||
return 0;
|
||||
return 0
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
#[link(name="gcc")]
|
||||
extern { }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue