mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
stage1: make @truncate
to an integer type of different sign an error at comptime too
This commit is contained in:
parent
ff0a15bb7a
commit
9ac6d28614
@ -19563,6 +19563,18 @@ static IrInstGen *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstSrcTrunc
|
||||
return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type);
|
||||
}
|
||||
|
||||
if (src_type->id != ZigTypeIdComptimeInt) {
|
||||
if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) {
|
||||
const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned";
|
||||
ir_add_error(ira, &target->base, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name)));
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
} else if (src_type->data.integral.bit_count > 0 && src_type->data.integral.bit_count < dest_type->data.integral.bit_count) {
|
||||
ir_add_error(ira, &target->base, buf_sprintf("type '%s' has fewer bits than destination type '%s'",
|
||||
buf_ptr(&src_type->name), buf_ptr(&dest_type->name)));
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
}
|
||||
|
||||
if (instr_is_comptime(target)) {
|
||||
ZigValue *val = ir_resolve_const(ira, target, UndefBad);
|
||||
if (val == nullptr)
|
||||
@ -19580,16 +19592,6 @@ static IrInstGen *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstSrcTrunc
|
||||
return result;
|
||||
}
|
||||
|
||||
if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) {
|
||||
const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned";
|
||||
ir_add_error(ira, &target->base, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name)));
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
} else if (src_type->data.integral.bit_count < dest_type->data.integral.bit_count) {
|
||||
ir_add_error(ira, &target->base, buf_sprintf("type '%s' has fewer bits than destination type '%s'",
|
||||
buf_ptr(&src_type->name), buf_ptr(&dest_type->name)));
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
|
||||
return ir_build_truncate_gen(ira, &instruction->base.base, dest_type, target);
|
||||
}
|
||||
|
||||
|
@ -24,13 +24,34 @@ test "truncate.u0.var" {
|
||||
try expect(z == 0);
|
||||
}
|
||||
|
||||
test "truncate sign mismatch but comptime known so it works anyway" {
|
||||
const x: u32 = 10;
|
||||
var result = @truncate(i8, x);
|
||||
try expect(result == 10);
|
||||
test "truncate i0 to larger integer allowed and has comptime known result" {
|
||||
var x: i0 = 0;
|
||||
const y = @truncate(i8, x);
|
||||
comptime try expect(y == 0);
|
||||
}
|
||||
|
||||
test "truncate.i0.literal" {
|
||||
var z = @truncate(i0, 0);
|
||||
try expect(z == 0);
|
||||
}
|
||||
|
||||
test "truncate.i0.const" {
|
||||
const c0: isize = 0;
|
||||
var z = @truncate(i0, c0);
|
||||
try expect(z == 0);
|
||||
}
|
||||
|
||||
test "truncate.i0.var" {
|
||||
var d: i8 = 2;
|
||||
var z = @truncate(i0, d);
|
||||
try expect(z == 0);
|
||||
}
|
||||
|
||||
test "truncate on comptime integer" {
|
||||
var x = @truncate(u16, 9999);
|
||||
try expect(x == 9999);
|
||||
var y = @truncate(u16, -21555);
|
||||
try expect(y == 0xabcd);
|
||||
var z = @truncate(i16, -65537);
|
||||
try expect(z == -1);
|
||||
}
|
||||
|
@ -6031,14 +6031,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
});
|
||||
|
||||
cases.add("truncate sign mismatch",
|
||||
\\fn f() i8 {
|
||||
\\export fn entry1() i8 {
|
||||
\\ var x: u32 = 10;
|
||||
\\ return @truncate(i8, x);
|
||||
\\}
|
||||
\\
|
||||
\\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
|
||||
\\export fn entry2() u8 {
|
||||
\\ var x: i32 = -10;
|
||||
\\ return @truncate(u8, x);
|
||||
\\}
|
||||
\\export fn entry3() i8 {
|
||||
\\ comptime var x: u32 = 10;
|
||||
\\ return @truncate(i8, x);
|
||||
\\}
|
||||
\\export fn entry4() u8 {
|
||||
\\ comptime var x: i32 = -10;
|
||||
\\ return @truncate(u8, x);
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:3:26: error: expected signed integer type, found 'u32'",
|
||||
"tmp.zig:7:26: error: expected unsigned integer type, found 'i32'",
|
||||
"tmp.zig:11:26: error: expected signed integer type, found 'u32'",
|
||||
"tmp.zig:15:26: error: expected unsigned integer type, found 'i32'",
|
||||
});
|
||||
|
||||
cases.add("try in function with non error return type",
|
||||
|
Loading…
Reference in New Issue
Block a user