Fix bits return location type

This commit is contained in:
David Gonzalez Martin 2025-03-24 10:24:16 +01:00
parent 852f312471
commit 0721f8a2ef
4 changed files with 40 additions and 4 deletions

View File

@ -70,6 +70,7 @@ os_linux_map_flags = fn(map_flags: OS_MapFlags) OS_Linux_MAP
.anonymous = map_flags.anonymous, .anonymous = map_flags.anonymous,
.no_reserve = map_flags.no_reserve, .no_reserve = map_flags.no_reserve,
.populate = map_flags.populate, .populate = map_flags.populate,
zero,
}; };
} }

View File

@ -1144,6 +1144,7 @@ const StructType = struct {
const Bits = struct { const Bits = struct {
fields: []const Field, fields: []const Field,
backing_type: *Type, backing_type: *Type,
implicit_backing_type: bool,
}; };
pub const ArrayType = struct { pub const ArrayType = struct {
@ -1170,6 +1171,7 @@ pub const FloatType = struct {
pub const Enumerator = struct { pub const Enumerator = struct {
fields: []const Enumerator.Field, fields: []const Enumerator.Field,
backing_type: *Type, backing_type: *Type,
implicit_backing_type: bool,
pub const Field = struct { pub const Field = struct {
name: []const u8, name: []const u8,
@ -2758,9 +2760,11 @@ const Converter = struct {
}, },
.select => { .select => {
const condition_value = converter.parse_value(module, null, .value); const condition_value = converter.parse_value(module, null, .value);
if (condition_value.type.bb != .integer) { if (condition_value.type.bb != .integer) {
converter.report_error(); converter.report_error();
} }
if (condition_value.type.bb.integer.bit_count != 1) { if (condition_value.type.bb.integer.bit_count != 1) {
converter.report_error(); converter.report_error();
} }
@ -3257,7 +3261,7 @@ const Converter = struct {
return value; return value;
}, },
.bits => |*bits| { .bits => |bits| {
var field_count: usize = 0; var field_count: usize = 0;
var llvm_value = bits.backing_type.llvm.handle.to_integer().get_constant(0, @intFromBool(false)).to_value(); var llvm_value = bits.backing_type.llvm.handle.to_integer().get_constant(0, @intFromBool(false)).to_value();
@ -3318,7 +3322,7 @@ const Converter = struct {
if (field_count != bits.fields.len) { if (field_count != bits.fields.len) {
// expect: 'zero' keyword // expect: 'zero' keyword
if (zero) { if (zero or bits.implicit_backing_type) {
// TODO: should we do anything? // TODO: should we do anything?
} else { } else {
@trap(); @trap();
@ -3542,10 +3546,18 @@ const Converter = struct {
} }
const value = module.values.add(); const value = module.values.add();
value.* = .{ value.* = .{
.type = bits.backing_type,
.llvm = bitfield_masked,
.bb = .instruction, .bb = .instruction,
.llvm = switch (bits.backing_type == field.type) {
true => bitfield_masked,
false => blk: {
assert(bits.backing_type.get_bit_size() > field.type.get_bit_size());
const trunc = module.llvm.builder.create_truncate(bitfield_masked, field.type.llvm.handle);
break :blk trunc;
},
},
.type = field.type,
.lvalue = false, .lvalue = false,
.dereference_to_assign = false, .dereference_to_assign = false,
}; };
@ -5516,6 +5528,7 @@ pub noinline fn convert(arena: *Arena, options: ConvertOptions) void {
.bits = .{ .bits = .{
.fields = fields, .fields = fields,
.backing_type = backing_type, .backing_type = backing_type,
.implicit_backing_type = is_implicit_type,
}, },
}, },
}); });
@ -5604,6 +5617,7 @@ pub noinline fn convert(arena: *Arena, options: ConvertOptions) void {
.enumerator = .{ .enumerator = .{
.backing_type = backing_type, .backing_type = backing_type,
.fields = fields, .fields = fields,
.implicit_backing_type = is_implicit_type,
}, },
}, },
.llvm = .{ .llvm = .{

View File

@ -396,3 +396,7 @@ test "struct_zero" {
test "select" { test "select" {
try invsrc(@src()); try invsrc(@src());
} }
test "bits_return_u1" {
try invsrc(@src());
}

17
tests/bits_return_u1.bbb Normal file
View File

@ -0,0 +1,17 @@
S = bits u32
{
a: u1,
b: u1,
c: u1,
}
foo = fn () u1
{
>a: S = { .a = 1, .b = 1, .c = 0 };
return a.c;
}
[export] main = fn [cc(c)] () s32
{
return #extend(foo() == 1);
}