about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-03-11 09:56:57 -0700
committerbors <bors@rust-lang.org>2014-03-11 09:56:57 -0700
commit9f3ebd8fc50682d6e4ef549cb31e70171acdcd71 (patch)
tree568d189da6e6d954f880746411f923f4db5906a1 /src/test
parenta0f20f09fde77fb7330b1a67918744149dca3318 (diff)
parent699b33d060c5c9cc580d50cf3fe39536ae7a059a (diff)
downloadrust-9f3ebd8fc50682d6e4ef549cb31e70171acdcd71.tar.gz
rust-9f3ebd8fc50682d6e4ef549cb31e70171acdcd71.zip
auto merge of #12556 : alexcrichton/rust/weak-linkage, r=brson
It is often convenient to have forms of weak linkage or other various types of
linkage. Sadly, just using these flavors of linkage are not compatible with
Rust's typesystem and how it considers some pointers to be non-null.

As a compromise, this commit adds support for weak linkage to external symbols,
but it requires that this is only placed on extern statics of type `*T`.
Codegen-wise, we get translations like:

```rust
    // rust code
    extern {
        #[linkage = "extern_weak"]
        static foo: *i32;
    }

    // generated IR
    @foo = extern_weak global i32
    @_some_internal_symbol = internal global *i32 @foo
```

All references to the rust value of `foo` then reference `_some_internal_symbol`
instead of the symbol `_foo` itself. This allows us to guarantee that the
address of `foo` will never be null while the value may sometimes be null.

An example was implemented in `std::rt::thread` to determine if
`__pthread_get_minstack()` is available at runtime, and a test is checked in to
use it for a static value as well. Function pointers a little odd because you
still need to transmute the pointer value to a function pointer, but it's
thankfully better than not having this capability at all.

Thanks to @bnoordhuis for the original patch, most of this work is still his!
Diffstat (limited to 'src/test')
-rw-r--r--src/test/auxiliary/linkage1.rs12
-rw-r--r--src/test/compile-fail/linkage1.rs14
-rw-r--r--src/test/compile-fail/linkage2.rs20
-rw-r--r--src/test/compile-fail/linkage3.rs21
-rw-r--r--src/test/run-pass/linkage1.rs32
5 files changed, 99 insertions, 0 deletions
diff --git a/src/test/auxiliary/linkage1.rs b/src/test/auxiliary/linkage1.rs
new file mode 100644
index 00000000000..9017ee88363
--- /dev/null
+++ b/src/test/auxiliary/linkage1.rs
@@ -0,0 +1,12 @@
+// 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.
+
+#[no_mangle]
+pub static foo: int = 3;
diff --git a/src/test/compile-fail/linkage1.rs b/src/test/compile-fail/linkage1.rs
new file mode 100644
index 00000000000..a045b838d51
--- /dev/null
+++ b/src/test/compile-fail/linkage1.rs
@@ -0,0 +1,14 @@
+// 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 {
+    #[linkage = "extern_weak"] static foo: int;
+    //~^ ERROR: the `linkage` attribute is experimental and not portable
+}
diff --git a/src/test/compile-fail/linkage2.rs b/src/test/compile-fail/linkage2.rs
new file mode 100644
index 00000000000..524324fa1f1
--- /dev/null
+++ b/src/test/compile-fail/linkage2.rs
@@ -0,0 +1,20 @@
+// 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(linkage)];
+
+extern {
+    #[linkage = "extern_weak"] static foo: i32;
+    //~^ ERROR: must have type `*T`
+}
+
+fn main() {
+    println!("{}", foo);
+}
diff --git a/src/test/compile-fail/linkage3.rs b/src/test/compile-fail/linkage3.rs
new file mode 100644
index 00000000000..2da800bcb1c
--- /dev/null
+++ b/src/test/compile-fail/linkage3.rs
@@ -0,0 +1,21 @@
+// 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(linkage)];
+
+extern {
+    #[linkage = "foo"] static foo: *i32;
+    //~^ ERROR: invalid linkage specified
+}
+
+fn main() {
+    println!("{}", foo);
+}
+
diff --git a/src/test/run-pass/linkage1.rs b/src/test/run-pass/linkage1.rs
new file mode 100644
index 00000000000..8f8b0cfecb2
--- /dev/null
+++ b/src/test/run-pass/linkage1.rs
@@ -0,0 +1,32 @@
+// 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.
+
+// ignore-win32
+// ignore-fast
+// ignore-android
+// ignore-macos
+// aux-build:linkage1.rs
+
+#[feature(linkage)];
+
+extern crate other = "linkage1";
+
+extern {
+    #[linkage = "extern_weak"]
+    static foo: *int;
+    #[linkage = "extern_weak"]
+    static something_that_should_never_exist: *mut int;
+}
+
+fn main() {
+    assert!(!foo.is_null());
+    assert_eq!(unsafe { *foo }, 3);
+    assert!(something_that_should_never_exist.is_null());
+}