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

Define UB in float-to-int casts to saturate #71269

Merged
merged 4 commits into from May 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/mir/rvalue.rs
Expand Up @@ -768,7 +768,7 @@ fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
) -> Bx::Value {
let fptosui_result = if signed { bx.fptosi(x, int_ty) } else { bx.fptoui(x, int_ty) };

if !bx.cx().sess().opts.debugging_opts.saturating_float_casts {
if let Some(false) = bx.cx().sess().opts.debugging_opts.saturating_float_casts {
return fptosui_result;
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_interface/tests.rs
Expand Up @@ -558,7 +558,7 @@ fn test_debugging_options_tracking_hash() {
tracked!(sanitizer, Some(Sanitizer::Address));
tracked!(sanitizer_memory_track_origins, 2);
tracked!(sanitizer_recover, vec![Sanitizer::Address]);
tracked!(saturating_float_casts, true);
tracked!(saturating_float_casts, Some(true));
tracked!(share_generics, Some(true));
tracked!(show_span, Some(String::from("abc")));
tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1));
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_session/options.rs
Expand Up @@ -936,9 +936,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"enable origins tracking in MemorySanitizer"),
sanitizer_recover: Vec<Sanitizer> = (vec![], parse_sanitizer_list, [TRACKED],
"enable recovery for selected sanitizers"),
saturating_float_casts: bool = (false, parse_bool, [TRACKED],
saturating_float_casts: Option<bool> = (None, parse_opt_bool, [TRACKED],
"make float->int casts UB-free: numbers outside the integer type's range are clipped to \
the max/min integer respectively, and NaN is mapped to 0 (default: no)"),
Mark-Simulacrum marked this conversation as resolved.
Show resolved Hide resolved
the max/min integer respectively, and NaN is mapped to 0 (default: yes)"),
save_analysis: bool = (false, parse_bool, [UNTRACKED],
"write syntax and type analysis (in JSON format) information, in \
addition to normal output (default: no)"),
Expand Down
7 changes: 0 additions & 7 deletions src/librustc_typeck/check/demand.rs
Expand Up @@ -909,13 +909,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
cast_suggestion,
Applicability::MaybeIncorrect, // lossy conversion
);
err.warn(
"if the rounded value cannot be represented by the target \
integer type, including `Inf` and `NaN`, casting will cause \
undefined behavior \
(see issue #10184 <https://github.com/rust-lang/rust/issues/10184> \
for more information)",
);
}
true
}
Expand Down
12 changes: 6 additions & 6 deletions src/test/codegen/unchecked-float-casts.rs
@@ -1,7 +1,7 @@
// compile-flags: -C no-prepopulate-passes
// This file tests that we don't generate any code for saturation when using the
// unchecked intrinsics.

// This file tests that we don't generate any code for saturation if
// -Z saturating-float-casts is not enabled.
// compile-flags: -C opt-level=3

#![crate_type = "lib"]

Expand All @@ -12,7 +12,7 @@ pub fn f32_to_u32(x: f32) -> u32 {
// CHECK-NOT: fcmp
// CHECK-NOT: icmp
// CHECK-NOT: select
x as u32
unsafe { x.to_int_unchecked() }
}

// CHECK-LABEL: @f32_to_i32
Expand All @@ -22,7 +22,7 @@ pub fn f32_to_i32(x: f32) -> i32 {
// CHECK-NOT: fcmp
// CHECK-NOT: icmp
// CHECK-NOT: select
x as i32
unsafe { x.to_int_unchecked() }
}

#[no_mangle]
Expand All @@ -31,5 +31,5 @@ pub fn f64_to_u16(x: f64) -> u16 {
// CHECK-NOT: fcmp
// CHECK-NOT: icmp
// CHECK-NOT: select
x as u16
unsafe { x.to_int_unchecked() }
}