Merge branch 'odin-lang:master' into core_sync_typo

This commit is contained in:
Znarf
2026-07-15 22:47:27 +02:00
committed by GitHub
7 changed files with 131 additions and 44 deletions

View File

@@ -1386,22 +1386,22 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ
}
}
gb_internal bool polymorphic_assign_index(Type **gt_, i64 *dst_count, i64 source_count) {
gb_internal bool polymorphic_assign_index(Type **gt_, i64 *dst_count, i64 source_count, bool modify_type) {
Type *gt = *gt_;
GB_ASSERT(gt->kind == Type_Generic);
Entity *e = scope_lookup(gt->Generic.scope, gt->Generic.interned_name, 0);
GB_ASSERT(e != nullptr);
if (e->kind == Entity_TypeName) {
*gt_ = nullptr;
*dst_count = source_count;
e->kind = Entity_Constant;
e->Constant.value = exact_value_i64(source_count);
e->type = t_untyped_integer;
if (modify_type) {
*gt_ = nullptr;
e->kind = Entity_Constant;
e->Constant.value = exact_value_i64(source_count);
e->type = t_untyped_integer;
}
return true;
} else if (e->kind == Entity_Constant) {
*gt_ = nullptr;
if (e->Constant.value.kind != ExactValue_Integer) {
return false;
}
@@ -1410,6 +1410,9 @@ gb_internal bool polymorphic_assign_index(Type **gt_, i64 *dst_count, i64 source
return false;
}
*dst_count = source_count;
if (modify_type) {
*gt_ = nullptr;
}
return true;
}
return false;
@@ -1490,12 +1493,18 @@ gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, T
case Type_Array:
if (source->kind == Type_Array) {
if (poly->Array.generic_count != nullptr) {
if (!polymorphic_assign_index(&poly->Array.generic_count, &poly->Array.count, source->Array.count)) {
Type *generic_count = poly->Array.generic_count;
i64 count = poly->Array.count;
if (generic_count != nullptr) {
if (!polymorphic_assign_index(&generic_count, &count, source->Array.count, modify_type)) {
return false;
}
if (modify_type) {
poly->Array.generic_count = generic_count;
poly->Array.count = count;
}
}
if (poly->Array.count == source->Array.count) {
if (count == source->Array.count) {
return is_polymorphic_type_assignable(c, poly->Array.elem, source->Array.elem, true, modify_type);
}
} else if (source->kind == Type_EnumeratedArray) {
@@ -1510,6 +1519,9 @@ gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, T
if (it->kind != Type_Enum) {
return false;
}
if (!modify_type) {
return is_polymorphic_type_assignable(c, poly->Array.elem, source->EnumeratedArray.elem, true, false);
}
poly->kind = Type_EnumeratedArray;
poly->cached_size = -1;
@@ -1565,14 +1577,18 @@ gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, T
case Type_FixedCapacityDynamicArray:
if (source->kind == Type_FixedCapacityDynamicArray) {
if (poly->FixedCapacityDynamicArray.generic_capacity != nullptr) {
if (!polymorphic_assign_index(&poly->FixedCapacityDynamicArray.generic_capacity,
&poly->FixedCapacityDynamicArray.capacity,
source->FixedCapacityDynamicArray.capacity)) {
Type *generic_capacity = poly->FixedCapacityDynamicArray.generic_capacity;
i64 capacity = poly->FixedCapacityDynamicArray.capacity;
if (generic_capacity != nullptr) {
if (!polymorphic_assign_index(&generic_capacity, &capacity, source->FixedCapacityDynamicArray.capacity, modify_type)) {
return false;
}
if (modify_type) {
poly->FixedCapacityDynamicArray.generic_capacity = generic_capacity;
poly->FixedCapacityDynamicArray.capacity = capacity;
}
}
if (poly->FixedCapacityDynamicArray.capacity == source->FixedCapacityDynamicArray.capacity) {
if (capacity == source->FixedCapacityDynamicArray.capacity) {
return is_polymorphic_type_assignable(c, poly->FixedCapacityDynamicArray.elem, source->FixedCapacityDynamicArray.elem, true, modify_type);
}
}
@@ -1723,8 +1739,10 @@ gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, T
bool key = is_polymorphic_type_assignable(c, poly->Map.key, source->Map.key, true, modify_type);
bool value = is_polymorphic_type_assignable(c, poly->Map.value, source->Map.value, true, modify_type);
if (key || value) {
poly->Map.lookup_result_type = nullptr;
init_map_internal_types(poly);
if (modify_type) {
poly->Map.lookup_result_type = nullptr;
init_map_internal_types(poly);
}
return true;
}
}
@@ -1732,20 +1750,29 @@ gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, T
case Type_Matrix:
if (source->kind == Type_Matrix) {
if (poly->Matrix.generic_row_count != nullptr) {
poly->Matrix.stride_in_bytes = 0;
if (!polymorphic_assign_index(&poly->Matrix.generic_row_count, &poly->Matrix.row_count, source->Matrix.row_count)) {
Type *generic_row_count = poly->Matrix.generic_row_count;
Type *generic_column_count = poly->Matrix.generic_column_count;
i64 row_count = poly->Matrix.row_count;
i64 column_count = poly->Matrix.column_count;
if (generic_row_count != nullptr) {
if (!polymorphic_assign_index(&generic_row_count, &row_count, source->Matrix.row_count, modify_type)) {
return false;
}
}
if (poly->Matrix.generic_column_count != nullptr) {
poly->Matrix.stride_in_bytes = 0;
if (!polymorphic_assign_index(&poly->Matrix.generic_column_count, &poly->Matrix.column_count, source->Matrix.column_count)) {
if (generic_column_count != nullptr) {
if (!polymorphic_assign_index(&generic_column_count, &column_count, source->Matrix.column_count, modify_type)) {
return false;
}
}
if (poly->Matrix.row_count == source->Matrix.row_count &&
poly->Matrix.column_count == source->Matrix.column_count) {
if (modify_type && (poly->Matrix.generic_row_count != nullptr || poly->Matrix.generic_column_count != nullptr)) {
poly->Matrix.generic_row_count = generic_row_count;
poly->Matrix.generic_column_count = generic_column_count;
poly->Matrix.row_count = row_count;
poly->Matrix.column_count = column_count;
poly->Matrix.stride_in_bytes = 0;
}
if (row_count == source->Matrix.row_count &&
column_count == source->Matrix.column_count) {
return is_polymorphic_type_assignable(c, poly->Matrix.elem, source->Matrix.elem, true, modify_type);
}
}
@@ -1753,12 +1780,18 @@ gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, T
case Type_SimdVector:
if (source->kind == Type_SimdVector) {
if (poly->SimdVector.generic_count != nullptr) {
if (!polymorphic_assign_index(&poly->SimdVector.generic_count, &poly->SimdVector.count, source->SimdVector.count)) {
Type *generic_count = poly->SimdVector.generic_count;
i64 count = poly->SimdVector.count;
if (generic_count != nullptr) {
if (!polymorphic_assign_index(&generic_count, &count, source->SimdVector.count, modify_type)) {
return false;
}
if (modify_type) {
poly->SimdVector.generic_count = generic_count;
poly->SimdVector.count = count;
}
}
if (poly->SimdVector.count == source->SimdVector.count) {
if (count == source->SimdVector.count) {
return is_polymorphic_type_assignable(c, poly->SimdVector.elem, source->SimdVector.elem, true, modify_type);
}
}

View File

@@ -1342,22 +1342,8 @@ namespace lbAbiArm64 {
} else if (size <= 8) {
cast_type = LLVMIntTypeInContext(c, cast(unsigned)(size*8));
} else {
unsigned count = cast(unsigned)((size+7)/8);
LLVMTypeRef llvm_i64 = LLVMIntTypeInContext(c, 64);
LLVMTypeRef *types = gb_alloc_array(temporary_allocator(), LLVMTypeRef, count);
i64 size_copy = size;
for (unsigned i = 0; i < count; i++) {
if (size_copy >= 8) {
types[i] = llvm_i64;
} else {
types[i] = LLVMIntTypeInContext(c, 8*cast(unsigned)size_copy);
}
size_copy -= 8;
}
GB_ASSERT(size_copy <= 0);
cast_type = LLVMStructTypeInContext(c, types, count, true);
cast_type = llvm_array_type(llvm_i64, 2);
}
args[i] = lb_arg_type_direct(type, cast_type, nullptr, nullptr);
} else {

View File

@@ -463,7 +463,7 @@ gb_internal LLVMValueRef llvm_const_insert_value_with_rebuild(lbModule *m, LLVMV
GB_ASSERT(count > 0);
unsigned value_count = LLVMCountStructElementTypes(LLVMTypeOf(agg));
LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, count);
LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, value_count);
defer (gb_free(heap_allocator(), values));
for (unsigned i = 0; i < value_count; i++) {

View File

@@ -1496,6 +1496,7 @@ gb_internal lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) {
case 0: result_type = alloc_type_array(t->FixedCapacityDynamicArray.elem, t->FixedCapacityDynamicArray.capacity); break;
case 1: result_type = t_int; break;
}
break;
case Type_Map:
{

View File

@@ -88,6 +88,13 @@ $ODIN test ../test_issue_7010.odin $COMMON
clang -c ../test_issue_6809_6816.c -o test_issue_6809_6816_c.o -O3
$ODIN test ../test_issue_6809_6816.odin -o:speed $COMMON
clang -c ../test_issue_5640.c -o test_issue_5640_c.o
if [[ "$(uname)" != "NetBSD" ]]; then
$ODIN test ../test_issue_5640.odin -o:none --sanitize:address $COMMON
else
$ODIN test ../test_issue_5640.odin -o:none $COMMON
fi
set +x
popd

View File

@@ -0,0 +1,19 @@
// Tests issue: https://github.com/odin-lang/Odin/issues/5640
#include <stdint.h>
#include <stdbool.h>
typedef struct {
uint32_t a;
uint32_t b;
uint32_t c;
} MyStruct;
bool test_stack_next(
int64_t r0, int64_t r1, int64_t r2, int64_t r3,
int64_t r4, int64_t r5, int64_t r6, int64_t r7,
MyStruct s,
int32_t next_arg
) {
return next_arg == 999;
}

View File

@@ -0,0 +1,41 @@
// Tests issue: https://github.com/odin-lang/Odin/issues/5640
package test_issues
import "core:testing"
MyStruct :: struct {
a: u32,
b: u32,
c: u32,
}
Foo :: struct {
x: [15]u8, // errors with 11, 13, 14, 15
}
myfunc :: #force_no_inline proc( f: Foo ) -> bool {
return f.x[0] == 45 && f.x[14] == 67
}
foreign import test_lib "build/test_issue_5640_c.o"
foreign test_lib {
test_stack_next :: proc(
r0, r1, r2, r3, r4, r5, r6, r7: i64,
s: MyStruct,
next_arg: i32,
) -> bool ---
}
@test
test_stack_parameter_alignment_arm64_abi :: proc(t: ^testing.T) {
s := MyStruct{ a = 42, b = 1337, c = 342 }
res := test_stack_next(0, 1, 2, 3, 4, 5, 6, 7, s, 999)
testing.expect(t, res == true)
res_2 := myfunc({{45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67}})
testing.expect(t, res_2 == true)
}