mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
stage2: fix unsigned integer to signed integer coercion
This commit is contained in:
parent
be71195bba
commit
0e2b9ac777
@ -9565,7 +9565,7 @@ fn coerce(
|
||||
const src_info = inst_ty.intInfo(target);
|
||||
if ((src_info.signedness == dst_info.signedness and dst_info.bits >= src_info.bits) or
|
||||
// small enough unsigned ints can get casted to large enough signed ints
|
||||
(src_info.signedness == .signed and dst_info.signedness == .unsigned and dst_info.bits > src_info.bits))
|
||||
(dst_info.signedness == .signed and dst_info.bits > src_info.bits))
|
||||
{
|
||||
try sema.requireRuntimeBlock(block, inst_src);
|
||||
return block.addTyOp(.intcast, dest_type, inst);
|
||||
|
||||
@ -2032,14 +2032,22 @@ pub const FuncGen = struct {
|
||||
if (self.liveness.isUnused(inst))
|
||||
return null;
|
||||
|
||||
const target = self.dg.module.getTarget();
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const dest_ty = self.air.typeOfIndex(inst);
|
||||
const dest_info = dest_ty.intInfo(target);
|
||||
const dest_llvm_ty = try self.dg.llvmType(dest_ty);
|
||||
const operand = try self.resolveInst(ty_op.operand);
|
||||
const inst_ty = self.air.typeOfIndex(inst);
|
||||
const operand_ty = self.air.typeOf(ty_op.operand);
|
||||
const operand_info = operand_ty.intInfo(target);
|
||||
|
||||
const signed = inst_ty.isSignedInt();
|
||||
// TODO: Should we use intcast here or just a simple bitcast?
|
||||
// LLVM does truncation vs bitcast (+signed extension) in the intcast depending on the sizes
|
||||
return self.builder.buildIntCast2(operand, try self.dg.llvmType(inst_ty), llvm.Bool.fromBool(signed), "");
|
||||
if (operand_info.bits < dest_info.bits) {
|
||||
switch (operand_info.signedness) {
|
||||
.signed => return self.builder.buildSExt(operand, dest_llvm_ty, ""),
|
||||
.unsigned => return self.builder.buildZExt(operand, dest_llvm_ty, ""),
|
||||
}
|
||||
}
|
||||
return self.builder.buildTrunc(operand, dest_llvm_ty, "");
|
||||
}
|
||||
|
||||
fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
|
||||
|
||||
@ -11,3 +11,9 @@ test "integer widening" {
|
||||
var f: u128 = e;
|
||||
try expect(f == a);
|
||||
}
|
||||
|
||||
test "implicit unsigned integer to signed integer" {
|
||||
var a: u8 = 250;
|
||||
var b: i16 = a;
|
||||
try expect(b == 250);
|
||||
}
|
||||
|
||||
@ -2,12 +2,6 @@ const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
const mem = std.mem;
|
||||
|
||||
test "implicit unsigned integer to signed integer" {
|
||||
var a: u8 = 250;
|
||||
var b: i16 = a;
|
||||
try expect(b == 250);
|
||||
}
|
||||
|
||||
test "float widening" {
|
||||
var a: f16 = 12.34;
|
||||
var b: f32 = a;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user