]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Add a usage pass to collect one-off analyses
authorHaitao Li <lihaitao@gmail.com>
Thu, 19 Jan 2012 02:52:26 +0000 (10:52 +0800)
committerHaitao Li <lihaitao@gmail.com>
Thu, 19 Jan 2012 09:27:44 +0000 (17:27 +0800)
This patch starts from move the analysis which checkes of probably
incorrectly usage of `int|uint` in native fn.

Issue #1543

man/rustc.1
src/comp/driver/driver.rs
src/comp/driver/rustc.rs
src/comp/driver/session.rs
src/comp/middle/check_usage.rs [new file with mode: 0644]
src/comp/middle/typeck.rs
src/comp/rustc.rc
src/test/compile-fail/warn-native-int-types.rs

index 2e05974451df2db38162112c035293c3d64530ba..20f24a1307aa5b29b1752824a24520017ade7e2d 100644 (file)
@@ -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"
index 9cb636716b99897799fe14ac4f47a28faa12132d..54ca5db4294914fd4419e9b0245584a803633b1e 100644 (file)
@@ -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"),
index bd4c04715989ed470b7adc3d9e7d30e025fa6f6b..fcd5f1852ae79e86096ff9fea226902d0ae9efd1 100644 (file)
@@ -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
index ad1da33673eb3c75f25c0f18b4c5b07b03aaa0d1..4b7154a5a99b0b9c6fe260a44c3028bb3c582f26 100644 (file)
@@ -33,6 +33,7 @@
      debuginfo: bool,
      extra_debuginfo: bool,
      verify: bool,
+     check_usage: bool,
      save_temps: bool,
      stats: bool,
      time_passes: bool,
diff --git a/src/comp/middle/check_usage.rs b/src/comp/middle/check_usage.rs
new file mode 100644 (file)
index 0000000..227e563
--- /dev/null
@@ -0,0 +1,59 @@
+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:
+//
index cb159a54c8ce7885ab20f89cd92a9375b1b72bf9..d16c0d315dd52a3cba437303c2a4c9cfd6ab6344 100644 (file)
@@ -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); }
index 22acbf9882428cc135464a484c4925572de00b66..f6405b963bad999b48df7df388c88685dca7e919 100644 (file)
@@ -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;
index 82836a37ea2154663bf5bda2f756509a50efb2e8..882b3038e8af781cdd392a25fa2a328400a7fb24 100644 (file)
@@ -5,5 +5,6 @@
 }
 
 fn main() {
-  "let compile fail to verify warning message" = 999;
+  // let it fail to verify warning message
+  fail
 }