authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-02 13:39:46+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-02 17:57:10+03:00
log8b58dab78b8a157a39377654691324dd71f77d23
tree0198f4ee62cde36f0cede9c9a587749982085312
parent7a8d9af4a94caeb74361c9462cd44a1e4356150b

Sema: resolve lazy value before intToFloat

Closes #12698

3 files changed, 39 insertions(+), 5 deletions(-)

src/Sema.zig+2-2
......@@ -17499,7 +17499,7 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1749917499
1750017500 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
1750117501 const target = sema.mod.getTarget();
17502 const result_val = try val.intToFloat(sema.arena, operand_ty, dest_ty, target);
17502 const result_val = try val.intToFloatAdvanced(sema.arena, operand_ty, dest_ty, target, sema.kit(block, operand_src));
1750317503 return sema.addConstant(dest_ty, result_val);
1750417504 } else if (dest_ty.zigTypeTag() == .ComptimeFloat) {
1750517505 return sema.failWithNeededComptime(block, operand_src, "value being casted to 'comptime_float' must be comptime known");
......@@ -22998,7 +22998,7 @@ fn coerceExtra(
2299822998 }
2299922999 break :int;
2300023000 };
23001 const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target);
23001 const result_val = try val.intToFloatAdvanced(sema.arena, inst_ty, dest_ty, target, sema.kit(block, inst_src));
2300223002 // TODO implement this compile error
2300323003 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);
2300423004 //if (!int_again_val.eql(val, inst_ty, mod)) {
src/value.zig+26-3
......@@ -2940,17 +2940,24 @@ pub const Value = extern union {
29402940 }
29412941
29422942 pub fn intToFloat(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, target: Target) !Value {
2943 return intToFloatAdvanced(val, arena, int_ty, float_ty, target, null) catch |err| switch (err) {
2944 error.OutOfMemory => return error.OutOfMemory,
2945 else => unreachable,
2946 };
2947 }
2948
2949 pub fn intToFloatAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, target: Target, sema_kit: ?Module.WipAnalysis) !Value {
29432950 if (int_ty.zigTypeTag() == .Vector) {
29442951 const result_data = try arena.alloc(Value, int_ty.vectorLen());
29452952 for (result_data) |*scalar, i| {
2946 scalar.* = try intToFloatScalar(val.indexVectorlike(i), arena, float_ty.scalarType(), target);
2953 scalar.* = try intToFloatScalar(val.indexVectorlike(i), arena, float_ty.scalarType(), target, sema_kit);
29472954 }
29482955 return Value.Tag.aggregate.create(arena, result_data);
29492956 }
2950 return intToFloatScalar(val, arena, float_ty, target);
2957 return intToFloatScalar(val, arena, float_ty, target, sema_kit);
29512958 }
29522959
2953 pub fn intToFloatScalar(val: Value, arena: Allocator, float_ty: Type, target: Target) !Value {
2960 pub fn intToFloatScalar(val: Value, arena: Allocator, float_ty: Type, target: Target, sema_kit: ?Module.WipAnalysis) !Value {
29542961 switch (val.tag()) {
29552962 .undef, .zero, .one => return val,
29562963 .the_only_possible_value => return Value.initTag(.zero), // for i0, u0
......@@ -2970,6 +2977,22 @@ pub const Value = extern union {
29702977 const float = bigIntToFloat(limbs, false);
29712978 return floatToValue(float, arena, float_ty, target);
29722979 },
2980 .lazy_align => {
2981 const ty = val.castTag(.lazy_align).?.data;
2982 if (sema_kit) |sk| {
2983 return intToFloatInner((try ty.abiAlignmentAdvanced(target, .{ .sema_kit = sk })).scalar, arena, float_ty, target);
2984 } else {
2985 return intToFloatInner(ty.abiAlignment(target), arena, float_ty, target);
2986 }
2987 },
2988 .lazy_size => {
2989 const ty = val.castTag(.lazy_size).?.data;
2990 if (sema_kit) |sk| {
2991 return intToFloatInner((try ty.abiSizeAdvanced(target, .{ .sema_kit = sk })).scalar, arena, float_ty, target);
2992 } else {
2993 return intToFloatInner(ty.abiSize(target), arena, float_ty, target);
2994 }
2995 },
29732996 else => unreachable,
29742997 }
29752998 }
test/behavior/sizeof_and_typeof.zig+11
......@@ -301,3 +301,14 @@ test "array access of generic param in typeof expression" {
301301 try expect(S.first("a") == 'a');
302302 comptime try expect(S.first("a") == 'a');
303303}
304
305test "lazy size cast to float" {
306 {
307 const S = struct { a: u8 };
308 try expect(@intToFloat(f32, @sizeOf(S)) == 1.0);
309 }
310 {
311 const S = struct { a: u8 };
312 try expect(@as(f32, @sizeOf(S)) == 1.0);
313 }
314}