summaryrefslogtreecommitdiffstats
path: root/src/test/ui/linkage-attr
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/linkage-attr
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/linkage-attr')
-rw-r--r--src/test/ui/linkage-attr/auxiliary/def_colliding_external.rs7
-rw-r--r--src/test/ui/linkage-attr/auxiliary/def_illtyped_external.rs5
-rw-r--r--src/test/ui/linkage-attr/auxiliary/link-cfg-works-transitive-dylib.rs4
-rw-r--r--src/test/ui/linkage-attr/auxiliary/link-cfg-works-transitive-rlib.rs7
-rw-r--r--src/test/ui/linkage-attr/auxiliary/linkage1.rs4
-rw-r--r--src/test/ui/linkage-attr/issue-10755.rs10
-rw-r--r--src/test/ui/linkage-attr/link-attr-validation-early.rs8
-rw-r--r--src/test/ui/linkage-attr/link-attr-validation-early.stderr21
-rw-r--r--src/test/ui/linkage-attr/link-attr-validation-late.rs40
-rw-r--r--src/test/ui/linkage-attr/link-attr-validation-late.stderr147
-rw-r--r--src/test/ui/linkage-attr/link-cfg-works.rs13
-rw-r--r--src/test/ui/linkage-attr/linkage-detect-extern-generated-name-collision.rs24
-rw-r--r--src/test/ui/linkage-attr/linkage-detect-extern-generated-name-collision.stderr8
-rw-r--r--src/test/ui/linkage-attr/linkage-detect-local-generated-name-collision.rs26
-rw-r--r--src/test/ui/linkage-attr/linkage-detect-local-generated-name-collision.stderr8
-rw-r--r--src/test/ui/linkage-attr/linkage-requires-raw-ptr.rs11
-rw-r--r--src/test/ui/linkage-attr/linkage-requires-raw-ptr.stderr8
-rw-r--r--src/test/ui/linkage-attr/linkage1.rs32
-rw-r--r--src/test/ui/linkage-attr/linkage2.rs18
-rw-r--r--src/test/ui/linkage-attr/linkage2.stderr8
-rw-r--r--src/test/ui/linkage-attr/linkage3.rs17
-rw-r--r--src/test/ui/linkage-attr/linkage3.stderr8
-rw-r--r--src/test/ui/linkage-attr/linkage4.rs5
-rw-r--r--src/test/ui/linkage-attr/linkage4.stderr12
24 files changed, 451 insertions, 0 deletions
diff --git a/src/test/ui/linkage-attr/auxiliary/def_colliding_external.rs b/src/test/ui/linkage-attr/auxiliary/def_colliding_external.rs
new file mode 100644
index 000000000..60b55b3e2
--- /dev/null
+++ b/src/test/ui/linkage-attr/auxiliary/def_colliding_external.rs
@@ -0,0 +1,7 @@
+#![feature(linkage)]
+#![crate_type = "lib"]
+
+extern "C" {
+ #[linkage = "external"]
+ pub static collision: *const i32;
+}
diff --git a/src/test/ui/linkage-attr/auxiliary/def_illtyped_external.rs b/src/test/ui/linkage-attr/auxiliary/def_illtyped_external.rs
new file mode 100644
index 000000000..2300930e5
--- /dev/null
+++ b/src/test/ui/linkage-attr/auxiliary/def_illtyped_external.rs
@@ -0,0 +1,5 @@
+#![feature(linkage)]
+#![crate_type = "lib"]
+
+#[linkage="external"]
+pub static EXTERN: u32 = 0;
diff --git a/src/test/ui/linkage-attr/auxiliary/link-cfg-works-transitive-dylib.rs b/src/test/ui/linkage-attr/auxiliary/link-cfg-works-transitive-dylib.rs
new file mode 100644
index 000000000..0d927117d
--- /dev/null
+++ b/src/test/ui/linkage-attr/auxiliary/link-cfg-works-transitive-dylib.rs
@@ -0,0 +1,4 @@
+#![feature(link_cfg)]
+
+#[link(name = "foo", cfg(foo))]
+extern "C" {}
diff --git a/src/test/ui/linkage-attr/auxiliary/link-cfg-works-transitive-rlib.rs b/src/test/ui/linkage-attr/auxiliary/link-cfg-works-transitive-rlib.rs
new file mode 100644
index 000000000..0a296f0b2
--- /dev/null
+++ b/src/test/ui/linkage-attr/auxiliary/link-cfg-works-transitive-rlib.rs
@@ -0,0 +1,7 @@
+// no-prefer-dynamic
+
+#![feature(link_cfg)]
+#![crate_type = "rlib"]
+
+#[link(name = "foo", cfg(foo))]
+extern "C" {}
diff --git a/src/test/ui/linkage-attr/auxiliary/linkage1.rs b/src/test/ui/linkage-attr/auxiliary/linkage1.rs
new file mode 100644
index 000000000..e87ce5e4d
--- /dev/null
+++ b/src/test/ui/linkage-attr/auxiliary/linkage1.rs
@@ -0,0 +1,4 @@
+#[no_mangle]
+pub static foo: isize = 3;
+
+pub fn bar() {}
diff --git a/src/test/ui/linkage-attr/issue-10755.rs b/src/test/ui/linkage-attr/issue-10755.rs
new file mode 100644
index 000000000..afd2dc46c
--- /dev/null
+++ b/src/test/ui/linkage-attr/issue-10755.rs
@@ -0,0 +1,10 @@
+// build-fail
+// dont-check-compiler-stderr
+// compile-flags: -C linker=llllll -C linker-flavor=ld
+// error-pattern: `llllll`
+
+// Before, the error-pattern checked for "not found". On WSL with appendWindowsPath=true, running
+// in invalid command returns a PermissionDenied instead.
+
+fn main() {
+}
diff --git a/src/test/ui/linkage-attr/link-attr-validation-early.rs b/src/test/ui/linkage-attr/link-attr-validation-early.rs
new file mode 100644
index 000000000..b9a835fb5
--- /dev/null
+++ b/src/test/ui/linkage-attr/link-attr-validation-early.rs
@@ -0,0 +1,8 @@
+// Top-level ill-formed
+#[link] //~ ERROR attribute must be of the form
+ //~| WARN this was previously accepted
+#[link = "foo"] //~ ERROR attribute must be of the form
+ //~| WARN this was previously accepted
+extern "C" {}
+
+fn main() {}
diff --git a/src/test/ui/linkage-attr/link-attr-validation-early.stderr b/src/test/ui/linkage-attr/link-attr-validation-early.stderr
new file mode 100644
index 000000000..d36601ed0
--- /dev/null
+++ b/src/test/ui/linkage-attr/link-attr-validation-early.stderr
@@ -0,0 +1,21 @@
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+ --> $DIR/link-attr-validation-early.rs:2:1
+ |
+LL | #[link]
+ | ^^^^^^^
+ |
+ = note: `#[deny(ill_formed_attribute_input)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...")]`
+ --> $DIR/link-attr-validation-early.rs:4:1
+ |
+LL | #[link = "foo"]
+ | ^^^^^^^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/linkage-attr/link-attr-validation-late.rs b/src/test/ui/linkage-attr/link-attr-validation-late.rs
new file mode 100644
index 000000000..b454fbd0e
--- /dev/null
+++ b/src/test/ui/linkage-attr/link-attr-validation-late.rs
@@ -0,0 +1,40 @@
+#![feature(native_link_modifiers_verbatim)]
+#![feature(link_cfg)]
+
+// Top-level ill-formed
+#[link(name = "...", "literal")] //~ ERROR unexpected `#[link]` argument
+#[link(name = "...", unknown)] //~ ERROR unexpected `#[link]` argument
+extern "C" {}
+
+// Duplicate arguments
+#[link(name = "foo", name = "bar")] //~ ERROR multiple `name` arguments
+#[link(name = "...", kind = "dylib", kind = "bar")] //~ ERROR multiple `kind` arguments
+#[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] //~ ERROR multiple `modifiers` arguments
+#[link(name = "...", cfg(FALSE), cfg(FALSE))] //~ ERROR multiple `cfg` arguments
+#[link(wasm_import_module = "foo", wasm_import_module = "bar")] //~ ERROR multiple `wasm_import_module` arguments
+extern "C" {}
+
+// Ill-formed arguments
+#[link(name)] //~ ERROR link name must be of the form `name = "string"`
+ //~| ERROR `#[link]` attribute requires a `name = "string"` argument
+#[link(name())] //~ ERROR link name must be of the form `name = "string"`
+ //~| ERROR `#[link]` attribute requires a `name = "string"` argument
+#[link(name = "...", kind)] //~ ERROR link kind must be of the form `kind = "string"`
+#[link(name = "...", kind())] //~ ERROR link kind must be of the form `kind = "string"`
+#[link(name = "...", modifiers)] //~ ERROR link modifiers must be of the form `modifiers = "string"`
+#[link(name = "...", modifiers())] //~ ERROR link modifiers must be of the form `modifiers = "string"`
+#[link(name = "...", cfg)] //~ ERROR link cfg must be of the form `cfg(/* predicate */)`
+#[link(name = "...", cfg = "literal")] //~ ERROR link cfg must be of the form `cfg(/* predicate */)`
+#[link(name = "...", cfg("literal"))] //~ ERROR link cfg must have a single predicate argument
+#[link(name = "...", wasm_import_module)] //~ ERROR wasm import module must be of the form `wasm_import_module = "string"`
+#[link(name = "...", wasm_import_module())] //~ ERROR wasm import module must be of the form `wasm_import_module = "string"`
+extern "C" {}
+
+// Basic modifier validation
+#[link(name = "...", modifiers = "")] //~ ERROR invalid linking modifier syntax, expected '+' or '-' prefix
+#[link(name = "...", modifiers = "no-plus-minus")] //~ ERROR invalid linking modifier syntax, expected '+' or '-' prefix
+#[link(name = "...", modifiers = "+unknown")] //~ ERROR unknown linking modifier `unknown`
+#[link(name = "...", modifiers = "+verbatim,+verbatim")] //~ ERROR multiple `verbatim` modifiers
+extern "C" {}
+
+fn main() {}
diff --git a/src/test/ui/linkage-attr/link-attr-validation-late.stderr b/src/test/ui/linkage-attr/link-attr-validation-late.stderr
new file mode 100644
index 000000000..bb08f9a4c
--- /dev/null
+++ b/src/test/ui/linkage-attr/link-attr-validation-late.stderr
@@ -0,0 +1,147 @@
+error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module
+ --> $DIR/link-attr-validation-late.rs:5:22
+ |
+LL | #[link(name = "...", "literal")]
+ | ^^^^^^^^^
+
+error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module
+ --> $DIR/link-attr-validation-late.rs:6:22
+ |
+LL | #[link(name = "...", unknown)]
+ | ^^^^^^^
+
+error: multiple `name` arguments in a single `#[link]` attribute
+ --> $DIR/link-attr-validation-late.rs:10:22
+ |
+LL | #[link(name = "foo", name = "bar")]
+ | ^^^^^^^^^^^^
+
+error: multiple `kind` arguments in a single `#[link]` attribute
+ --> $DIR/link-attr-validation-late.rs:11:38
+ |
+LL | #[link(name = "...", kind = "dylib", kind = "bar")]
+ | ^^^^^^^^^^^^
+
+error: multiple `modifiers` arguments in a single `#[link]` attribute
+ --> $DIR/link-attr-validation-late.rs:12:47
+ |
+LL | #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")]
+ | ^^^^^^^^^^^^^^^^^
+
+error: multiple `cfg` arguments in a single `#[link]` attribute
+ --> $DIR/link-attr-validation-late.rs:13:34
+ |
+LL | #[link(name = "...", cfg(FALSE), cfg(FALSE))]
+ | ^^^^^^^^^^
+
+error: multiple `wasm_import_module` arguments in a single `#[link]` attribute
+ --> $DIR/link-attr-validation-late.rs:14:36
+ |
+LL | #[link(wasm_import_module = "foo", wasm_import_module = "bar")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: link name must be of the form `name = "string"`
+ --> $DIR/link-attr-validation-late.rs:18:8
+ |
+LL | #[link(name)]
+ | ^^^^
+
+error[E0459]: `#[link]` attribute requires a `name = "string"` argument
+ --> $DIR/link-attr-validation-late.rs:18:1
+ |
+LL | #[link(name)]
+ | ^^^^^^^^^^^^^ missing `name` argument
+
+error: link name must be of the form `name = "string"`
+ --> $DIR/link-attr-validation-late.rs:20:8
+ |
+LL | #[link(name())]
+ | ^^^^^^
+
+error[E0459]: `#[link]` attribute requires a `name = "string"` argument
+ --> $DIR/link-attr-validation-late.rs:20:1
+ |
+LL | #[link(name())]
+ | ^^^^^^^^^^^^^^^ missing `name` argument
+
+error: link kind must be of the form `kind = "string"`
+ --> $DIR/link-attr-validation-late.rs:22:22
+ |
+LL | #[link(name = "...", kind)]
+ | ^^^^
+
+error: link kind must be of the form `kind = "string"`
+ --> $DIR/link-attr-validation-late.rs:23:22
+ |
+LL | #[link(name = "...", kind())]
+ | ^^^^^^
+
+error: link modifiers must be of the form `modifiers = "string"`
+ --> $DIR/link-attr-validation-late.rs:24:22
+ |
+LL | #[link(name = "...", modifiers)]
+ | ^^^^^^^^^
+
+error: link modifiers must be of the form `modifiers = "string"`
+ --> $DIR/link-attr-validation-late.rs:25:22
+ |
+LL | #[link(name = "...", modifiers())]
+ | ^^^^^^^^^^^
+
+error: link cfg must be of the form `cfg(/* predicate */)`
+ --> $DIR/link-attr-validation-late.rs:26:22
+ |
+LL | #[link(name = "...", cfg)]
+ | ^^^
+
+error: link cfg must be of the form `cfg(/* predicate */)`
+ --> $DIR/link-attr-validation-late.rs:27:22
+ |
+LL | #[link(name = "...", cfg = "literal")]
+ | ^^^^^^^^^^^^^^^
+
+error: link cfg must have a single predicate argument
+ --> $DIR/link-attr-validation-late.rs:28:22
+ |
+LL | #[link(name = "...", cfg("literal"))]
+ | ^^^^^^^^^^^^^^
+
+error: wasm import module must be of the form `wasm_import_module = "string"`
+ --> $DIR/link-attr-validation-late.rs:29:22
+ |
+LL | #[link(name = "...", wasm_import_module)]
+ | ^^^^^^^^^^^^^^^^^^
+
+error: wasm import module must be of the form `wasm_import_module = "string"`
+ --> $DIR/link-attr-validation-late.rs:30:22
+ |
+LL | #[link(name = "...", wasm_import_module())]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
+ --> $DIR/link-attr-validation-late.rs:34:34
+ |
+LL | #[link(name = "...", modifiers = "")]
+ | ^^
+
+error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
+ --> $DIR/link-attr-validation-late.rs:35:34
+ |
+LL | #[link(name = "...", modifiers = "no-plus-minus")]
+ | ^^^^^^^^^^^^^^^
+
+error: unknown linking modifier `unknown`, expected one of: bundle, verbatim, whole-archive, as-needed
+ --> $DIR/link-attr-validation-late.rs:36:34
+ |
+LL | #[link(name = "...", modifiers = "+unknown")]
+ | ^^^^^^^^^^
+
+error: multiple `verbatim` modifiers in a single `modifiers` argument
+ --> $DIR/link-attr-validation-late.rs:37:34
+ |
+LL | #[link(name = "...", modifiers = "+verbatim,+verbatim")]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 24 previous errors
+
+For more information about this error, try `rustc --explain E0459`.
diff --git a/src/test/ui/linkage-attr/link-cfg-works.rs b/src/test/ui/linkage-attr/link-cfg-works.rs
new file mode 100644
index 000000000..254091ff2
--- /dev/null
+++ b/src/test/ui/linkage-attr/link-cfg-works.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:link-cfg-works-transitive-rlib.rs
+// aux-build:link-cfg-works-transitive-dylib.rs
+
+#![feature(link_cfg)]
+
+extern crate link_cfg_works_transitive_dylib;
+extern crate link_cfg_works_transitive_rlib;
+
+#[link(name = "foo", cfg(foo))]
+extern "C" {}
+
+fn main() {}
diff --git a/src/test/ui/linkage-attr/linkage-detect-extern-generated-name-collision.rs b/src/test/ui/linkage-attr/linkage-detect-extern-generated-name-collision.rs
new file mode 100644
index 000000000..3a0910658
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage-detect-extern-generated-name-collision.rs
@@ -0,0 +1,24 @@
+// rust-lang/rust#61232: We used to ICE when trying to detect a
+// collision on the symbol generated for the external linkage item in
+// an extern crate.
+
+// build-fail
+// aux-build:def_colliding_external.rs
+// FIXME(#83838) codegen-units=1 triggers llvm asserts
+// compile-flags: -Ccodegen-units=16
+
+extern crate def_colliding_external as dep1;
+
+#[no_mangle]
+pub static _rust_extern_with_linkage_collision: i32 = 0;
+
+mod dep2 {
+ #[no_mangle]
+ pub static collision: usize = 0;
+}
+
+fn main() {
+ unsafe {
+ println!("{:p}", &dep1::collision);
+ }
+}
diff --git a/src/test/ui/linkage-attr/linkage-detect-extern-generated-name-collision.stderr b/src/test/ui/linkage-attr/linkage-detect-extern-generated-name-collision.stderr
new file mode 100644
index 000000000..06a070822
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage-detect-extern-generated-name-collision.stderr
@@ -0,0 +1,8 @@
+error: symbol `collision` is already defined
+ --> $DIR/auxiliary/def_colliding_external.rs:6:5
+ |
+LL | pub static collision: *const i32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/linkage-attr/linkage-detect-local-generated-name-collision.rs b/src/test/ui/linkage-attr/linkage-detect-local-generated-name-collision.rs
new file mode 100644
index 000000000..c1df9ccef
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage-detect-local-generated-name-collision.rs
@@ -0,0 +1,26 @@
+// build-fail
+// FIXME(#83838) codegen-units=1 triggers llvm asserts
+// compile-flags: -Ccodegen-units=16
+#![feature(linkage)]
+
+mod dep1 {
+ extern "C" {
+ #[linkage = "external"]
+ #[no_mangle]
+ pub static collision: *const i32; //~ ERROR symbol `collision` is already defined
+ }
+}
+
+#[no_mangle]
+pub static _rust_extern_with_linkage_collision: i32 = 0;
+
+mod dep2 {
+ #[no_mangle]
+ pub static collision: usize = 0;
+}
+
+fn main() {
+ unsafe {
+ println!("{:p}", &dep1::collision);
+ }
+}
diff --git a/src/test/ui/linkage-attr/linkage-detect-local-generated-name-collision.stderr b/src/test/ui/linkage-attr/linkage-detect-local-generated-name-collision.stderr
new file mode 100644
index 000000000..e0be1ac21
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage-detect-local-generated-name-collision.stderr
@@ -0,0 +1,8 @@
+error: symbol `collision` is already defined
+ --> $DIR/linkage-detect-local-generated-name-collision.rs:10:9
+ |
+LL | pub static collision: *const i32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/linkage-attr/linkage-requires-raw-ptr.rs b/src/test/ui/linkage-attr/linkage-requires-raw-ptr.rs
new file mode 100644
index 000000000..93afc537f
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage-requires-raw-ptr.rs
@@ -0,0 +1,11 @@
+// rust-lang/rust#59548: We used to ICE when trying to use a static
+// with a type that violated its own `#[linkage]`.
+
+// build-fail
+// aux-build:def_illtyped_external.rs
+
+extern crate def_illtyped_external as dep;
+
+fn main() {
+ println!("{:p}", &dep::EXTERN);
+}
diff --git a/src/test/ui/linkage-attr/linkage-requires-raw-ptr.stderr b/src/test/ui/linkage-attr/linkage-requires-raw-ptr.stderr
new file mode 100644
index 000000000..5abbe745c
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage-requires-raw-ptr.stderr
@@ -0,0 +1,8 @@
+error: must have type `*const T` or `*mut T` due to `#[linkage]` attribute
+ --> $DIR/auxiliary/def_illtyped_external.rs:5:1
+ |
+LL | pub static EXTERN: u32 = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/linkage-attr/linkage1.rs b/src/test/ui/linkage-attr/linkage1.rs
new file mode 100644
index 000000000..deab7a251
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage1.rs
@@ -0,0 +1,32 @@
+// run-pass
+// ignore-windows
+// ignore-macos
+// ignore-emscripten doesn't support this linkage
+// ignore-sgx weak linkage not permitted
+// aux-build:linkage1.rs
+
+#![feature(linkage)]
+
+extern crate linkage1 as other;
+
+extern "C" {
+ #[linkage = "extern_weak"]
+ static foo: *const isize;
+ #[linkage = "extern_weak"]
+ static something_that_should_never_exist: *mut isize;
+}
+
+fn main() {
+ // It appears that the --as-needed flag to linkers will not pull in a dynamic
+ // library unless it satisfies a non weak undefined symbol. The 'other' crate
+ // is compiled as a dynamic library where it would only be used for a
+ // weak-symbol as part of an executable, so the dynamic library would be
+ // discarded. By adding and calling `other::bar`, we get around this problem.
+ other::bar();
+
+ unsafe {
+ assert!(!foo.is_null());
+ assert_eq!(*foo, 3);
+ assert!(something_that_should_never_exist.is_null());
+ }
+}
diff --git a/src/test/ui/linkage-attr/linkage2.rs b/src/test/ui/linkage-attr/linkage2.rs
new file mode 100644
index 000000000..a7be19852
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage2.rs
@@ -0,0 +1,18 @@
+// FIXME https://github.com/rust-lang/rust/issues/59774
+
+// build-fail
+// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> ""
+// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// ignore-sgx no weak linkages permitted
+
+#![feature(linkage)]
+
+extern "C" {
+ #[linkage = "extern_weak"]
+ static foo: i32;
+//~^ ERROR: must have type `*const T` or `*mut T` due to `#[linkage]` attribute
+}
+
+fn main() {
+ println!("{}", unsafe { foo });
+}
diff --git a/src/test/ui/linkage-attr/linkage2.stderr b/src/test/ui/linkage-attr/linkage2.stderr
new file mode 100644
index 000000000..a6ac0aad0
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage2.stderr
@@ -0,0 +1,8 @@
+error: must have type `*const T` or `*mut T` due to `#[linkage]` attribute
+ --> $DIR/linkage2.rs:12:5
+ |
+LL | static foo: i32;
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/linkage-attr/linkage3.rs b/src/test/ui/linkage-attr/linkage3.rs
new file mode 100644
index 000000000..112eb1d3b
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage3.rs
@@ -0,0 +1,17 @@
+// FIXME https://github.com/rust-lang/rust/issues/59774
+
+// check-fail
+// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> ""
+// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+
+#![feature(linkage)]
+
+extern "C" {
+ #[linkage = "foo"]
+ static foo: *const i32;
+//~^ ERROR: invalid linkage specified
+}
+
+fn main() {
+ println!("{:?}", unsafe { foo });
+}
diff --git a/src/test/ui/linkage-attr/linkage3.stderr b/src/test/ui/linkage-attr/linkage3.stderr
new file mode 100644
index 000000000..f2579c6e8
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage3.stderr
@@ -0,0 +1,8 @@
+error: invalid linkage specified
+ --> $DIR/linkage3.rs:11:5
+ |
+LL | static foo: *const i32;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/linkage-attr/linkage4.rs b/src/test/ui/linkage-attr/linkage4.rs
new file mode 100644
index 000000000..3b935f972
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage4.rs
@@ -0,0 +1,5 @@
+#[linkage = "external"]
+static foo: isize = 0;
+//~^^ ERROR: the `linkage` attribute is experimental and not portable
+
+fn main() {}
diff --git a/src/test/ui/linkage-attr/linkage4.stderr b/src/test/ui/linkage-attr/linkage4.stderr
new file mode 100644
index 000000000..30d4d2b7b
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage4.stderr
@@ -0,0 +1,12 @@
+error[E0658]: the `linkage` attribute is experimental and not portable across platforms
+ --> $DIR/linkage4.rs:1:1
+ |
+LL | #[linkage = "external"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #29603 <https://github.com/rust-lang/rust/issues/29603> for more information
+ = help: add `#![feature(linkage)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.