diff options
| author | gingerBill <bill@gingerbill.org> | 2021-05-05 23:00:12 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-05-05 23:00:12 +0100 |
| commit | 0f2a9e6143e584d79af72858dceffa1b9e4b11d4 (patch) | |
| tree | 53a1b9c9327e74be45852db486843d9cd404c1e7 /src/llvm_backend.cpp | |
| parent | 278de3a92f80e1c3f1abc3ece53db6d0bba1e393 (diff) | |
Fix LLVM store point for nested types containing procedures (e.g. `^^proc()`)
Diffstat (limited to 'src/llvm_backend.cpp')
| -rw-r--r-- | src/llvm_backend.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index baf768880..c0d0a66ad 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -518,6 +518,38 @@ void lb_const_store(lbValue ptr, lbValue value) { } +bool lb_is_type_proc_recursive(Type *t) { + for (;;) { + if (t == nullptr) { + return false; + } + switch (t->kind) { + case Type_Named: + t = t->Named.base; + break; + case Type_Pointer: + t = t->Pointer.elem; + break; + case Type_Array: + t = t->Array.elem; + break; + case Type_EnumeratedArray: + t = t->EnumeratedArray.elem; + break; + case Type_Slice: + t = t->Slice.elem; + break; + case Type_DynamicArray: + t = t->DynamicArray.elem; + break; + case Type_Proc: + return true; + default: + return false; + } + } +} + void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) { GB_ASSERT(value.value != nullptr); Type *a = type_deref(ptr.type); @@ -530,7 +562,7 @@ void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) { GB_ASSERT_MSG(are_types_identical(ca, core_type(value.type)), "%s != %s", type_to_string(a), type_to_string(value.type)); } - if (is_type_proc(a)) { + if (lb_is_type_proc_recursive(a)) { // NOTE(bill, 2020-11-11): Because of certain LLVM rules, a procedure value may be // stored as regular pointer with no procedure information |