Skip to content
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

arithmetic-overflow checks during const-eval #23863

Merged
merged 16 commits into from
Apr 1, 2015

Conversation

pnkfelix
Copy link
Member

const_eval : add overflow-checking for {+, -, *, /, <<, >>}.

One tricky detail here: There is some duplication of labor between rustc::middle::const_eval and rustc_trans::trans::consts. It might be good to explore ways to try to factor out the common structure to the two passes (by abstracting over the particular value-representation used in the compile-time interpreter).


Update: Rebased atop #23841

Fix #22531

Fix #23030

Fix #23221

Fix #23235

@rust-highfive
Copy link
Collaborator

r? @alexcrichton

(rust_highfive has picked a reviewer for you, use r? to override)

@pnkfelix pnkfelix changed the title Arith oflo const eval arithmetic-overflow checks during const-eval Mar 30, 2015
@pnkfelix
Copy link
Member Author

cc @eddyb

(actually, I'd be happy to take a review from eddyb)

Also, eddyb: You may be concerned about collisions here with your own const-fn work. Feel free to recommend some ordering on how the two PR's land, or suggest some other strategy to avoid unnecessary rebasing effort.

@pnkfelix
Copy link
Member Author

r? @nikomatsakis

@eddyb
Copy link
Member

eddyb commented Mar 30, 2015

const fn is pretty simple, really, there won't be much churn I would have to deal with (I don't think).

As for the checks in trans: I did something else for div/rem: check_const invokes const_eval for those binops on integers and errors if evaluation fails.
Sadly, that doesn't work well in the presence of const fn and associated constants.

@nikomatsakis I wonder if recording "obligations" on constant evaluation would make sense - like where clauses, but implicit and working on values (either arguments of const fns or associated constants on type parameters).

if !oflo { Ok(const_uint(ret)) } else { signal!(e, SubuWithOverflow(a, b)) }

pub_fn_checked_op!{ const_int_checked_add(a: i64, b: i64,.. IntTy) {
int_arith_body overflowing_add const_int AddiWithOverflow(a, b)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the indentation levels here intentional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah it was so that the operator name (e.g. "add") would line up in both the method name and in the operator invocation.

Maybe I would have been better off using some well-placed calls to stringify!...

@nikomatsakis
Copy link
Contributor

r+ modulo the FIXME

@eddyb
Copy link
Member

eddyb commented Mar 31, 2015

@nikomatsakis Should we open a discussion about the interactions between trans::consts and const_eval somewhere else?

I personally prefer checking somewhere higher than trans, but in the end, what I am not particularly fond of is extracting values from LLVM for checking.

It works for this PR, and it's not enough to stop it from merging (we need those checks in beta), but I hope we can find a cleaner solution.

@pnkfelix
Copy link
Member Author

@bors r=nikomatsakis

@bors
Copy link
Contributor

bors commented Mar 31, 2015

📌 Commit e40d0de has been approved by nikomatsakis

@pnkfelix
Copy link
Member Author

@eddyb @nikomatsakis

Should we open a discussion about the interactions between trans::consts and const_eval somewhere else?

I just made this post on internals: http://internals.rust-lang.org/t/removing-const-eval-duplication-of-labor-between-librustc-and-librustc-trans/1786

so we can continue that conversation in a focused fashion there.

@pnkfelix
Copy link
Member Author

@bors r-

I want to check this in a cross-compiling environment, and perhaps land it in tandem with #23841 and perhaps a fix for #23890

@pnkfelix
Copy link
Member Author

(I have now rebased this atop #23841, but I am pretty sure that it is going to conflict with other PR's in the queue, namely #23549, so I am still holding off on putting back the r+ until I see if that lands or not.)

@bors
Copy link
Contributor

bors commented Mar 31, 2015

☔ The latest upstream changes (presumably #23549) made this pull request unmergeable. Please resolve the merge conflicts.

@pnkfelix
Copy link
Member Author

annoying: the error messages on some of my tests are different for 64-bit compile versus a cross-compiling 64-bit host/32-bit target. :(

Update: Well, being forced to fix this may yield an overall code cleanup. :)

…values.

Moved such overflow checking into one place (in `rustc::middle::ty`,
since it needs to be run on-demand during `const_eval` in some
scenarios), and revised `rustc_typeck` accordingly.

(Note that we only check for overflow if program did not provide a
discriminant value explicitly.)

Fix rust-lang#23030

Fix rust-lang#23221

Fix rust-lang#23235
@pnkfelix
Copy link
Member Author

pnkfelix commented Apr 1, 2015

r=nikomatsakis ; @alexcrichton says he will merge into next rollup.

@alexcrichton
Copy link
Member

@bors: r=nikomatsakis

@bors
Copy link
Contributor

bors commented Apr 1, 2015

📌 Commit 2a9de1d has been approved by nikomatsakis

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Apr 1, 2015
const_eval : add overflow-checking for {`+`, `-`, `*`, `/`, `<<`, `>>`}.

One tricky detail here: There is some duplication of labor between `rustc::middle::const_eval` and `rustc_trans::trans::consts`. It might be good to explore ways to try to factor out the common structure to the two passes (by abstracting over the particular value-representation used in the compile-time interpreter).

----

Update: Rebased atop rust-lang#23841

Fix rust-lang#22531

Fix rust-lang#23030

Fix rust-lang#23221

Fix rust-lang#23235
@bors bors merged commit 2a9de1d into rust-lang:master Apr 1, 2015
@andersk
Copy link
Contributor

andersk commented Apr 2, 2015

I think this caused #23968: !0u32/2 gives “error: attempted to divide with overflow in a constant expression [E0020]”.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment