Auto merge of #36173 - petrochenkov:unstat, r=nikomatsakis

Issue deprecation warnings for safe accesses to extern statics

Fixes https://github.com/rust-lang/rust/issues/35112
cc https://github.com/rust-lang/rust/issues/36247
This commit is contained in:
bors 2016-09-08 15:57:02 -07:00 committed by GitHub
commit 378195665c
11 changed files with 123 additions and 16 deletions

View File

@ -471,7 +471,7 @@ extern {
fn main() {
println!("You have readline version {} installed.",
rl_readline_version as i32);
unsafe { rl_readline_version as i32 });
}
```

View File

@ -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,
};

View File

@ -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)]
@ -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
)
}
}

View File

@ -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;
@ -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.
@ -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> {
@ -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) => {

View File

@ -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

View File

@ -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;
}

View File

@ -16,5 +16,5 @@ extern {
}
fn main() {
println!("{}", foo);
println!("{}", unsafe { foo });
}

View File

@ -16,5 +16,5 @@ extern {
}
fn main() {
println!("{:?}", foo);
println!("{:?}", unsafe { foo });
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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() {}