Skip to content

Fix some dead-code pass bugs #10870

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 14, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions src/etc/combine-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,15 @@ def scrub(b):

c = open("tmp/run_pass_stage2.rc", "w")
i = 0
c.write("// AUTO-GENERATED FILE: DO NOT EDIT\n")
c.write("#[pkgid=\"run_pass_stage2#0.1\"];\n")
c.write("#[link(name=\"run_pass_stage2\", vers=\"0.1\")];\n")
c.write("#[feature(globs, macro_rules, struct_variant, managed_boxes)];\n")
c.write("#[allow(attribute_usage)];\n")
c.write(
"""
// AUTO-GENERATED FILE: DO NOT EDIT
#[pkgid=\"run_pass_stage2#0.1\"];
#[link(name=\"run_pass_stage2\", vers=\"0.1\")];
#[feature(globs, macro_rules, struct_variant, managed_boxes)];
#[allow(warnings)];
"""
)
for t in stage2_tests:
p = os.path.join(run_pass, t)
p = p.replace("\\", "\\\\")
Expand All @@ -56,15 +60,19 @@ def scrub(b):


d = open("tmp/run_pass_stage2_driver.rs", "w")
d.write("// AUTO-GENERATED FILE: DO NOT EDIT\n")
d.write("#[feature(globs, managed_boxes)];\n")
d.write("extern mod extra;\n")
d.write("extern mod run_pass_stage2;\n")
d.write("use run_pass_stage2::*;\n")
d.write("use std::io;\n")
d.write("use std::io::Writer;\n")
d.write("fn main() {\n")
d.write(" let mut out = io::stdout();\n")
d.write(
"""
// AUTO-GENERATED FILE: DO NOT EDIT
#[feature(globs, managed_boxes)];
extern mod extra;
extern mod run_pass_stage2;
use run_pass_stage2::*;
use std::io;
use std::io::Writer;
fn main() {
let mut out = io::stdout();
"""
)
i = 0
for t in stage2_tests:
p = os.path.join("test", "run-pass", t)
Expand Down
44 changes: 28 additions & 16 deletions src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ fn should_explore(tcx: ty::ctxt, def_id: ast::DefId) -> bool {
match tcx.items.find(&def_id.node) {
Some(&ast_map::node_item(..))
| Some(&ast_map::node_method(..))
| Some(&ast_map::node_foreign_item(..))
| Some(&ast_map::node_trait_method(..)) => true,
_ => false
}
Expand All @@ -61,11 +62,10 @@ impl MarkSymbolVisitor {
}
}

fn lookup_and_handle_definition(&mut self, id: &ast::NodeId,
span: codemap::Span) {
fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
let def = match self.tcx.def_map.find(id) {
Some(&def) => def,
None => self.tcx.sess.span_bug(span, "def ID not in def map?!"),
None => return
};
let def_id = match def {
ast::DefVariant(enum_id, _, _) => Some(enum_id),
Expand Down Expand Up @@ -107,8 +107,7 @@ impl MarkSymbolVisitor {
match item.node {
ast::item_fn(..)
| ast::item_ty(..)
| ast::item_static(..)
| ast::item_foreign_mod(_) => {
| ast::item_static(..) => {
visit::walk_item(self, item, ());
}
_ => ()
Expand All @@ -120,6 +119,9 @@ impl MarkSymbolVisitor {
ast_map::node_method(method, _, _) => {
visit::walk_block(self, method.body, ());
}
ast_map::node_foreign_item(foreign_item, _, _, _) => {
visit::walk_foreign_item(self, foreign_item, ());
}
_ => ()
}
}
Expand All @@ -129,9 +131,6 @@ impl Visitor<()> for MarkSymbolVisitor {

fn visit_expr(&mut self, expr: @ast::Expr, _: ()) {
match expr.node {
ast::ExprPath(_) | ast::ExprStruct(..) => {
self.lookup_and_handle_definition(&expr.id, expr.span);
}
ast::ExprMethodCall(..) => {
match self.method_map.find(&expr.id) {
Some(&typeck::method_map_entry {
Expand Down Expand Up @@ -160,12 +159,16 @@ impl Visitor<()> for MarkSymbolVisitor {
fn visit_ty(&mut self, typ: &ast::Ty, _: ()) {
match typ.node {
ast::ty_path(_, _, ref id) => {
self.lookup_and_handle_definition(id, typ.span);
self.lookup_and_handle_definition(id);
}
_ => visit::walk_ty(self, typ, ()),
}
}

fn visit_path(&mut self, _: &ast::Path, id: ast::NodeId, _: ()) {
self.lookup_and_handle_definition(&id);
}

fn visit_item(&mut self, _item: @ast::item, _: ()) {
// Do not recurse into items. These items will be added to the
// worklist and recursed into manually if necessary.
Expand Down Expand Up @@ -299,19 +302,31 @@ impl DeadVisitor {
}
false
}

fn warn_dead_code(&mut self, id: ast::NodeId,
span: codemap::Span, ident: &ast::Ident) {
self.tcx.sess.add_lint(dead_code, id, span,
format!("code is never used: `{}`",
token::ident_to_str(ident)));
}
}

impl Visitor<()> for DeadVisitor {
fn visit_item(&mut self, item: @ast::item, _: ()) {
let ctor_id = get_struct_ctor_id(item);
if !self.symbol_is_live(item.id, ctor_id) && should_warn(item) {
self.tcx.sess.add_lint(dead_code, item.id, item.span,
format!("code is never used: `{}`",
token::ident_to_str(&item.ident)));
self.warn_dead_code(item.id, item.span, &item.ident);
}
visit::walk_item(self, item, ());
}

fn visit_foreign_item(&mut self, fi: @ast::foreign_item, _: ()) {
if !self.symbol_is_live(fi.id, None) {
self.warn_dead_code(fi.id, fi.span, &fi.ident);
}
visit::walk_foreign_item(self, fi, ());
}

fn visit_fn(&mut self, fk: &visit::fn_kind,
_: &ast::fn_decl, block: ast::P<ast::Block>,
span: codemap::Span, id: ast::NodeId, _: ()) {
Expand All @@ -320,10 +335,7 @@ impl Visitor<()> for DeadVisitor {
visit::fk_method(..) => {
let ident = visit::name_of_fn(fk);
if !self.symbol_is_live(id, None) {
self.tcx.sess
.add_lint(dead_code, id, span,
format!("code is never used: `{}`",
token::ident_to_str(&ident)));
self.warn_dead_code(id, span, &ident);
}
}
_ => ()
Expand Down
7 changes: 6 additions & 1 deletion src/librustuv/uvll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@

#[allow(non_camel_case_types)]; // C types

use std::libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t, c_double};
use std::libc::{size_t, c_int, c_uint, c_void, c_char, c_double};
use std::libc::ssize_t;
use std::libc::{malloc, free};
use std::libc;
use std::vec;

#[cfg(test)]
use std::libc::uintptr_t;

pub use self::errors::*;

pub static OK: c_int = 0;
Expand Down Expand Up @@ -541,7 +544,9 @@ extern {
pub fn rust_is_ipv4_sockaddr(addr: *sockaddr) -> c_int;
pub fn rust_is_ipv6_sockaddr(addr: *sockaddr) -> c_int;

#[cfg(test)]
fn rust_uv_handle_type_max() -> uintptr_t;
#[cfg(test)]
fn rust_uv_req_type_max() -> uintptr_t;
fn rust_uv_get_udp_handle_from_send_req(req: *uv_udp_send_t) -> *uv_udp_t;

Expand Down
1 change: 1 addition & 0 deletions src/libstd/num/cmath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#[allow(missing_doc)];
#[allow(non_uppercase_statics)];
#[allow(dead_code)];

// function names are almost identical to C's libmath, a few have been
// renamed, grep for "rename:"
Expand Down
34 changes: 20 additions & 14 deletions src/test/compile-fail/lint-dead-code-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,7 @@ pub static pub_static: int = 0;
static priv_static: int = 0; //~ ERROR: code is never used
static used_static: int = 0;
pub static used_static2: int = used_static;

pub fn pub_fn() {
used_fn();
let used_struct1 = UsedStruct1 { x: 1 };
let used_struct2 = UsedStruct2(1);
let used_struct3 = UsedStruct3;
let e = foo3;
SemiUsedStruct::la_la_la();

}
fn priv_fn() { //~ ERROR: code is never used
let unused_struct = PrivStruct;
}
fn used_fn() {}
static USED_STATIC: int = 0;

pub type typ = ~UsedStruct4;
pub struct PubStruct();
Expand All @@ -59,6 +46,25 @@ pub enum pub_enum { foo1, bar1 }
enum priv_enum { foo2, bar2 } //~ ERROR: code is never used
enum used_enum { foo3, bar3 }

pub fn pub_fn() {
used_fn();
let used_struct1 = UsedStruct1 { x: 1 };
let used_struct2 = UsedStruct2(1);
let used_struct3 = UsedStruct3;
let e = foo3;
SemiUsedStruct::la_la_la();

let i = 1;
match i {
USED_STATIC => (),
_ => ()
}
}
fn priv_fn() { //~ ERROR: code is never used
let unused_struct = PrivStruct;
}
fn used_fn() {}

fn foo() { //~ ERROR: code is never used
bar();
let unused_enum = foo2;
Expand Down
22 changes: 19 additions & 3 deletions src/test/compile-fail/lint-dead-code-3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,27 @@ fn bar2() {
pub fn pub_fn() {
let foo2_struct = Foo2;
foo2_struct.foo2();

blah::baz();
}

// not warned because it's used in the parameter of `free` below
enum c_void {}
mod blah {
use std::libc::size_t;
// not warned because it's used in the parameter of `free` and return of
// `malloc` below, which are also used.
enum c_void {}

extern {
fn free(p: *c_void);
fn malloc(size: size_t) -> *c_void;
}

pub fn baz() {
unsafe { free(malloc(4)); }
}
}

enum c_void {} //~ ERROR: code is never used
extern {
fn free(p: *c_void);
fn free(p: *c_void); //~ ERROR: code is never used
}
1 change: 1 addition & 0 deletions src/test/compile-fail/warn-foreign-int-types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// except according to those terms.

#[forbid(ctypes)];
#[allow(dead_code)];

mod xx {
extern {
Expand Down