diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 49af4ec39..488c84099 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3421,7 +3421,8 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { cc.link_section = e->Variable.link_section; ExactValue v = tav.value; - lbValue init = lb_const_value(m, e->type, v, cc); + lbValue init = lb_const_value(m, e->type, v, cc, tav.type); + LLVMDeleteGlobal(g.value); g.value = nullptr; diff --git a/src/types.cpp b/src/types.cpp index f87d62297..260dd4918 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2656,6 +2656,40 @@ gb_internal bool type_has_nil(Type *t) { return false; } +gb_internal bool is_type_union_constantable(Type *type); + +gb_internal bool is_type_constant_type_for_unions(Type *t) { + t = core_type(t); + if (t == nullptr) { return false; } + switch (t->kind) { + case Type_Basic: + if (t->Basic.kind == Basic_typeid) { + return true; + } + return (t->Basic.flags & BasicFlag_ConstantType) != 0; + case Type_BitSet: + return true; + case Type_Proc: + return true; + case Type_Array: + return is_type_constant_type(t->Array.elem); + case Type_EnumeratedArray: + return is_type_constant_type(t->EnumeratedArray.elem); + case Type_Struct: + { + for (Entity *field : t->Struct.fields) { + if (!is_type_constant_type_for_unions(field->type)) { + return false; + } + } + return true; + } + case Type_Union: + return is_type_union_constantable(t); + } + return false; +} + gb_internal bool is_type_union_constantable(Type *type) { Type *bt = base_type(type); GB_ASSERT(bt->kind == Type_Union); @@ -2667,7 +2701,7 @@ gb_internal bool is_type_union_constantable(Type *type) { } for (Type *v : bt->Union.variants) { - if (!is_type_constant_type(v)) { + if (!is_type_constant_type_for_unions(v)) { return false; } } @@ -2680,7 +2714,7 @@ gb_internal bool is_type_raw_union_constantable(Type *type) { GB_ASSERT(bt->Struct.is_raw_union); for (Entity *f : bt->Struct.fields) { - if (!is_type_constant_type(f->type)) { + if (!is_type_constant_type_for_unions(f->type)) { return false; } }