Pass 'small_struct_ints'

This commit is contained in:
David Gonzalez Martin 2025-06-13 13:41:51 -06:00
parent 9e1856d4c5
commit 45fab3dd29
2 changed files with 45 additions and 12 deletions

View File

@ -7172,7 +7172,26 @@ contains_no_user_data = fn (type: &Type, start: u64, end: u64) u1
.struct => .struct =>
{ {
result = 1; result = 1;
#trap();
>fields = type.content.struct.fields;
for (&field: fields)
{
>field_offset = field.offset;
if (field_offset >= end)
{
break;
}
>field_start = #select(field_offset < start, start - field_offset, 0);
if (!contains_no_user_data(field.type, field_start, end - field_offset))
{
result = 0;
break;
}
}
}, },
.array, .enum_array => .array, .enum_array =>
{ {
@ -12945,15 +12964,30 @@ emit = fn (module: &Module) void
else else
{ {
return_value = create_load(module, { return_value = create_load(module, {
.type = semantic_return_type, .type = semantic_return_type,
.pointer = return_alloca, .pointer = return_alloca,
zero, zero,
}); });
} }
} }
else else
{ {
#trap(); >source: &LLVMValue = zero;
if (function_type.abi.return_abi.attributes.direct.offset == 0)
{
source = return_alloca;
}
else
{
#trap();
}
assert(source != zero);
>source_type = function_type.abi.return_abi.semantic_type;
>destination_type = coerce_to_type;
>result = create_coerced_load(module, source, source_type, destination_type);
return_value = result;
} }
}, },
.indirect => .indirect =>
@ -13329,6 +13363,7 @@ names: [_][]u8 =
"return_u64_u64", "return_u64_u64",
"select", "select",
"slice", "slice",
"small_struct_ints",
]; ];
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32 [export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32

View File

@ -609,21 +609,19 @@ fn bool contains_no_user_data(Type* type, u64 start, u64 end)
{ {
case TypeId::structure: case TypeId::structure:
{ {
u64 offset = 0;
for (auto& field: type->structure.fields) for (auto& field: type->structure.fields)
{ {
if (offset >= end) auto field_offset = field.offset;
if (field_offset >= end)
{ {
break; break;
} }
auto field_start = offset < start ? start - offset : 0; auto field_start = field_offset < start ? start - field_offset : 0;
if (!contains_no_user_data(field.type, field_start, end - offset)) if (!contains_no_user_data(field.type, field_start, end - field_offset))
{ {
return false; return false;
} }
offset += get_byte_size(field.type);
} }
return true; return true;