about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-01-15 12:42:08 +0100
committerGitHub <noreply@github.com>2019-01-15 12:42:08 +0100
commite8cfae4140ca237b277b3e5afac61f6504c54191 (patch)
treecfe6a534d8dad10a6c8643df82e193d311df3409
parent77727feb180493bfce998d4fcba9dfd7ca5f0637 (diff)
parentbd1551e46e4a788dc974f4aac8ba821133625663 (diff)
downloadrust-e8cfae4140ca237b277b3e5afac61f6504c54191.tar.gz
rust-e8cfae4140ca237b277b3e5afac61f6504c54191.zip
Rollup merge of #57467 - JohnTitor:implement-the-check-attribute-1, r=oli-obk
Implement `check_attribute` to forbid `#[allow_internal_unsafe]`

Fixes #56768.

r? @oli-obk
-rw-r--r--src/librustc_lint/builtin.rs43
-rw-r--r--src/librustc_lint/lib.rs2
-rw-r--r--src/libsyntax/ast.rs4
-rw-r--r--src/test/ui/lint/lint-forbid-internal-unsafe.rs16
-rw-r--r--src/test/ui/lint/lint-forbid-internal-unsafe.stderr14
5 files changed, 58 insertions, 21 deletions
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 72bcf8edfdd..ddb397b7c7f 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -40,9 +40,9 @@ use syntax_pos::{BytePos, Span, SyntaxContext};
 use syntax::symbol::keywords;
 use syntax::errors::{Applicability, DiagnosticBuilder};
 use syntax::print::pprust::expr_to_string;
+use syntax::visit::FnKind;
 
 use rustc::hir::{self, GenericParamKind, PatKind};
-use rustc::hir::intravisit::FnKind;
 
 use nonstandard_style::{MethodLateContext, method_context};
 
@@ -216,7 +216,7 @@ impl LintPass for UnsafeCode {
 }
 
 impl UnsafeCode {
-    fn report_unsafe(&self, cx: &LateContext, span: Span, desc: &'static str) {
+    fn report_unsafe(&self, cx: &EarlyContext, span: Span, desc: &'static str) {
         // This comes from a macro that has #[allow_internal_unsafe].
         if span.allows_unsafe() {
             return;
@@ -226,23 +226,31 @@ impl UnsafeCode {
     }
 }
 
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
-    fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
-        if let hir::ExprKind::Block(ref blk, _) = e.node {
+impl EarlyLintPass for UnsafeCode {
+    fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
+        if attr.check_name("allow_internal_unsafe") {
+            self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \
+                                               macros using unsafe without triggering \
+                                               the `unsafe_code` lint at their call site");
+        }
+    }
+
+    fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
+        if let ast::ExprKind::Block(ref blk, _) = e.node {
             // Don't warn about generated blocks, that'll just pollute the output.
-            if blk.rules == hir::UnsafeBlock(hir::UserProvided) {
+            if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) {
                 self.report_unsafe(cx, blk.span, "usage of an `unsafe` block");
             }
         }
     }
 
-    fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+    fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
         match it.node {
-            hir::ItemKind::Trait(_, hir::Unsafety::Unsafe, ..) => {
+            ast::ItemKind::Trait(_, ast::Unsafety::Unsafe, ..) => {
                 self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait")
             }
 
-            hir::ItemKind::Impl(hir::Unsafety::Unsafe, ..) => {
+            ast::ItemKind::Impl(ast::Unsafety::Unsafe, ..) => {
                 self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait")
             }
 
@@ -251,19 +259,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
     }
 
     fn check_fn(&mut self,
-                cx: &LateContext,
-                fk: FnKind<'tcx>,
-                _: &hir::FnDecl,
-                _: &hir::Body,
+                cx: &EarlyContext,
+                fk: FnKind,
+                _: &ast::FnDecl,
                 span: Span,
                 _: ast::NodeId) {
         match fk {
-            FnKind::ItemFn(_, _, hir::FnHeader { unsafety: hir::Unsafety::Unsafe, .. }, ..) => {
+            FnKind::ItemFn(_, ast::FnHeader { unsafety: ast::Unsafety::Unsafe, .. }, ..) => {
                 self.report_unsafe(cx, span, "declaration of an `unsafe` function")
             }
 
             FnKind::Method(_, sig, ..) => {
-                if sig.header.unsafety == hir::Unsafety::Unsafe {
+                if sig.header.unsafety == ast::Unsafety::Unsafe {
                     self.report_unsafe(cx, span, "implementation of an `unsafe` method")
                 }
             }
@@ -272,9 +279,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
         }
     }
 
-    fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
-        if let hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(_)) = item.node {
-            if sig.header.unsafety == hir::Unsafety::Unsafe {
+    fn check_trait_item(&mut self, cx: &EarlyContext, item: &ast::TraitItem) {
+        if let ast::TraitItemKind::Method(ref sig, None) = item.node {
+            if sig.header.unsafety == ast::Unsafety::Unsafe {
                 self.report_unsafe(cx, item.span, "declaration of an `unsafe` method")
             }
         }
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 4dfb664451b..0d05cc1b2be 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -111,6 +111,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
     add_early_builtin!(sess,
                        UnusedParens,
                        UnusedImportBraces,
+                       UnsafeCode,
                        AnonymousParameters,
                        UnusedDocComment,
                        BadRepr,
@@ -134,7 +135,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
         NonSnakeCase: NonSnakeCase,
         NonUpperCaseGlobals: NonUpperCaseGlobals,
         NonShorthandFieldPatterns: NonShorthandFieldPatterns,
-        UnsafeCode: UnsafeCode,
         UnusedAllocation: UnusedAllocation,
         MissingCopyImplementations: MissingCopyImplementations,
         UnstableFeatures: UnstableFeatures,
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e3a8980a975..99ab9fbcf5f 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -853,13 +853,13 @@ pub struct Field {
 
 pub type SpannedIdent = Spanned<Ident>;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub enum BlockCheckMode {
     Default,
     Unsafe(UnsafeSource),
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub enum UnsafeSource {
     CompilerGenerated,
     UserProvided,
diff --git a/src/test/ui/lint/lint-forbid-internal-unsafe.rs b/src/test/ui/lint/lint-forbid-internal-unsafe.rs
new file mode 100644
index 00000000000..b08fbf6f845
--- /dev/null
+++ b/src/test/ui/lint/lint-forbid-internal-unsafe.rs
@@ -0,0 +1,16 @@
+#![forbid(unsafe_code)]
+#![feature(allow_internal_unsafe)]
+
+#[allow_internal_unsafe]
+//~^ ERROR: `allow_internal_unsafe` allows defining
+macro_rules! evil {
+    ($e:expr) => {
+        unsafe {
+            $e
+        }
+    }
+}
+
+fn main() {
+    println!("{}", evil!(*(0 as *const u8)));
+}
diff --git a/src/test/ui/lint/lint-forbid-internal-unsafe.stderr b/src/test/ui/lint/lint-forbid-internal-unsafe.stderr
new file mode 100644
index 00000000000..59dab119682
--- /dev/null
+++ b/src/test/ui/lint/lint-forbid-internal-unsafe.stderr
@@ -0,0 +1,14 @@
+error: `allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site
+  --> $DIR/lint-forbid-internal-unsafe.rs:4:1
+   |
+LL | #[allow_internal_unsafe]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint-forbid-internal-unsafe.rs:1:11
+   |
+LL | #![forbid(unsafe_code)]
+   |           ^^^^^^^^^^^
+
+error: aborting due to previous error
+