Skip to content

Commit 927d24e

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 6b891ee commit 927d24e

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-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: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// { dg-do run }
2+
// { dg-options "-O0" }
3+
#![feature(no_core)]
4+
#![no_core]
5+
6+
extern "C" {
7+
fn abort();
8+
}
9+
10+
pub fn main() -> i32 {
11+
unsafe {
12+
let hex_val: u128 = 0x10000000000000000_u128;
13+
if *((&hex_val as *const u128 as usize + 8) as *const u8) != 1 {
14+
abort();
15+
}
16+
17+
let bin_val: u128 =
18+
0b10000000000000000000000000000000000000000000000000000000000000000_u128;
19+
if *((&bin_val as *const u128 as usize + 8) as *const u8) != 1 {
20+
abort();
21+
}
22+
23+
let oct_val: u128 = 0o2000000000000000000000_u128;
24+
if *((&oct_val as *const u128 as usize + 8) as *const u8) != 1 {
25+
abort();
26+
}
27+
}
28+
0
29+
}

0 commit comments

Comments
 (0)