{"action":"opened","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/28382","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/28382/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/28382/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/28382/events","html_url":"https://github.com/rust-lang/rust/issues/28382","id":106196948,"number":28382,"title":"Float to integer casts can have undefined results","user":{"login":"Aatch","id":342416,"avatar_url":"https://avatars.githubusercontent.com/u/342416?v=3","gravatar_id":"","url":"https://api.github.com/users/Aatch","html_url":"https://github.com/Aatch","followers_url":"https://api.github.com/users/Aatch/followers","following_url":"https://api.github.com/users/Aatch/following{/other_user}","gists_url":"https://api.github.com/users/Aatch/gists{/gist_id}","starred_url":"https://api.github.com/users/Aatch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Aatch/subscriptions","organizations_url":"https://api.github.com/users/Aatch/orgs","repos_url":"https://api.github.com/users/Aatch/repos","events_url":"https://api.github.com/users/Aatch/events{/privacy}","received_events_url":"https://api.github.com/users/Aatch/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-09-13T03:20:37Z","updated_at":"2015-09-13T03:20:37Z","closed_at":null,"body":"By accident I came across an ICE from this code: `(-1.0 as usize,)`. The ICE is triggered by an assertion while building the constant tuple. The field has a value of `undef`.\r\n\r\nLooking into it, the two floating point to integer cast instructions, `fptoui` and `fptosi` have a very large surface for producing undefined values. Any time the result cannot fit into the destination type, the result is undefined. This means casting from a negative float to an unsigned integer is undefined and casting from a float with a value outside the range for the target integer type (signed or otherwise) is undefined.\r\n\r\nSome possible solutions:\r\n\r\n1. Treat it as an error always. This means generating an assertion before the cast, similar to how we generate assertions to check for divide-by-zero.\r\n2. Clamp the value. Casting from outside the valid range will clamp to one end of the range. so `-1.0 as u32` would produce `0`.\r\n4. A combination of both. Treat the case similarly to how we treat integer overflow and emit an assertion in debug builds, but omit them in release builds, falling back to the clamping behaviour.\r\n\r\nI'm personally leaning towards 3. Most of the time an invalid cast of this nature will be unintentional, so protecting against it seems reasonable. The problem is also similar enough to overflowing that handling it similarly seems reasonable.\r\n\r\n/cc @rust-lang/compiler @rust-lang/libs"}}