Skip to content

Commit 5744556

Browse files
committed
Added lint for #[deriving] structs and enums with unsafe pointers. #13032.
1 parent c83994e commit 5744556

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

src/librustc/middle/lint.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ pub enum Lint {
115115
DeprecatedOwnedVector,
116116

117117
Warnings,
118+
119+
RawPointerDeriving,
118120
}
119121

120122
pub fn level_to_str(lv: level) -> &'static str {
@@ -406,6 +408,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
406408
desc: "use of a `~[T]` vector",
407409
default: allow,
408410
}),
411+
412+
("raw_pointer_deriving",
413+
LintSpec {
414+
lint: RawPointerDeriving,
415+
desc: "uses of #[deriving] with raw pointers are rarely correct",
416+
default: warn,
417+
}),
409418
];
410419

411420
/*
@@ -959,6 +968,37 @@ fn check_heap_item(cx: &Context, it: &ast::Item) {
959968
}
960969
}
961970

971+
struct RawPtrDerivingVisitor<'a> {
972+
cx: &'a Context<'a>
973+
}
974+
975+
impl<'a> Visitor<()> for RawPtrDerivingVisitor<'a> {
976+
fn visit_ty(&mut self, ty: &ast::Ty, _: ()) {
977+
static MSG: &'static str = "use of `#[deriving]` with a raw pointer";
978+
match ty.node {
979+
ast::TyPtr(..) => self.cx.span_lint(RawPointerDeriving, ty.span, MSG),
980+
_ => {}
981+
}
982+
visit::walk_ty(self, ty, ());
983+
}
984+
// explicit override to a no-op to reduce code bloat
985+
fn visit_expr(&mut self, _: &ast::Expr, _: ()) {}
986+
fn visit_block(&mut self, _: &ast::Block, _: ()) {}
987+
}
988+
989+
fn check_raw_ptr_deriving(cx: &Context, item: &ast::Item) {
990+
if !attr::contains_name(item.attrs.as_slice(), "deriving") {
991+
return
992+
}
993+
match item.node {
994+
ast::ItemStruct(..) | ast::ItemEnum(..) => {
995+
let mut visitor = RawPtrDerivingVisitor { cx: cx };
996+
visit::walk_item(&mut visitor, item, ());
997+
}
998+
_ => {}
999+
}
1000+
}
1001+
9621002
static crate_attrs: &'static [&'static str] = &[
9631003
"crate_type", "feature", "no_start", "no_main", "no_std", "crate_id",
9641004
"desc", "comment", "license", "copyright", // not used in rustc now
@@ -1585,6 +1625,7 @@ impl<'a> Visitor<()> for Context<'a> {
15851625
check_heap_item(cx, it);
15861626
check_missing_doc_item(cx, it);
15871627
check_attrs_usage(cx, it.attrs.as_slice());
1628+
check_raw_ptr_deriving(cx, it);
15881629

15891630
cx.visit_ids(|v| v.visit_item(it, ()));
15901631

src/librustc/middle/ty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ pub struct t_box_ {
384384
// alive, and using ty::get is unsafe when the ctxt is no longer alive.
385385
enum t_opaque {}
386386

387+
#[allow(raw_pointer_deriving)]
387388
#[deriving(Clone, Eq, TotalEq, Hash)]
388389
pub struct t { priv inner: *t_opaque }
389390

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#[feature(struct_variant)];
12+
#[allow(dead_code)];
13+
#[deny(raw_pointer_deriving)];
14+
15+
#[deriving(Clone)]
16+
struct Foo {
17+
x: *int //~ ERROR use of `#[deriving]` with a raw pointer
18+
}
19+
20+
#[deriving(Clone)]
21+
struct Bar(*mut int); //~ ERROR use of `#[deriving]` with a raw pointer
22+
23+
#[deriving(Clone)]
24+
enum Baz {
25+
A(*int), //~ ERROR use of `#[deriving]` with a raw pointer
26+
B { x: *mut int } //~ ERROR use of `#[deriving]` with a raw pointer
27+
}
28+
29+
#[deriving(Clone)]
30+
struct Buzz {
31+
x: (*int, //~ ERROR use of `#[deriving]` with a raw pointer
32+
*uint) //~ ERROR use of `#[deriving]` with a raw pointer
33+
}
34+
35+
fn main() {}

0 commit comments

Comments
 (0)