authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-10 17:30:50+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-11 11:36:28+03:00
log2e037fd827487ce94ae0beb313a1f0536085d61e
tree273cedc57f162c4ece5c09788dfd3d6bb3d39171
parenteddc68ad9470730a2742084a29ab08fa5363c754

use correct cast function when doing `@floatCast` at comptime


3 files changed, 44 insertions(+), 21 deletions(-)

src/ir.cpp+13-7
...@@ -13020,7 +13020,11 @@ static IrInstGen *ir_resolve_cast(IrAnalyze *ira, IrInst *source_instr, IrInstGe...@@ -13020,7 +13020,11 @@ static IrInstGen *ir_resolve_cast(IrAnalyze *ira, IrInst *source_instr, IrInstGe
13020{13020{
13021 if (instr_is_comptime(value) || !type_has_bits(ira->codegen, wanted_type)) {13021 if (instr_is_comptime(value) || !type_has_bits(ira->codegen, wanted_type)) {
13022 IrInstGen *result = ir_const(ira, source_instr, wanted_type);13022 IrInstGen *result = ir_const(ira, source_instr, wanted_type);
13023 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, value->value, value->value->type,13023 ZigValue *val = ir_resolve_const(ira, value, UndefBad);
13024 if (val == nullptr)
13025 return ira->codegen->invalid_inst_gen;
13026
13027 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, val, val->type,
13024 result->value, wanted_type))13028 result->value, wanted_type))
13025 {13029 {
13026 return ira->codegen->invalid_inst_gen;13030 return ira->codegen->invalid_inst_gen;
...@@ -26680,6 +26684,10 @@ static IrInstGen *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstSrcIntCa...@@ -26680,6 +26684,10 @@ static IrInstGen *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstSrcIntCa
26680 }26684 }
2668126685
26682 if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeInt) {26686 if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeInt) {
26687 ZigValue *val = ir_resolve_const(ira, target, UndefBad);
26688 if (val == nullptr)
26689 return ira->codegen->invalid_inst_gen;
26690
26683 return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type);26691 return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type);
26684 }26692 }
2668526693
...@@ -26718,13 +26726,11 @@ static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFlo...@@ -26718,13 +26726,11 @@ static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFlo
26718 }26726 }
2671926727
26720 if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeFloat) {26728 if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeFloat) {
26721 return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type);26729 ZigValue *val = ir_resolve_const(ira, target, UndefBad);
26722 }26730 if (val == nullptr)
26731 return ira->codegen->invalid_inst_gen;
2672326732
26724 if (target->value->type->id != ZigTypeIdFloat) {26733 return ir_analyze_widen_or_shorten(ira, &instruction->target->base, target, dest_type);
26725 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected float type, found '%s'",
26726 buf_ptr(&target->value->type->name)));
26727 return ira->codegen->invalid_inst_gen;
26728 }26734 }
2672926735
26730 return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type);26736 return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type);
test/compile_errors.zig+18-14
...@@ -2,6 +2,22 @@ const tests = @import("tests.zig");...@@ -2,6 +2,22 @@ const tests = @import("tests.zig");
2const std = @import("std");2const std = @import("std");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.addTest("int/float conversion to comptime_int/float",
6 \\export fn foo() void {
7 \\ var a: f32 = 2;
8 \\ _ = @floatToInt(comptime_int, a);
9 \\}
10 \\export fn bar() void {
11 \\ var a: u32 = 2;
12 \\ _ = @intToFloat(comptime_float, a);
13 \\}
14 , &[_][]const u8{
15 "tmp.zig:3:35: error: unable to evaluate constant expression",
16 "tmp.zig:3:9: note: referenced here",
17 "tmp.zig:7:37: error: unable to evaluate constant expression",
18 "tmp.zig:7:9: note: referenced here",
19 });
20
5 cases.add("extern variable has no type",21 cases.add("extern variable has no type",
6 \\extern var foo;22 \\extern var foo;
7 \\pub export fn entry() void {23 \\pub export fn entry() void {
...@@ -90,19 +106,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -90,19 +106,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
90 \\ var a: u32 = 2;106 \\ var a: u32 = 2;
91 \\ _ = @floatToInt(u32, a);107 \\ _ = @floatToInt(u32, a);
92 \\}108 \\}
93 \\export fn qux() void {
94 \\ var a: u32 = 2;
95 \\ _ = @intCast(comptime_int, a);
96 \\}
97 , &[_][]const u8{109 , &[_][]const u8{
98 "tmp.zig:3:32: error: expected type 'comptime_int', found 'u32'",110 "tmp.zig:3:32: error: unable to evaluate constant expression",
99 "tmp.zig:3:9: note: referenced here",111 "tmp.zig:3:9: note: referenced here",
100 "tmp.zig:7:21: error: expected float type, found 'u32'",112 "tmp.zig:7:21: error: expected float type, found 'u32'",
101 "tmp.zig:7:9: note: referenced here",113 "tmp.zig:7:9: note: referenced here",
102 "tmp.zig:11:26: error: expected float type, found 'u32'",114 "tmp.zig:11:26: error: expected float type, found 'u32'",
103 "tmp.zig:11:9: note: referenced here",115 "tmp.zig:11:9: note: referenced here",
104 "tmp.zig:15:32: error: expected type 'comptime_int', found 'u32'",
105 "tmp.zig:15:9: note: referenced here",
106 });116 });
107117
108 cases.addTest("invalid float casts",118 cases.addTest("invalid float casts",
...@@ -118,19 +128,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -118,19 +128,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
118 \\ var a: f32 = 2;128 \\ var a: f32 = 2;
119 \\ _ = @intToFloat(f32, a);129 \\ _ = @intToFloat(f32, a);
120 \\}130 \\}
121 \\export fn qux() void {
122 \\ var a: f32 = 2;
123 \\ _ = @floatCast(comptime_float, a);
124 \\}
125 , &[_][]const u8{131 , &[_][]const u8{
126 "tmp.zig:3:36: error: expected type 'comptime_float', found 'f32'",132 "tmp.zig:3:36: error: unable to evaluate constant expression",
127 "tmp.zig:3:9: note: referenced here",133 "tmp.zig:3:9: note: referenced here",
128 "tmp.zig:7:21: error: expected integer type, found 'f32'",134 "tmp.zig:7:21: error: expected integer type, found 'f32'",
129 "tmp.zig:7:9: note: referenced here",135 "tmp.zig:7:9: note: referenced here",
130 "tmp.zig:11:26: error: expected int type, found 'f32'",136 "tmp.zig:11:26: error: expected int type, found 'f32'",
131 "tmp.zig:11:9: note: referenced here",137 "tmp.zig:11:9: note: referenced here",
132 "tmp.zig:15:36: error: expected type 'comptime_float', found 'f32'",
133 "tmp.zig:15:9: note: referenced here",
134 });138 });
135139
136 cases.addTest("invalid assignments",140 cases.addTest("invalid assignments",
test/stage1/behavior/cast.zig+13
...@@ -384,6 +384,19 @@ test "@intCast i32 to u7" {...@@ -384,6 +384,19 @@ test "@intCast i32 to u7" {
384 expect(z == 0xff);384 expect(z == 0xff);
385}385}
386386
387test "@floatCast cast down" {
388 {
389 var double: f64 = 0.001534;
390 var single = @floatCast(f32, double);
391 expect(single == 0.001534);
392 }
393 {
394 const double: f64 = 0.001534;
395 const single = @floatCast(f32, double);
396 expect(single == 0.001534);
397 }
398}
399
387test "implicit cast undefined to optional" {400test "implicit cast undefined to optional" {
388 expect(MakeType(void).getNull() == null);401 expect(MakeType(void).getNull() == null);
389 expect(MakeType(void).getNonNull() != null);402 expect(MakeType(void).getNonNull() != null);