Skip to content

Commit

Permalink
Issue deprecation warnings for safe accesses to extern statics
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Sep 8, 2016
1 parent ea45edf commit aadbcff
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/doc/book/ffi.md
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ extern {
fn main() {
println!("You have readline version {} installed.",
rl_readline_version as i32);
unsafe { rl_readline_version as i32 });
}
```

Expand Down
4 changes: 2 additions & 2 deletions src/libpanic_unwind/seh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,13 @@ extern "C" {
// Again, I'm not entirely sure what this is describing, it just seems to work.
#[cfg_attr(not(test), lang = "msvc_try_filter")]
static mut TYPE_DESCRIPTOR1: _TypeDescriptor = _TypeDescriptor {
pVFTable: &TYPE_INFO_VTABLE as *const _ as *const _,
pVFTable: unsafe { &TYPE_INFO_VTABLE } as *const _ as *const _,
spare: 0 as *mut _,
name: imp::NAME1,
};

static mut TYPE_DESCRIPTOR2: _TypeDescriptor = _TypeDescriptor {
pVFTable: &TYPE_INFO_VTABLE as *const _ as *const _,
pVFTable: unsafe { &TYPE_INFO_VTABLE } as *const _ as *const _,
spare: 0 as *mut _,
name: imp::NAME2,
};
Expand Down
9 changes: 8 additions & 1 deletion src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ declare_lint! {
"lifetimes or labels named `'_` were erroneously allowed"
}

declare_lint! {
pub SAFE_EXTERN_STATICS,
Warn,
"safe access to extern statics was erroneously allowed"
}

/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
Expand Down Expand Up @@ -228,7 +234,8 @@ impl LintPass for HardwiredLints {
RENAMED_AND_REMOVED_LINTS,
SUPER_OR_SELF_IN_GLOBAL_PATH,
HR_LIFETIME_IN_ASSOC_TYPE,
LIFETIME_UNDERSCORE
LIFETIME_UNDERSCORE,
SAFE_EXTERN_STATICS
)
}
}
Expand Down
40 changes: 31 additions & 9 deletions src/librustc/middle/effect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use self::RootUnsafeContext::*;
use dep_graph::DepNode;
use ty::{self, Ty, TyCtxt};
use ty::MethodCall;
use lint;

use syntax::ast;
use syntax_pos::Span;
Expand Down Expand Up @@ -57,16 +58,25 @@ struct EffectCheckVisitor<'a, 'tcx: 'a> {
}

impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
fn require_unsafe(&mut self, span: Span, description: &str) {
fn require_unsafe_ext(&mut self, node_id: ast::NodeId, span: Span,
description: &str, is_lint: bool) {
if self.unsafe_context.push_unsafe_count > 0 { return; }
match self.unsafe_context.root {
SafeContext => {
// Report an error.
struct_span_err!(
self.tcx.sess, span, E0133,
"{} requires unsafe function or block", description)
.span_label(span, &description)
.emit();
if is_lint {
self.tcx.sess.add_lint(lint::builtin::SAFE_EXTERN_STATICS,
node_id,
span,
format!("{} requires unsafe function or \
block (error E0133)", description));
} else {
// Report an error.
struct_span_err!(
self.tcx.sess, span, E0133,
"{} requires unsafe function or block", description)
.span_label(span, &description)
.emit();
}
}
UnsafeBlock(block_id) => {
// OK, but record this.
Expand All @@ -76,6 +86,10 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
UnsafeFn => {}
}
}

fn require_unsafe(&mut self, span: Span, description: &str) {
self.require_unsafe_ext(ast::DUMMY_NODE_ID, span, description, false)
}
}

impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
Expand Down Expand Up @@ -173,8 +187,16 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
self.require_unsafe(expr.span, "use of inline assembly");
}
hir::ExprPath(..) => {
if let Def::Static(_, true) = self.tcx.expect_def(expr.id) {
self.require_unsafe(expr.span, "use of mutable static");
if let Def::Static(def_id, mutbl) = self.tcx.expect_def(expr.id) {
if mutbl {
self.require_unsafe(expr.span, "use of mutable static");
} else if match self.tcx.map.get_if_local(def_id) {
Some(hir::map::NodeForeignItem(..)) => true,
Some(..) => false,
None => self.tcx.sess.cstore.is_foreign_item(def_id),
} {
self.require_unsafe_ext(expr.id, expr.span, "use of extern static", true);
}
}
}
hir::ExprField(ref base_expr, field) => {
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
id: LintId::of(LIFETIME_UNDERSCORE),
reference: "RFC 1177 <https://github.com/rust-lang/rfcs/pull/1177>",
},
FutureIncompatibleInfo {
id: LintId::of(SAFE_EXTERN_STATICS),
reference: "issue 36247 <https://github.com/rust-lang/rust/issues/35112>",
},
]);

// Register renamed and removed lints
Expand Down
14 changes: 14 additions & 0 deletions src/test/compile-fail/auxiliary/extern-statics.rs
Original file line number Diff line number Diff line change
@@ -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.

extern {
pub static XA: u8;
pub static mut XB: u8;
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/linkage2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ extern {
}

fn main() {
println!("{}", foo);
println!("{}", unsafe { foo });
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/linkage3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ extern {
}

fn main() {
println!("{:?}", foo);
println!("{:?}", unsafe { foo });
}
28 changes: 28 additions & 0 deletions src/test/compile-fail/safe-extern-statics-mut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// 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:extern-statics.rs

#![allow(unused)]
#![deny(safe_extern_statics)]

extern crate extern_statics;
use extern_statics::*;

extern {
static mut B: u8;
}

fn main() {
let b = B; //~ ERROR use of mutable static requires unsafe function or block
let rb = &B; //~ ERROR use of mutable static requires unsafe function or block
let xb = XB; //~ ERROR use of mutable static requires unsafe function or block
let xrb = &XB; //~ ERROR use of mutable static requires unsafe function or block
}
32 changes: 32 additions & 0 deletions src/test/compile-fail/safe-extern-statics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// 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:extern-statics.rs

#![allow(unused)]
#![deny(safe_extern_statics)]

extern crate extern_statics;
use extern_statics::*;

extern {
static A: u8;
}

fn main() {
let a = A; //~ ERROR use of extern static requires unsafe function or block
//~^ WARN this was previously accepted by the compiler
let ra = &A; //~ ERROR use of extern static requires unsafe function or block
//~^ WARN this was previously accepted by the compiler
let xa = XA; //~ ERROR use of extern static requires unsafe function or block
//~^ WARN this was previously accepted by the compiler
let xra = &XA; //~ ERROR use of extern static requires unsafe function or block
//~^ WARN this was previously accepted by the compiler
}
2 changes: 1 addition & 1 deletion src/test/run-pass/check-static-recursion-foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ extern "C" {
static test_static: c_int;
}

static B: &'static c_int = &test_static;
static B: &'static c_int = unsafe { &test_static };

pub fn main() {}

0 comments on commit aadbcff

Please sign in to comment.