Skip to content

Rollup of 4 pull requests #135569

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

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644

[dependencies]
core = { path = "../core" }
-compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std', 'no-f16-f128'] }
-compiler_builtins = { version = "=0.1.144", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.144", features = ['rustc-dep-of-std', 'no-f16-f128'] }

[dev-dependencies]
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
Expand Down
31 changes: 23 additions & 8 deletions compiler/rustc_lint/src/types/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,20 +204,35 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static
match t.kind() {
ty::Uint(ty::UintTy::Usize) | ty::Int(ty::IntTy::Isize) => None,
ty::Uint(_) => Some(Integer::fit_unsigned(val).uint_ty_str()),
ty::Int(_) if negative => Some(Integer::fit_signed(-(val as i128)).int_ty_str()),
ty::Int(int) => {
let signed = Integer::fit_signed(val as i128);
let unsigned = Integer::fit_unsigned(val);
Some(if Some(unsigned.size().bits()) == int.bit_width() {
unsigned.uint_ty_str()
ty::Int(_) => {
let signed = literal_to_i128(val, negative).map(Integer::fit_signed);
if negative {
signed.map(Integer::int_ty_str)
} else {
signed.int_ty_str()
})
let unsigned = Integer::fit_unsigned(val);
Some(if let Some(signed) = signed {
if unsigned.size() < signed.size() {
unsigned.uint_ty_str()
} else {
signed.int_ty_str()
}
} else {
unsigned.uint_ty_str()
})
}
}
_ => None,
}
}

fn literal_to_i128(val: u128, negative: bool) -> Option<i128> {
if negative {
(val <= i128::MAX as u128 + 1).then(|| val.wrapping_neg() as i128)
} else {
val.try_into().ok()
}
}

fn lint_int_literal<'tcx>(
cx: &LateContext<'tcx>,
type_limits: &TypeLimits,
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_target/src/callconv/wasm.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use rustc_abi::{BackendRepr, Float, Integer, Primitive};

use crate::abi::call::{ArgAbi, FnAbi};
use crate::abi::{HasDataLayout, TyAbiInterface};

Expand Down Expand Up @@ -27,6 +29,16 @@ where
if ret.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, ret) {
ret.make_indirect();
}

// `long double`, `__int128_t` and `__uint128_t` use an indirect return
if let BackendRepr::Scalar(scalar) = ret.layout.backend_repr {
match scalar.primitive() {
Primitive::Int(Integer::I128, _) | Primitive::Float(Float::F128) => {
ret.make_indirect();
}
_ => {}
}
}
}

fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
Expand Down
4 changes: 2 additions & 2 deletions library/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ dependencies = [

[[package]]
name = "compiler_builtins"
version = "0.1.143"
version = "0.1.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c85ba2077e3eab3dd81be4ece6b7fb2ad0887c1fb813e9a45400baf75c6c7c29"
checksum = "d18a7b7b5a56aa131e62314b4d862c9f6aa2860f615f3770094ec9064d7ec572"
dependencies = [
"cc",
"rustc-std-workspace-core",
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ edition = "2021"

[dependencies]
core = { path = "../core" }
compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "=0.1.144", features = ['rustc-dep-of-std'] }

[dev-dependencies]
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
Expand Down
2 changes: 1 addition & 1 deletion library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core", public = true }
compiler_builtins = { version = "=0.1.143" }
compiler_builtins = { version = "=0.1.144" }
unwind = { path = "../unwind" }
hashbrown = { version = "0.15", default-features = false, features = [
'rustc-dep-of-std',
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sync/lazy_lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ union Data<T, F> {
/// ```
/// use std::sync::LazyLock;
///
/// // n.b. static items do not call [`Drop`] on program termination, so this won't be deallocated.
/// // Note: static items do not call [`Drop`] on program termination, so this won't be deallocated.
/// // this is fine, as the OS can deallocate the terminated program faster than we can free memory
/// // but tools like valgrind might report "memory leaks" as it isn't obvious this is intentional.
/// static DEEP_THOUGHT: LazyLock<String> = LazyLock::new(|| {
Expand Down
49 changes: 49 additions & 0 deletions tests/codegen/f128-wasm32-callconv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//! Verify that Rust implements the expected calling convention for `f128`

//@ add-core-stubs
//@ compile-flags: --target wasm32-wasip1
//@ needs-llvm-components: webassembly

#![crate_type = "lib"]
#![no_std]
#![no_core]
#![feature(no_core, lang_items, f128)]

extern crate minicore;

extern "C" {
fn extern_call(arg0: f128);
fn extern_ret() -> f128;
}

#[no_mangle]
pub extern "C" fn pass(_arg0: u32, arg1: f128) {
// CHECK-LABEL: @pass(
// an f128 is passed via registers
// CHECK-SAME: fp128 noundef %arg1
// CHECK: call void @extern_call
unsafe { extern_call(arg1) };
}

// Check that we produce the correct return ABI
#[no_mangle]
pub extern "C" fn ret(_arg0: u32, arg1: f128) -> f128 {
// CHECK-LABEL: @ret(
// but an f128 is returned via the stack
// CHECK-SAME: sret
// CHECK: store fp128 %arg1
// CHECK-NEXT: ret void
arg1
}

// Check that we consume the correct return ABI
#[no_mangle]
pub extern "C" fn forward(dst: *mut f128) {
// CHECK-LABEL: @forward
// CHECK-SAME: ptr{{.*}} %dst)
// without optimizatons, an intermediate alloca is used
// CHECK: call void @extern_ret
// CHECK: store fp128
// CHECK: ret void
unsafe { *dst = extern_ret() };
}
49 changes: 49 additions & 0 deletions tests/codegen/i128-wasm32-callconv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//! Verify that Rust implements the expected calling convention for `i128`/`u128`.

//@ add-core-stubs
//@ compile-flags: --target wasm32-wasip1
//@ needs-llvm-components: webassembly

#![crate_type = "lib"]
#![no_std]
#![no_core]
#![feature(no_core, lang_items)]

extern crate minicore;

extern "C" {
fn extern_call(arg0: i128);
fn extern_ret() -> i128;
}

#[no_mangle]
pub extern "C" fn pass(_arg0: u32, arg1: i128) {
// CHECK-LABEL: @pass(
// an i128 is passed via registers
// CHECK-SAME: i128 noundef %arg1
// CHECK: call void @extern_call
unsafe { extern_call(arg1) };
}

// Check that we produce the correct return ABI
#[no_mangle]
pub extern "C" fn ret(_arg0: u32, arg1: i128) -> i128 {
// CHECK-LABEL: @ret(
// but an i128 is returned via the stack
// CHECK-SAME: sret
// CHECK: store i128 %arg1
// CHECK-NEXT: ret void
arg1
}

// Check that we consume the correct return ABI
#[no_mangle]
pub extern "C" fn forward(dst: *mut i128) {
// CHECK-LABEL: @forward
// CHECK-SAME: ptr{{.*}} %dst)
// without optimizatons, an intermediate alloca is used
// CHECK: call void @extern_ret
// CHECK: store i128
// CHECK: ret void
unsafe { *dst = extern_ret() };
}
26 changes: 26 additions & 0 deletions tests/ui/lint/type-overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,46 @@

fn main() {
let error = 255i8; //~WARNING literal out of range for `i8`
//~^ HELP consider using the type `u8` instead

let ok = 0b1000_0001; // should be ok -> i32
let ok = 0b0111_1111i8; // should be ok -> 127i8

let fail = 0b1000_0001i8; //~WARNING literal out of range for `i8`
//~^ HELP consider using the type `u8` instead
//~| HELP consider using the type `u8` for the literal and cast it to `i8`

let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for `i64`
//~^ HELP consider using the type `u64` instead
//~| HELP consider using the type `u64` for the literal and cast it to `i64`

let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for `u32`
//~^ HELP consider using the type `u64` instead

let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000;
//~^ WARNING literal out of range for `i128`
//~| HELP consider using the type `u128` instead
//~| HELP consider using the type `u128` for the literal and cast it to `i128`

let fail = 0x8000_0000_0000_0000_0000_0000_0000_0000;
//~^ WARNING literal out of range for `i32`
//~| HELP consider using the type `u128` instead

let fail = -0x8000_0000_0000_0000_0000_0000_0000_0000; // issue #131849
//~^ WARNING literal out of range for `i32`
//~| HELP consider using the type `i128` instead

let fail = -0x8000_0000_0000_0000_0000_0000_0000_0001i128;
//~^ WARNING literal out of range for `i128`

let fail = 340282366920938463463374607431768211455i8;
//~^ WARNING literal out of range for `i8`
//~| HELP consider using the type `u128` instead

let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for `i32`
//~| HELP consider using the type `u64` instead
//~| HELP

let fail = -0b1111_1111i8; //~WARNING literal out of range for `i8`
//~| HELP consider using the type `i16` instead
}
53 changes: 45 additions & 8 deletions tests/ui/lint/type-overflow.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ LL | #![warn(overflowing_literals)]
| ^^^^^^^^^^^^^^^^^^^^

warning: literal out of range for `i8`
--> $DIR/type-overflow.rs:10:16
--> $DIR/type-overflow.rs:11:16
|
LL | let fail = 0b1000_0001i8;
| ^^^^^^^^^^^^^
Expand All @@ -29,7 +29,7 @@ LL | let fail = 0b1000_0001u8 as i8;
| ~~~~~~~~~~~~~~~~~~~

warning: literal out of range for `i64`
--> $DIR/type-overflow.rs:12:16
--> $DIR/type-overflow.rs:15:16
|
LL | let fail = 0x8000_0000_0000_0000i64;
| ^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -45,15 +45,15 @@ LL | let fail = 0x8000_0000_0000_0000u64 as i64;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

warning: literal out of range for `u32`
--> $DIR/type-overflow.rs:14:16
--> $DIR/type-overflow.rs:19:16
|
LL | let fail = 0x1_FFFF_FFFFu32;
| ^^^^^^^^^^^^^^^^ help: consider using the type `u64` instead: `0x1_FFFF_FFFFu64`
|
= note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into the type `u32` and will become `4294967295u32`

warning: literal out of range for `i128`
--> $DIR/type-overflow.rs:16:22
--> $DIR/type-overflow.rs:22:22
|
LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -66,26 +66,63 @@ LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000u128 as i128;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

warning: literal out of range for `i32`
--> $DIR/type-overflow.rs:19:16
--> $DIR/type-overflow.rs:27:16
|
LL | let fail = 0x8000_0000_0000_0000_0000_0000_0000_0000;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into the type `i32` and will become `0i32`
= help: consider using the type `u128` instead

warning: literal out of range for `i32`
--> $DIR/type-overflow.rs:31:17
|
LL | let fail = -0x8000_0000_0000_0000_0000_0000_0000_0000; // issue #131849
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into the type `i32`
= note: and the value `-0x8000_0000_0000_0000_0000_0000_0000_0000` will become `0i32`
= help: consider using the type `i128` instead

warning: literal out of range for `i128`
--> $DIR/type-overflow.rs:35:17
|
LL | let fail = -0x8000_0000_0000_0000_0000_0000_0000_0001i128;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0001i128` (decimal `170141183460469231731687303715884105729`) does not fit into the type `i128`
= note: and the value `-0x8000_0000_0000_0000_0000_0000_0000_0001i128` will become `170141183460469231731687303715884105727i128`

warning: literal out of range for `i8`
--> $DIR/type-overflow.rs:38:16
|
LL | let fail = 340282366920938463463374607431768211455i8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the literal `340282366920938463463374607431768211455i8` does not fit into the type `i8` whose range is `-128..=127`
= help: consider using the type `u128` instead

warning: literal out of range for `i32`
--> $DIR/type-overflow.rs:42:16
|
LL | let fail = 0x8FFF_FFFF_FFFF_FFFE;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into the type `i32` and will become `-2i32`
= help: consider using the type `i128` instead
= help: consider using the type `u64` instead
help: to use as a negative number (decimal `-2`), consider using the type `u32` for the literal and cast it to `i32`
|
LL | let fail = 0x8FFF_FFFF_FFFF_FFFEu32 as i32;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

warning: literal out of range for `i8`
--> $DIR/type-overflow.rs:21:17
--> $DIR/type-overflow.rs:46:17
|
LL | let fail = -0b1111_1111i8;
| ^^^^^^^^^^^^^ help: consider using the type `i16` instead: `0b1111_1111i16`
|
= note: the literal `0b1111_1111i8` (decimal `255`) does not fit into the type `i8`
= note: and the value `-0b1111_1111i8` will become `1i8`

warning: 7 warnings emitted
warning: 11 warnings emitted

Loading