Issue deprecation warnings for safe accesses to extern statics
This commit is contained in:
parent
ea45edf0ee
commit
aadbcffb7c
11 changed files with 123 additions and 16 deletions
|
@ -471,7 +471,7 @@ extern {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("You have readline version {} installed.",
|
println!("You have readline version {} installed.",
|
||||||
rl_readline_version as i32);
|
unsafe { rl_readline_version as i32 });
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -232,13 +232,13 @@ extern "C" {
|
||||||
// Again, I'm not entirely sure what this is describing, it just seems to work.
|
// Again, I'm not entirely sure what this is describing, it just seems to work.
|
||||||
#[cfg_attr(not(test), lang = "msvc_try_filter")]
|
#[cfg_attr(not(test), lang = "msvc_try_filter")]
|
||||||
static mut TYPE_DESCRIPTOR1: _TypeDescriptor = _TypeDescriptor {
|
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 _,
|
spare: 0 as *mut _,
|
||||||
name: imp::NAME1,
|
name: imp::NAME1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static mut TYPE_DESCRIPTOR2: _TypeDescriptor = _TypeDescriptor {
|
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 _,
|
spare: 0 as *mut _,
|
||||||
name: imp::NAME2,
|
name: imp::NAME2,
|
||||||
};
|
};
|
||||||
|
|
|
@ -192,6 +192,12 @@ declare_lint! {
|
||||||
"lifetimes or labels named `'_` were erroneously allowed"
|
"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
|
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||||
/// which are used by other parts of the compiler.
|
/// which are used by other parts of the compiler.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -228,7 +234,8 @@ impl LintPass for HardwiredLints {
|
||||||
RENAMED_AND_REMOVED_LINTS,
|
RENAMED_AND_REMOVED_LINTS,
|
||||||
SUPER_OR_SELF_IN_GLOBAL_PATH,
|
SUPER_OR_SELF_IN_GLOBAL_PATH,
|
||||||
HR_LIFETIME_IN_ASSOC_TYPE,
|
HR_LIFETIME_IN_ASSOC_TYPE,
|
||||||
LIFETIME_UNDERSCORE
|
LIFETIME_UNDERSCORE,
|
||||||
|
SAFE_EXTERN_STATICS
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ use self::RootUnsafeContext::*;
|
||||||
use dep_graph::DepNode;
|
use dep_graph::DepNode;
|
||||||
use ty::{self, Ty, TyCtxt};
|
use ty::{self, Ty, TyCtxt};
|
||||||
use ty::MethodCall;
|
use ty::MethodCall;
|
||||||
|
use lint;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
@ -57,16 +58,25 @@ struct EffectCheckVisitor<'a, 'tcx: 'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
|
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; }
|
if self.unsafe_context.push_unsafe_count > 0 { return; }
|
||||||
match self.unsafe_context.root {
|
match self.unsafe_context.root {
|
||||||
SafeContext => {
|
SafeContext => {
|
||||||
// Report an error.
|
if is_lint {
|
||||||
struct_span_err!(
|
self.tcx.sess.add_lint(lint::builtin::SAFE_EXTERN_STATICS,
|
||||||
self.tcx.sess, span, E0133,
|
node_id,
|
||||||
"{} requires unsafe function or block", description)
|
span,
|
||||||
.span_label(span, &description)
|
format!("{} requires unsafe function or \
|
||||||
.emit();
|
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) => {
|
UnsafeBlock(block_id) => {
|
||||||
// OK, but record this.
|
// OK, but record this.
|
||||||
|
@ -76,6 +86,10 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
|
||||||
UnsafeFn => {}
|
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> {
|
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");
|
self.require_unsafe(expr.span, "use of inline assembly");
|
||||||
}
|
}
|
||||||
hir::ExprPath(..) => {
|
hir::ExprPath(..) => {
|
||||||
if let Def::Static(_, true) = self.tcx.expect_def(expr.id) {
|
if let Def::Static(def_id, mutbl) = self.tcx.expect_def(expr.id) {
|
||||||
self.require_unsafe(expr.span, "use of mutable static");
|
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) => {
|
hir::ExprField(ref base_expr, field) => {
|
||||||
|
|
|
@ -201,6 +201,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||||
id: LintId::of(LIFETIME_UNDERSCORE),
|
id: LintId::of(LIFETIME_UNDERSCORE),
|
||||||
reference: "RFC 1177 <https://github.com/rust-lang/rfcs/pull/1177>",
|
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
|
// Register renamed and removed lints
|
||||||
|
|
14
src/test/compile-fail/auxiliary/extern-statics.rs
Normal file
14
src/test/compile-fail/auxiliary/extern-statics.rs
Normal 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;
|
||||||
|
}
|
|
@ -16,5 +16,5 @@ extern {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{}", foo);
|
println!("{}", unsafe { foo });
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,5 +16,5 @@ extern {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{:?}", foo);
|
println!("{:?}", unsafe { foo });
|
||||||
}
|
}
|
||||||
|
|
28
src/test/compile-fail/safe-extern-statics-mut.rs
Normal file
28
src/test/compile-fail/safe-extern-statics-mut.rs
Normal 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
|
||||||
|
}
|
32
src/test/compile-fail/safe-extern-statics.rs
Normal file
32
src/test/compile-fail/safe-extern-statics.rs
Normal 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
|
||||||
|
}
|
|
@ -27,6 +27,6 @@ extern "C" {
|
||||||
static test_static: c_int;
|
static test_static: c_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
static B: &'static c_int = &test_static;
|
static B: &'static c_int = unsafe { &test_static };
|
||||||
|
|
||||||
pub fn main() {}
|
pub fn main() {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue