Skip to content

Commit 0c95523

Browse files
committed
gccrs: Fix 128-bit non-decimal integer literal saturation
This patch replaces std::strtol with GNU MP (GMP) for arbitrary-precision parsing. Additionally, the hex literal dispatcher was corrected to avoid prepending "0x" to the internal string, ensuring compatibility with mpz_set_str. gcc/rust/ChangeLog: * lex/rust-lex.cc (Lexer::parse_non_decimal_int_literal): Use GMP for base conversion to support 128-bit literals. (Lexer::parse_non_decimal_int_literals): Fix hex prefix inconsistency by passing pure string. gcc/testsuite/ChangeLog: * rust/execute/non_decimal_128_saturation.rs: New test. Signed-off-by: Enes Cevik <nsvke@proton.me>
1 parent 7b26919 commit 0c95523

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

gcc/rust/lex/rust-lex.cc

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2271,9 +2271,13 @@ Lexer::parse_non_decimal_int_literal (location_t loc, IsDigitFunc is_digit_func,
22712271
}
22722272

22732273
// convert value to decimal representation
2274-
long dec_num = std::strtol (existent_str.c_str (), nullptr, base);
2275-
2276-
existent_str = std::to_string (dec_num);
2274+
mpz_t dec_num;
2275+
mpz_init (dec_num);
2276+
mpz_set_str (dec_num, existent_str.c_str (), base);
2277+
char *s = mpz_get_str (NULL, 10, dec_num);
2278+
existent_str = s;
2279+
free (s);
2280+
mpz_clear (dec_num);
22772281

22782282
// parse in type suffix if it exists
22792283
auto type_suffix_pair = parse_in_type_suffix ();
@@ -2313,7 +2317,8 @@ Lexer::parse_non_decimal_int_literals (location_t loc)
23132317
if (current_char == 'x')
23142318
{
23152319
// hex (integer only)
2316-
return parse_non_decimal_int_literal (loc, is_x_digit, str + "x", 16);
2320+
return parse_non_decimal_int_literal (loc, is_x_digit, std::move (str),
2321+
16);
23172322
}
23182323
else if (current_char == 'o')
23192324
{
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// { dg-do run }
2+
// { dg-require-effective-target lp64 }
3+
// { dg-options "-O0" }
4+
#![feature(no_core)]
5+
#![no_core]
6+
7+
fn main() -> i32 {
8+
let hex_val: u128 = 0x1_0000_0000_0000_0000_u128;
9+
if (hex_val >> 64) as u8 != 1 {
10+
return 1;
11+
}
12+
13+
let bin_val: u128 =
14+
0b1_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_u128;
15+
if (bin_val >> 64) as u8 != 1 {
16+
return 1;
17+
}
18+
19+
let oct_val: u128 = 0o2_000_000_000_000_000_000_000_u128;
20+
if (oct_val >> 64) as u8 != 1 {
21+
return 1;
22+
}
23+
0
24+
}

0 commit comments

Comments
 (0)