提交 327a15d5 编写于 作者: H Haitao Li

rustc: Add a usage pass to collect one-off analyses

This patch starts from move the analysis which checkes of probably
incorrectly usage of `int|uint` in native fn.

Issue #1543
上级 45c0651a
......@@ -123,6 +123,9 @@ Build a test harness.
.TP
\fB--warn-unused-imports\fR:
Warn about unnecessary imports.
.TP
\fB--no-check-usage\fR:
Disables various one-off usage analyses.
.SH "BUGS"
See \fBhttps://github.com/mozilla/rust/issues\fR for a list of known bugs.
.SH "AUTHOR"
......
......@@ -6,7 +6,7 @@
import syntax::{ast, codemap};
import front::attr;
import middle::{trans, resolve, freevars, kind, ty, typeck, fn_usage,
last_use};
last_use, check_usage};
import syntax::print::{pp, pprust};
import util::{ppaux, filesearch};
import back::link;
......@@ -203,6 +203,10 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
bind last_use::find_last_uses(crate, def_map, ref_map, ty_cx));
time(time_passes, "kind checking",
bind kind::check_crate(ty_cx, method_map, last_uses, crate));
if sess.opts.check_usage {
time(time_passes, "usage analyses",
bind check_usage::check_crate(ty_cx, crate));
}
if upto == cu_no_trans { ret {crate: crate, tcx: some(ty_cx), src: src}; }
let outputs = option::get(outputs);
......@@ -395,6 +399,7 @@ fn build_session_options(match: getopts::match,
} else { link::output_type_exe };
let libcore = !opt_present(match, "no-core");
let verify = !opt_present(match, "no-verify");
let check_usage = !opt_present(match, "no-usage-check");
let save_temps = opt_present(match, "save-temps");
let extra_debuginfo = opt_present(match, "xg");
let debuginfo = opt_present(match, "g") || extra_debuginfo;
......@@ -446,6 +451,7 @@ fn build_session_options(match: getopts::match,
debuginfo: debuginfo,
extra_debuginfo: extra_debuginfo,
verify: verify,
check_usage: check_usage,
save_temps: save_temps,
stats: stats,
time_passes: time_passes,
......@@ -514,6 +520,7 @@ fn opts() -> [getopts::opt] {
optopt("sysroot"), optopt("target"), optflag("stats"),
optflag("time-passes"), optflag("time-llvm-passes"),
optflag("no-verify"),
optflag("no-usage-check"),
optmulti("cfg"), optflag("test"),
optflag("no-core"),
optflag("lib"), optflag("bin"), optflag("static"), optflag("gc"),
......
......@@ -38,6 +38,7 @@ fn usage(argv0: str) {
--ls list the symbols defined by a crate file
-L <path> add a directory to the library search path
--no-verify suppress LLVM verification step (slight speedup)
--no-check-usage suppress various one-off usage analyses
--parse-only parse only; do not compile, assemble, or link
--no-trans run all passes except translation; no output
-g produce debug info
......
......@@ -33,6 +33,7 @@
debuginfo: bool,
extra_debuginfo: bool,
verify: bool,
check_usage: bool,
save_temps: bool,
stats: bool,
time_passes: bool,
......
import driver::session::session;
import middle::ty::ctxt;
import syntax::{ast, visit};
type crate_ctxt = {tcx: ty::ctxt};
fn check_native_fn(ccx: @crate_ctxt, decl: ast::fn_decl) {
let tys = vec::map(decl.inputs) {|a| a.ty };
for ty in (tys + [decl.output]) {
alt ty.node {
ast::ty_int(ast::ty_i.) {
ccx.tcx.sess.span_warn(
ty.span, "found rust type `int` in native module, while " +
"ctypes::c_int or ctypes::long should be used");
}
ast::ty_uint(ast::ty_u.) {
ccx.tcx.sess.span_warn(
ty.span, "found rust type `uint` in native module, while " +
"ctypes::c_uint or ctypes::ulong should be used");
}
_ { }
}
}
}
fn check_item(ccx: @crate_ctxt, it: @ast::item) {
alt it.node {
ast::item_native_mod(nmod) {
for ni in nmod.items {
alt ni.node {
ast::native_item_fn(decl, tps) {
check_native_fn(ccx, decl);
}
_ { }
}
}
}
_ {/* nothing to do */ }
}
}
fn check_crate(tcx: ty::ctxt, crate: @ast::crate) {
let ccx = @{tcx: tcx};
let visit = visit::mk_simple_visitor(@{
visit_item: bind check_item(ccx, _)
with *visit::default_simple_visitor()
});
visit::visit_crate(*crate, (), visit);
tcx.sess.abort_if_errors();
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//
......@@ -2680,25 +2680,6 @@ fn check_method(ccx: @crate_ctxt, method: @ast::method) {
check_fn(ccx, ast::proto_bare, method.decl, method.body, method.id, none);
}
fn check_native_fn(ccx: @crate_ctxt, decl: ast::fn_decl) {
let tys = vec::map(decl.inputs) {|a| a.ty };
for ty in (tys + [decl.output]) {
alt ty.node {
ast::ty_int(ast::ty_i) {
ccx.tcx.sess.span_warn(
ty.span, "found rust type `int` in native module, while " +
"ctypes::c_int or ctypes::long should be used");
}
ast::ty_uint(ast::ty_u) {
ccx.tcx.sess.span_warn(
ty.span, "found rust type `uint` in native module, while " +
"ctypes::c_uint or ctypes::ulong should be used");
}
_ { }
}
}
}
fn check_item(ccx: @crate_ctxt, it: @ast::item) {
alt it.node {
ast::item_const(_, e) { check_const(ccx, it.span, e, it.id); }
......@@ -2709,16 +2690,6 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
ast::item_res(decl, tps, body, dtor_id, _) {
check_fn(ccx, ast::proto_bare, decl, body, dtor_id, none);
}
ast::item_native_mod(nmod) {
for ni in nmod.items {
alt ni.node {
ast::native_item_fn(decl, tps) {
check_native_fn(ccx, decl);
}
_ { }
}
}
}
ast::item_impl(tps, _, ty, ms) {
ccx.self_infos += [self_impl(ast_ty_to_ty(ccx.tcx, m_check, ty))];
for m in ms { check_method(ccx, m); }
......
......@@ -29,6 +29,7 @@ mod middle {
mod fn_usage;
mod check_alt;
mod check_const;
mod check_usage;
mod mut;
mod alias;
mod last_use;
......
......@@ -5,5 +5,6 @@
}
fn main() {
"let compile fail to verify warning message" = 999;
// let it fail to verify warning message
fail
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册