authorgravatar for adria.arrufat@gmail.comAdrià Arrufat <adria.arrufat@gmail.com> 2026-03-20 15:40:36+09:00
committergravatar for adria.arrufat@gmail.comAdrià Arrufat <adria.arrufat@gmail.com> 2026-03-20 15:40:36+09:00
log911f411886cd740db4939adb9eec05cffb655df0
tree2b1731322eed78f2e5efcf6d4a5ea2b79767770e
parent7b27dc60f3d251d418ff80131d43730c6afe5964

Sema: improve type validation in zirRoundCast


1 files changed, 32 insertions(+), 24 deletions(-)

src/Sema.zig+32-24
......@@ -20881,33 +20881,41 @@ fn zirRoundCast(
2088120881 const dest_scalar_ty = dest_ty.scalarType(zcu);
2088220882 const operand_scalar_ty = operand_ty.scalarType(zcu);
2088320883
20884 if (dest_scalar_ty.zigTypeTag(zcu) == .float or dest_scalar_ty.zigTypeTag(zcu) == .comptime_float) {
20885 const coerced_operand = try sema.coerce(block, dest_ty, operand, operand_src);
20886
20887 const result_ref = switch (mode) {
20888 .round => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.round),
20889 .floor => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.floor),
20890 .ceil => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.ceil),
20891 .truncate => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.trunc),
20892 else => unreachable,
20893 };
20884 try sema.checkFloatType(block, operand_src, operand_scalar_ty);
2089420885
20895 if (result_ref) |ref| return ref;
20886 switch (dest_scalar_ty.zigTypeTag(zcu)) {
20887 .float, .comptime_float => {
20888 const coerced_operand = try sema.coerce(block, dest_ty, operand, operand_src);
2089620889
20897 const air_tag: Air.Inst.Tag = switch (mode) {
20898 .round => .round,
20899 .floor => .floor,
20900 .ceil => .ceil,
20901 .truncate => .trunc_float,
20902 else => unreachable,
20903 };
20890 const result_ref = switch (mode) {
20891 .round => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.round),
20892 .floor => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.floor),
20893 .ceil => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.ceil),
20894 .truncate => try sema.maybeConstantUnaryMath(coerced_operand, dest_ty, Value.trunc),
20895 .exact => unreachable,
20896 };
2090420897
20905 try sema.requireRuntimeBlock(block, operand_src, null);
20906 return block.addUnOp(air_tag, coerced_operand);
20907 }
20898 if (result_ref) |ref| return ref;
2090820899
20909 _ = try sema.checkIntType(block, src, dest_scalar_ty);
20910 try sema.checkFloatType(block, operand_src, operand_scalar_ty);
20900 const air_tag: Air.Inst.Tag = switch (mode) {
20901 .round => .round,
20902 .floor => .floor,
20903 .ceil => .ceil,
20904 .truncate => .trunc_float,
20905 .exact => unreachable,
20906 };
20907
20908 try sema.requireRuntimeBlock(block, operand_src, null);
20909 return block.addUnOp(air_tag, coerced_operand);
20910 },
20911 .int, .comptime_int => {},
20912 else => return sema.fail(
20913 block,
20914 src,
20915 "expected integer, float, or vector of either integers or floats, found '{f}'",
20916 .{dest_ty.fmt(pt)},
20917 ),
20918 }
2091120919
2091220920 if (sema.resolveValue(operand)) |operand_val| {
2091320921 const result_val = try sema.intFromFloat(block, operand_src, operand_val, operand_ty, dest_ty, mode);
......@@ -20948,7 +20956,7 @@ fn zirRoundCast(
2094820956 .round => .round,
2094920957 .floor => .floor,
2095020958 .ceil => .ceil,
20951 else => unreachable,
20959 .truncate, .exact => unreachable,
2095220960 };
2095320961 const rounded_op = try block.addUnOp(op_tag, operand);
2095420962