diff --git a/src/ir.cpp b/src/ir.cpp index eb7308e8f5..e6334d39e7 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -25957,16 +25957,10 @@ static IrInstGen *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstSrcIntCa return ira->codegen->invalid_inst_gen; } - if (instr_is_comptime(target)) { + if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeInt) { return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); } - if (dest_type->id == ZigTypeIdComptimeInt) { - ir_add_error(ira, &instruction->target->base, buf_sprintf("attempt to cast runtime value to '%s'", - buf_ptr(&dest_type->name))); - return ira->codegen->invalid_inst_gen; - } - return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type); } @@ -25975,7 +25969,7 @@ static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFlo if (type_is_invalid(dest_type)) return ira->codegen->invalid_inst_gen; - if (dest_type->id != ZigTypeIdFloat) { + if (dest_type->id != ZigTypeIdFloat && dest_type->id != ZigTypeIdComptimeFloat) { ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); return ira->codegen->invalid_inst_gen; @@ -26001,6 +25995,10 @@ static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFlo } } + if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeFloat) { + return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); + } + if (target->value->type->id != ZigTypeIdFloat) { ir_add_error(ira, &instruction->target->base, buf_sprintf("expected float type, found '%s'", buf_ptr(&target->value->type->name))); @@ -26064,6 +26062,12 @@ static IrInstGen *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstSrcI if (type_is_invalid(dest_type)) return ira->codegen->invalid_inst_gen; + if (dest_type->id != ZigTypeIdFloat && dest_type->id != ZigTypeIdComptimeFloat) { + ir_add_error(ira, &instruction->dest_type->base, + buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); + return ira->codegen->invalid_inst_gen; + } + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) return ira->codegen->invalid_inst_gen; @@ -26077,33 +26081,31 @@ static IrInstGen *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstSrcI return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, CastOpIntToFloat); } -static IrInstGen *ir_analyze_float_to_int(IrAnalyze *ira, IrInst* source_instr, - ZigType *dest_type, IrInstGen *operand, AstNode *operand_source_node) -{ - if (operand->value->type->id == ZigTypeIdComptimeInt) { - return ir_implicit_cast(ira, operand, dest_type); - } - - if (operand->value->type->id != ZigTypeIdFloat && operand->value->type->id != ZigTypeIdComptimeFloat) { - ir_add_error_node(ira, operand_source_node, buf_sprintf("expected float type, found '%s'", - buf_ptr(&operand->value->type->name))); - return ira->codegen->invalid_inst_gen; - } - - return ir_resolve_cast(ira, source_instr, operand, dest_type, CastOpFloatToInt); -} - static IrInstGen *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstSrcFloatToInt *instruction) { ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); if (type_is_invalid(dest_type)) return ira->codegen->invalid_inst_gen; - IrInstGen *operand = instruction->target->child; - if (type_is_invalid(operand->value->type)) + if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { + ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); + return ira->codegen->invalid_inst_gen; + } + + IrInstGen *target = instruction->target->child; + if (type_is_invalid(target->value->type)) return ira->codegen->invalid_inst_gen; - return ir_analyze_float_to_int(ira, &instruction->base.base, dest_type, operand, - instruction->target->base.source_node); + if (target->value->type->id == ZigTypeIdComptimeInt) { + return ir_implicit_cast(ira, target, dest_type); + } + + if (target->value->type->id != ZigTypeIdFloat && target->value->type->id != ZigTypeIdComptimeFloat) { + ir_add_error_node(ira, target->base.source_node, buf_sprintf("expected float type, found '%s'", + buf_ptr(&target->value->type->name))); + return ira->codegen->invalid_inst_gen; + } + + return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, CastOpFloatToInt); } static IrInstGen *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstSrcErrToInt *instruction) { diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 4b60deec1c..cbad5b882f 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,62 @@ const tests = @import("tests.zig"); const std = @import("std"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.addTest("invalid int casts", + \\export fn foo() void { + \\ var a: u32 = 2; + \\ _ = @intCast(comptime_int, a); + \\} + \\export fn bar() void { + \\ var a: u32 = 2; + \\ _ = @intToFloat(u32, a); + \\} + \\export fn baz() void { + \\ var a: u32 = 2; + \\ _ = @floatToInt(u32, a); + \\} + \\export fn qux() void { + \\ var a: u32 = 2; + \\ _ = @intCast(comptime_int, a); + \\} + , &[_][]const u8{ + "tmp.zig:3:32: error: expected type 'comptime_int', found 'u32'", + "tmp.zig:3:9: note: referenced here", + "tmp.zig:7:21: error: expected float type, found 'u32'", + "tmp.zig:7:9: note: referenced here", + "tmp.zig:11:26: error: expected float type, found 'u32'", + "tmp.zig:11:9: note: referenced here", + "tmp.zig:15:32: error: expected type 'comptime_int', found 'u32'", + "tmp.zig:15:9: note: referenced here", + }); + + cases.addTest("invalid float casts", + \\export fn foo() void { + \\ var a: f32 = 2; + \\ _ = @floatCast(comptime_float, a); + \\} + \\export fn bar() void { + \\ var a: f32 = 2; + \\ _ = @floatToInt(f32, a); + \\} + \\export fn baz() void { + \\ var a: f32 = 2; + \\ _ = @intToFloat(f32, a); + \\} + \\export fn qux() void { + \\ var a: f32 = 2; + \\ _ = @floatCast(comptime_float, a); + \\} + , &[_][]const u8{ + "tmp.zig:3:36: error: expected type 'comptime_float', found 'f32'", + "tmp.zig:3:9: note: referenced here", + "tmp.zig:7:21: error: expected integer type, found 'f32'", + "tmp.zig:7:9: note: referenced here", + "tmp.zig:11:26: error: expected int type, found 'f32'", + "tmp.zig:11:9: note: referenced here", + "tmp.zig:15:36: error: expected type 'comptime_float', found 'f32'", + "tmp.zig:15:9: note: referenced here", + }); + cases.addTest("invalid assignments", \\export fn entry1() void { \\ var a: []const u8 = "foo";