about summary refs log tree commit diff
path: root/src/test/ui/attributes
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/attributes')
-rw-r--r--src/test/ui/attributes/collapse-debuginfo-invalid.rs110
-rw-r--r--src/test/ui/attributes/collapse-debuginfo-invalid.stderr222
-rw-r--r--src/test/ui/attributes/issue-100631.rs8
-rw-r--r--src/test/ui/attributes/issue-100631.stderr12
-rw-r--r--src/test/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs31
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs4
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr13
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs5
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr14
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs13
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs14
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs4
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr15
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs6
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs9
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs13
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs15
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs13
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs6
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs6
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs4
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr8
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe.rs4
-rw-r--r--src/test/ui/attributes/unix_sigpipe/unix_sigpipe.stderr8
29 files changed, 597 insertions, 0 deletions
diff --git a/src/test/ui/attributes/collapse-debuginfo-invalid.rs b/src/test/ui/attributes/collapse-debuginfo-invalid.rs
new file mode 100644
index 00000000000..42d8982c118
--- /dev/null
+++ b/src/test/ui/attributes/collapse-debuginfo-invalid.rs
@@ -0,0 +1,110 @@
+#![feature(collapse_debuginfo)]
+#![feature(stmt_expr_attributes)]
+#![feature(type_alias_impl_trait)]
+#![no_std]
+
+// Test that the `#[collapse_debuginfo]` attribute can only be used on macro definitions.
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+extern crate std;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+use std::collections::HashMap;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+static FOO: u32 = 3;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+const BAR: u32 = 3;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+fn foo() {
+    let _ = #[collapse_debuginfo] || { };
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    let _ = 3;
+    let _ = #[collapse_debuginfo] 3;
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    match (3, 4) {
+        #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+        _ => (),
+    }
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+mod bar {
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+type Map = HashMap<u32, u32>;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+enum Foo {
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    Variant,
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+struct Bar {
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    field: u32,
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+union Qux {
+    a: u32,
+    b: u16
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+trait Foobar {
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    type Bar;
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+type AFoobar = impl Foobar;
+
+impl Foobar for Bar {
+    type Bar = u32;
+}
+
+fn constraining() -> AFoobar {
+    Bar { field: 3 }
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+impl Bar {
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    const FOO: u32 = 3;
+
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    fn bar(&self) {}
+}
+
+#[collapse_debuginfo]
+macro_rules! finally {
+    ($e:expr) => { $e }
+}
+
+fn main() {}
diff --git a/src/test/ui/attributes/collapse-debuginfo-invalid.stderr b/src/test/ui/attributes/collapse-debuginfo-invalid.stderr
new file mode 100644
index 00000000000..01c47609108
--- /dev/null
+++ b/src/test/ui/attributes/collapse-debuginfo-invalid.stderr
@@ -0,0 +1,222 @@
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:8:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | extern crate std;
+   | ----------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:12:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | use std::collections::HashMap;
+   | ------------------------------ not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:16:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | static FOO: u32 = 3;
+   | -------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:20:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | const BAR: u32 = 3;
+   | ------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:24:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / fn foo() {
+LL | |     let _ = #[collapse_debuginfo] || { };
+LL | |
+LL | |     #[collapse_debuginfo]
+...  |
+LL | |     }
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:27:13
+   |
+LL |     let _ = #[collapse_debuginfo] || { };
+   |             ^^^^^^^^^^^^^^^^^^^^^ ------ not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:29:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     let _ = 3;
+   |     ---------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:32:13
+   |
+LL |     let _ = #[collapse_debuginfo] 3;
+   |             ^^^^^^^^^^^^^^^^^^^^^ - not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:35:9
+   |
+LL |         #[collapse_debuginfo]
+   |         ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |         _ => (),
+   |         ------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:41:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / mod bar {
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:46:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | type Map = HashMap<u32, u32>;
+   | ----------------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:50:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / enum Foo {
+LL | |     #[collapse_debuginfo]
+LL | |
+LL | |     Variant,
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:53:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     Variant,
+   |     ------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:58:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / struct Bar {
+LL | |     #[collapse_debuginfo]
+LL | |
+LL | |     field: u32,
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:61:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     field: u32,
+   |     ---------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:66:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / union Qux {
+LL | |     a: u32,
+LL | |     b: u16
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:73:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / trait Foobar {
+LL | |     #[collapse_debuginfo]
+LL | |
+LL | |     type Bar;
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:81:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | type AFoobar = impl Foobar;
+   | --------------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:93:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / impl Bar {
+LL | |     #[collapse_debuginfo]
+LL | |
+LL | |     const FOO: u32 = 3;
+...  |
+LL | |     fn bar(&self) {}
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:76:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     type Bar;
+   |     --------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:96:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     const FOO: u32 = 3;
+   |     ------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:100:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     fn bar(&self) {}
+   |     ---------------- not a macro definition
+
+error: aborting due to 22 previous errors
+
diff --git a/src/test/ui/attributes/issue-100631.rs b/src/test/ui/attributes/issue-100631.rs
new file mode 100644
index 00000000000..0fefcf83fd5
--- /dev/null
+++ b/src/test/ui/attributes/issue-100631.rs
@@ -0,0 +1,8 @@
+// issue #100631, make sure `TyCtxt::get_attr` only called by case that compiler
+// can reasonably deal with multiple attributes.
+// `repr` will use `TyCtxt::get_attrs` since it's `DuplicatesOk`.
+#[repr(C)] //~ ERROR: unsupported representation for zero-variant enum [E0084]
+#[repr(C)]
+enum Foo {}
+
+fn main() {}
diff --git a/src/test/ui/attributes/issue-100631.stderr b/src/test/ui/attributes/issue-100631.stderr
new file mode 100644
index 00000000000..caa5351ddc7
--- /dev/null
+++ b/src/test/ui/attributes/issue-100631.stderr
@@ -0,0 +1,12 @@
+error[E0084]: unsupported representation for zero-variant enum
+  --> $DIR/issue-100631.rs:4:1
+   |
+LL | #[repr(C)]
+   | ^^^^^^^^^^
+LL | #[repr(C)]
+LL | enum Foo {}
+   | -------- zero-variant enum
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0084`.
diff --git a/src/test/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs b/src/test/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs
new file mode 100644
index 00000000000..e8b4fe7ae52
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs
@@ -0,0 +1,31 @@
+#![feature(rustc_private)]
+extern crate libc;
+
+/// So tests don't have to bring libc in scope themselves
+pub enum SignalHandler {
+    Ignore,
+    Default,
+}
+
+/// Helper to assert that [`libc::SIGPIPE`] has the expected signal handler.
+pub fn assert_sigpipe_handler(expected_handler: SignalHandler) {
+    #[cfg(unix)]
+    #[cfg(not(any(
+        target_os = "emscripten",
+        target_os = "fuchsia",
+        target_os = "horizon",
+        target_os = "android",
+    )))]
+    {
+        let prev = unsafe { libc::signal(libc::SIGPIPE, libc::SIG_IGN) };
+
+        let expected = match expected_handler {
+            SignalHandler::Ignore => libc::SIG_IGN,
+            SignalHandler::Default => libc::SIG_DFL,
+        };
+        assert_eq!(prev, expected);
+
+        // Unlikely to matter, but restore the old value anyway
+        unsafe { libc::signal(libc::SIGPIPE, prev); };
+    }
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs
new file mode 100644
index 00000000000..d6d020c52b2
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+#![unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute cannot be used at crate level
+
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr
new file mode 100644
index 00000000000..a1fb4d6787c
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr
@@ -0,0 +1,13 @@
+error: `unix_sigpipe` attribute cannot be used at crate level
+  --> $DIR/unix_sigpipe-crate.rs:2:1
+   |
+LL | #![unix_sigpipe = "inherit"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: perhaps you meant to use an outer attribute
+   |
+LL | #[unix_sigpipe = "inherit"]
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs
new file mode 100644
index 00000000000..294cb38526b
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs
@@ -0,0 +1,5 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "sig_ign"]
+#[unix_sigpipe = "inherit"] //~ error: multiple `unix_sigpipe` attributes
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr
new file mode 100644
index 00000000000..2362c17a090
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr
@@ -0,0 +1,14 @@
+error: multiple `unix_sigpipe` attributes
+  --> $DIR/unix_sigpipe-duplicates.rs:4:1
+   |
+LL | #[unix_sigpipe = "inherit"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+   |
+note: attribute also specified here
+  --> $DIR/unix_sigpipe-duplicates.rs:3:1
+   |
+LL | #[unix_sigpipe = "sig_ign"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs
new file mode 100644
index 00000000000..0a42a5b5ef1
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-error.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "sig_ign"]
+fn main() {
+    extern crate sigpipe_utils;
+
+    // #[unix_sigpipe = "sig_ign"] is active, so the legacy behavior of ignoring
+    // SIGPIPE shall be in effect
+    sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
new file mode 100644
index 00000000000..4f864807752
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
@@ -0,0 +1,14 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "inherit"]
+fn main() {
+    extern crate sigpipe_utils;
+
+    // #[unix_sigpipe = "inherit"] is active, so SIGPIPE shall NOT be ignored,
+    // instead the default handler shall be installed. (We assume that the
+    // process that runs these tests have the default handler.)
+    sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs
new file mode 100644
index 00000000000..b5ebc07a043
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe(inherit)] //~ error: malformed `unix_sigpipe` attribute input
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr
new file mode 100644
index 00000000000..59a87e13918
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-list.stderr
@@ -0,0 +1,15 @@
+error: malformed `unix_sigpipe` attribute input
+  --> $DIR/unix_sigpipe-list.rs:3:1
+   |
+LL | #[unix_sigpipe(inherit)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: the following are the possible correct uses
+   |
+LL | #[unix_sigpipe = "inherit|sig_ign|sig_dfl"]
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL | #[unix_sigpipe]
+   | ~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs
new file mode 100644
index 00000000000..cde6719fc9c
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs
@@ -0,0 +1,6 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
+fn f() {}
+
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr
new file mode 100644
index 00000000000..c4b81118c9f
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on `fn main()`
+  --> $DIR/unix_sigpipe-non-main-fn.rs:3:1
+   |
+LL | #[unix_sigpipe = "inherit"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs
new file mode 100644
index 00000000000..16f7276398e
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs
@@ -0,0 +1,8 @@
+#![feature(unix_sigpipe)]
+
+mod m {
+    #[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on root `fn main()`
+    fn main() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr
new file mode 100644
index 00000000000..a04f605edc2
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on root `fn main()`
+  --> $DIR/unix_sigpipe-non-root-main.rs:4:5
+   |
+LL |     #[unix_sigpipe = "inherit"]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs
new file mode 100644
index 00000000000..100b4ce9f74
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs
@@ -0,0 +1,9 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+fn main() {
+    extern crate sigpipe_utils;
+
+    // SIGPIPE shall be ignored since #[unix_sigpipe = "..."] is not used
+    sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs
new file mode 100644
index 00000000000..b5adc2e5572
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-only-feature.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+fn main() {
+    extern crate sigpipe_utils;
+
+    // Only #![feature(unix_sigpipe)] is enabled, not #[unix_sigpipe = "..."].
+    // This shall not change any behavior, so we still expect SIGPIPE to be
+    // ignored
+    sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs
new file mode 100644
index 00000000000..6befb9e9565
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs
@@ -0,0 +1,15 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+#![feature(rustc_attrs)]
+
+#[unix_sigpipe = "sig_dfl"]
+#[rustc_main]
+fn rustc_main() {
+    extern crate sigpipe_utils;
+
+    // #[unix_sigpipe = "sig_dfl"] is active, so SIGPIPE handler shall be
+    // SIG_DFL. Note that we have a #[rustc_main], but it should still work.
+    sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs
new file mode 100644
index 00000000000..238c0d57a68
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:sigpipe-utils.rs
+
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "sig_dfl"]
+fn main() {
+    extern crate sigpipe_utils;
+
+    // #[unix_sigpipe = "sig_dfl"] is active, so SIGPIPE shall NOT be ignored, instead
+    // the default handler shall be installed
+    sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
+}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs
new file mode 100644
index 00000000000..64fd5ec4f0e
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs
@@ -0,0 +1,6 @@
+#![feature(start)]
+#![feature(unix_sigpipe)]
+
+#[start]
+#[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
+fn custom_start(argc: isize, argv: *const *const u8) -> isize { 0 }
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr
new file mode 100644
index 00000000000..2c9ce479b6c
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on `fn main()`
+  --> $DIR/unix_sigpipe-start.rs:5:1
+   |
+LL | #[unix_sigpipe = "inherit"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs
new file mode 100644
index 00000000000..a5e47cfebc8
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs
@@ -0,0 +1,6 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "inherit"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
+struct S;
+
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr
new file mode 100644
index 00000000000..c56ee60bb2e
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr
@@ -0,0 +1,8 @@
+error: `unix_sigpipe` attribute can only be used on `fn main()`
+  --> $DIR/unix_sigpipe-struct.rs:3:1
+   |
+LL | #[unix_sigpipe = "inherit"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs
new file mode 100644
index 00000000000..4ec25de00ec
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe = "wrong"] //~ error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr
new file mode 100644
index 00000000000..a66e45aa210
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr
@@ -0,0 +1,8 @@
+error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+  --> $DIR/unix_sigpipe-wrong.rs:3:1
+   |
+LL | #[unix_sigpipe = "wrong"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.rs b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.rs
new file mode 100644
index 00000000000..7bf1c7350c3
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.rs
@@ -0,0 +1,4 @@
+#![feature(unix_sigpipe)]
+
+#[unix_sigpipe] //~ error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+fn main() {}
diff --git a/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.stderr b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.stderr
new file mode 100644
index 00000000000..1b1eda825aa
--- /dev/null
+++ b/src/test/ui/attributes/unix_sigpipe/unix_sigpipe.stderr
@@ -0,0 +1,8 @@
+error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
+  --> $DIR/unix_sigpipe.rs:3:1
+   |
+LL | #[unix_sigpipe]
+   | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+