Skip to content

Commit e9aab10

Browse files
author
asdf
committed
adding int type checks for assign and assign_op
1 parent 09bb07b commit e9aab10

File tree

1 file changed

+42
-8
lines changed

1 file changed

+42
-8
lines changed

src/librustc/middle/lint.rs

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ enum lint {
6565
non_camel_case_types,
6666
structural_records,
6767
type_limits,
68+
type_overflow,
6869
default_methods,
6970
deprecated_self,
7071

@@ -204,6 +205,11 @@ fn get_lint_dict() -> lint_dict {
204205
desc: ~"comparisons made useless by limits of the types involved",
205206
default: warn}),
206207

208+
(~"type_overflow",
209+
@{lint: type_overflow,
210+
desc: ~"the integer overflowed the container type",
211+
default: warn}),
212+
207213
(~"default_methods",
208214
@{lint: default_methods,
209215
desc: ~"allow default methods",
@@ -474,6 +480,10 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) {
474480
}
475481
}
476482

483+
pure fn is_valid_always<T: cmp::Ord>(v:T, min: T, max: T) -> bool {
484+
v <= max && v >= min
485+
}
486+
477487
pure fn rev_binop(binop: ast::binop) -> ast::binop {
478488
match binop {
479489
ast::lt => ast::gt,
@@ -505,7 +515,7 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) {
505515
}
506516
}
507517

508-
fn check_limits(cx: ty::ctxt, binop: ast::binop, l: &ast::expr,
518+
fn check_limits(cx: ty::ctxt, binop: Option<ast::binop>, l: &ast::expr,
509519
r: &ast::expr) -> bool {
510520
let (lit, expr, swap) = match (l.node, r.node) {
511521
(ast::expr_lit(_), _) => (l, r, true),
@@ -514,10 +524,12 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) {
514524
};
515525
// Normalize the binop so that the literal is always on the RHS in
516526
// the comparison
517-
let norm_binop = if (swap) {
518-
rev_binop(binop)
519-
} else {
520-
binop
527+
let norm_binop = |binop: ast::binop| {
528+
if (swap) {
529+
rev_binop(binop)
530+
} else {
531+
binop
532+
}
521533
};
522534
match ty::get(ty::expr_ty(cx, @*expr)).sty {
523535
ty::ty_int(int_ty) => {
@@ -531,7 +543,14 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) {
531543
},
532544
_ => fail
533545
};
534-
is_valid(norm_binop, lit_val, min, max)
546+
match binop {
547+
Some(binop_) => {
548+
is_valid(norm_binop(binop_), lit_val, min, max)
549+
}
550+
None => {
551+
is_valid_always(lit_val, min, max)
552+
}
553+
}
535554
}
536555
ty::ty_uint(uint_ty) => {
537556
let (min, max): (u64, u64) = uint_ty_range(uint_ty);
@@ -544,7 +563,14 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) {
544563
},
545564
_ => fail
546565
};
547-
is_valid(norm_binop, lit_val, min, max)
566+
match binop {
567+
Some(binop_) => {
568+
is_valid(norm_binop(binop_), lit_val, min, max)
569+
}
570+
None => {
571+
is_valid_always(lit_val, min, max)
572+
}
573+
}
548574
}
549575
_ => true
550576
}
@@ -563,12 +589,20 @@ fn check_item_type_limits(cx: ty::ctxt, it: @ast::item) {
563589
match e.node {
564590
ast::expr_binary(ref binop, @ref l, @ref r) => {
565591
if is_comparison(*binop)
566-
&& !check_limits(cx, *binop, l, r) {
592+
&& !check_limits(cx, Some(*binop), l, r) {
567593
cx.sess.span_lint(
568594
type_limits, e.id, it.id, e.span,
569595
~"comparison is useless due to type limits");
570596
}
571597
}
598+
ast::expr_assign(@ref l, @ref r) |
599+
ast::expr_assign_op(_ , @ref l, @ref r) => {
600+
if !check_limits(cx, None, l, r) {
601+
cx.sess.span_lint(
602+
type_limits, e.id, it.id, e.span,
603+
~"the integer overflowed the container type");
604+
}
605+
}
572606
_ => ()
573607
}
574608
},

0 commit comments

Comments
 (0)