-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Check inferred integer literals for overflows, closes #4220 #10018
Conversation
|
||
fn get_int_from_lit(lit: &lit) -> i64 { | ||
match lit.node { | ||
lit_int(n, _)| lit_int_unsuffixed(n) => return n, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
)|
→ ) |
I've updated the style issues. If this is a reasonable approach I could complete this patch in the next days. I think I should mention the original issue as well, #4220 |
@nikomatsakis Do you have an opinion about this? It's not a lint check, and I'm not sure why graydon suggested doing it in |
I'm still of the opinion that the proper way to do this is a lint. |
Thinking a bit more on this, I don't see how adding things into let x: i8 = 128; // ideally, would warn |
I moved to code to the linter and fixed the test. As it turns out, checking
is a tricky case. It's represented as Another thing I noticed: the overflow check for typed literals does handle edge cases correctly:
But I guess once the check for overflows is handled by the linter, we could remove the check in check_const.rs? https://github.com/mozilla/rust/blob/master/src/librustc/middle/check_const.rs#L206 |
Your point about overflow was precisely why I suggested the example. There is probably no great way to do this right now; I had in mind passing the information down via walk calls, or perhaps building up a (temporary) set of node-ids that are negated (i.e., the unary minus would insert its operand's id into the map, and ExprParen would propagate to its operand if it itself is in the map) -- this way you could just check whether the literal is in the map. As far as code in check_const.rs, I'd remove it, yes. It seems to be superseded by the lint check. |
My patch should pass down the information via walk calls, I hope I understood your intention correctly. Your test cases pass and I've removed the code from check_const.rs, but it seems like there were no tests for this. Should I add some to the tests in test/compile-fail/lint-type-overflow.rs ? |
} | ||
|
||
fn visit_expr(&mut self, e: @ast::Expr, _: ()) { | ||
fn visit_expr(&mut self, e: @ast::Expr, neg: bool) { | ||
let new_neg = match e.node { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation.
I'm not 100% sure we want to be adding a non- (Needs a rebase, btw.) |
(Also, in this case, a bare |
On Tue, Oct 29, 2013 at 03:19:09PM -0700, Florian Hahn wrote:
Cool, I'll take a look.
Definitely we need some tests -- particularly for edge cases! |
Ordinarily I'd say that this is exactly the kind of case where a My suggestion (which may well be overkill) is to add a field, but rather than making it a boolean, have its type be a In general though this looks great, exactly what I had in mind. |
Oh, and I think that |
Wouldn't that evalute to 128, which overflows an |
Yes. but so would:
and I don't intend to warn about that. In other words, we're doing a best effort thing, and I feel like if someone wrote something wacky like |
(Needs a rebase.) |
I've rebased, implemented the checks for uint (although maybe some code could be reused better, I'll look into that tomorrow) and added a couple of tests. |
ping @nikomatsakis |
One question -- @fhahn do you know if we have code anywhere (lexer maybe?) that checks for integer literals that don't fit within a |
After my patch, the
It warns that the comparision is useless for My guess would be, to only warn about the comparison and silence the warning about the literal, which would require passing the information from the comparison check to the overflow check. Should this be done by another field? |
I would be inclined to issue both warnings. You can annotate this by adding
underneath the line in question (the |
I've added the warnings to the two failing tests, they should pass now. But I was wondering if merging the type-limits and the type-overflow linter message would make sense.
In this case, the comparison is useless, because 128 does not fit into an
In this case, the warning would be "literal out of range for its type" instead of something like "addition is useless due to type limits" . Are logical operators special enough to have a separate warning? |
The idea for that link, I think, is usually for cases like |
Well, I see, there are other use cases for the type-limit lint. Compiling the tests for the std lib yields a few overflow warnings, I'l try to fix them tonight |
The checks are now handled by the linter
There was another error, when runnning the tests on gthe mac 32 bit buildbot. In an example in the docs, |
I've started working on this issue and pushed a small commit, which adds a range check for integer literals in `middle::const_eval` (no `uint` at the moment) At the moment, this patch is just a proof of concept, I'm not sure if there is a better function for the checks in `middle::const_eval`. This patch does not check for overflows after constant folding, eg: let x: i8 = 99 + 99;
Fix FP of single-element-loop closes rust-lang#10018 --- changelog: [`single_element_loop`]: No longer lints, if the loop contains a `break` or `continue` [rust-lang#10162](rust-lang/rust-clippy#10162) <!-- changelog_checked -->
I've started working on this issue and pushed a small commit, which adds a range check for integer literals in
middle::const_eval
(nouint
at the moment)At the moment, this patch is just a proof of concept, I'm not sure if there is a better function for the checks in
middle::const_eval
. This patch does not check for overflows after constant folding, eg: