diff --git a/vlib/builtin/int_test.v b/vlib/builtin/int_test.v index 8bafd8fefe..7c162f31a9 100644 --- a/vlib/builtin/int_test.v +++ b/vlib/builtin/int_test.v @@ -268,3 +268,12 @@ fn test_int_max() { assert int_max(-5, 5) == 5 assert int_max(5, -5) == 5 } + +fn test_big_int() { + x := i64(2147483647) + if x > -2147483649 && x < 2147483648 { + assert true + } else { + assert false + } +} diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 950599f36e..a69f57cdaa 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3184,13 +3184,6 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ g.write('*') } } - if expr is ast.IntegerLiteral { - if expected_type in [ast.u64_type, ast.u32_type, ast.u16_type] && expr.val[0] != `-` { - g.expr(expr) - g.write('U') - return - } - } if (exp_sym.kind == .function && !expected_type.has_option_or_result()) || (g.inside_struct_init && expected_type == ast.voidptr_type && expected_type != got_type_raw && expr !is ast.StructInit) { @@ -3814,6 +3807,13 @@ fn (mut g Gen) expr(node_ ast.Expr) { g.write2('-0', node.val[3..]) } else { g.write(node.val) + val_type := determine_integer_literal_type(node) + if val_type in [ast.u32_type, ast.u64_type] { + g.write('U') + } + if val_type in [ast.i64_type, ast.u64_type] { + g.write('LL') + } } } ast.IsRefType { @@ -5670,13 +5670,6 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) { } } g.expr(node.expr) - if node.expr is ast.IntegerLiteral { - if node_typ in [ast.u64_type, ast.u32_type, ast.u16_type] { - if !node.expr.val.starts_with('-') { - g.write('U') - } - } - } g.write('))') } } @@ -8519,3 +8512,43 @@ fn (mut g Gen) check_noscan(elem_typ ast.Type) string { } return '' } + +const hi_32_mask = u64(0xFFFFFFFF00000000) +const lo_32_mask = u64(0x00000000FFFFFFFF) +const sign_bit_32 = u32(0x80000000) +const sign_bit_64 = u64(0x8000000000000000) + +fn determine_integer_literal_type(node ast.IntegerLiteral) ast.Type { + is_negative := node.val.starts_with('-') + if is_negative { + uval := node.val.i64() + high32 := u32(uval >> 32) + low32 := u32(uval) + // Check if high 32 bits are all ones (0xFFFFFFFF) + // This indicates a 32-bit negative number in two's complement + high32_all_ones := high32 == u32(0xFFFFFFFF) + // Check if the sign bit (bit 31) is set in low 32 bits + // This confirms the number is negative in 32-bit context + low32_sign_bit_set := (low32 & sign_bit_32) != 0 + // If both conditions are true, it's a 32-bit signed integer (i32) + // Otherwise, it requires 64-bit representation (i64) + return if high32_all_ones && low32_sign_bit_set { ast.i32_type } else { ast.i64_type } + } else { + uval := node.val.u64() + high32_all_zero := (uval & hi_32_mask) == 0 + if high32_all_zero { + low32 := u32(uval) + // Check if sign bit (bit 31) is clear (0) + // This indicates the number fits in 31 bits (signed 32-bit positive) + low32_sign_bit_clear := (low32 & sign_bit_32) == 0 + // If sign bit is clear, it's a signed 32-bit integer (i32) + // Otherwise, it's an unsigned 32-bit integer (u32) + return if low32_sign_bit_clear { ast.i32_type } else { ast.u32_type } + } else { + sign_bit_clear := (uval & sign_bit_64) == 0 + // If sign bit is clear, it's a signed 64-bit integer (i64) + // Otherwise, it's an unsigned 64-bit integer (u64) + return if sign_bit_clear { ast.i64_type } else { ast.u64_type } + } + } +} diff --git a/vlib/v/gen/c/testdata/globals_with_weak_tag.c.must_have b/vlib/v/gen/c/testdata/globals_with_weak_tag.c.must_have index 8dd68e4e51..7b9dcd8f17 100644 --- a/vlib/v/gen/c/testdata/globals_with_weak_tag.c.must_have +++ b/vlib/v/gen/c/testdata/globals_with_weak_tag.c.must_have @@ -1,7 +1,7 @@ -u64 VWEAK abc = ((u64)(1U)); // global -u64 xyz = ((u64)(2U)); // global -u64 VWEAK weak_1 = ((u64)(4U)); // global -u64 VWEAK weak_2 = ((u64)(5U)); // global +u64 VWEAK abc = ((u64)(1)); // global +u64 xyz = ((u64)(2)); // global +u64 VWEAK weak_1 = ((u64)(4)); // global +u64 VWEAK weak_2 = ((u64)(5)); // global VV_LOC int main__a_weak_function(void); VV_LOC void main__main(void);