From d5ad32f388557c6b1f709d59a940adfa3332a5f2 Mon Sep 17 00:00:00 2001 From: Kiet Tran Date: Wed, 11 Dec 2013 20:49:46 -0500 Subject: [PATCH 1/3] Check more live Path nodes in dead-code pass --- src/librustc/middle/dead.rs | 14 +++++----- src/test/compile-fail/lint-dead-code-1.rs | 34 +++++++++++++---------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 2327425c2ade0..a4e2c9742c8b0 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -61,11 +61,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), @@ -129,9 +128,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 { @@ -160,12 +156,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. diff --git a/src/test/compile-fail/lint-dead-code-1.rs b/src/test/compile-fail/lint-dead-code-1.rs index 7d7cbce6e89ac..6086484772ad6 100644 --- a/src/test/compile-fail/lint-dead-code-1.rs +++ b/src/test/compile-fail/lint-dead-code-1.rs @@ -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(); @@ -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; From 71ce559f7de6b50dde7af7cf22ff6c4b2942d3c1 Mon Sep 17 00:00:00 2001 From: Kiet Tran Date: Sat, 14 Dec 2013 00:08:26 -0500 Subject: [PATCH 2/3] Dead-code pass now marks and warns foreign items --- src/librustc/middle/dead.rs | 30 +++++++++++++------ src/librustuv/uvll.rs | 7 ++++- src/libstd/num/cmath.rs | 1 + src/test/compile-fail/lint-dead-code-3.rs | 22 ++++++++++++-- .../compile-fail/warn-foreign-int-types.rs | 1 + 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index a4e2c9742c8b0..9007e4bd90a9d 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -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 } @@ -106,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, ()); } _ => () @@ -119,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, ()); + } _ => () } } @@ -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, span: codemap::Span, id: ast::NodeId, _: ()) { @@ -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); } } _ => () diff --git a/src/librustuv/uvll.rs b/src/librustuv/uvll.rs index 09ebd29bc2216..c1d4d367e25f2 100644 --- a/src/librustuv/uvll.rs +++ b/src/librustuv/uvll.rs @@ -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; @@ -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; diff --git a/src/libstd/num/cmath.rs b/src/libstd/num/cmath.rs index 72051a933980e..5212b6fc15ec4 100644 --- a/src/libstd/num/cmath.rs +++ b/src/libstd/num/cmath.rs @@ -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:" diff --git a/src/test/compile-fail/lint-dead-code-3.rs b/src/test/compile-fail/lint-dead-code-3.rs index 8a5f239ed05c6..29d77959997f6 100644 --- a/src/test/compile-fail/lint-dead-code-3.rs +++ b/src/test/compile-fail/lint-dead-code-3.rs @@ -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 } diff --git a/src/test/compile-fail/warn-foreign-int-types.rs b/src/test/compile-fail/warn-foreign-int-types.rs index be6871ae6ffa7..726d778c3bb2b 100644 --- a/src/test/compile-fail/warn-foreign-int-types.rs +++ b/src/test/compile-fail/warn-foreign-int-types.rs @@ -9,6 +9,7 @@ // except according to those terms. #[forbid(ctypes)]; +#[allow(dead_code)]; mod xx { extern { From a67b8863c2d2e31f834e7a2b39b0afa6f8be7492 Mon Sep 17 00:00:00 2001 From: Kiet Tran Date: Sat, 14 Dec 2013 01:56:51 -0500 Subject: [PATCH 3/3] Suppress warnings in run-pass tests --- src/etc/combine-tests.py | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/etc/combine-tests.py b/src/etc/combine-tests.py index afecf0875c053..5ada1bfa63046 100755 --- a/src/etc/combine-tests.py +++ b/src/etc/combine-tests.py @@ -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("\\", "\\\\") @@ -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)