diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-12-24 04:10:26 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-12-24 04:11:58 -0500 |
| commit | 2a25398c869fcdefe8b6508974a5c463ca833520 (patch) | |
| tree | cab802b768a4b2559a234c2a29c301435678bac3 /src/codegen.cpp | |
| parent | 86397a532ec3c6699c39c8eeb966cd56b66c6c96 (diff) | |
| download | zig-2a25398c869fcdefe8b6508974a5c463ca833520.tar.gz zig-2a25398c869fcdefe8b6508974a5c463ca833520.zip | |
fix segfault when passing union enum with sub byte...
...field to const slice parameter
we use a packed struct internally to represent a const array
of disparate union values, and needed to update the internal
getelementptr instruction to recognize that.
closes #664
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 339c643425..552467989e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3705,12 +3705,24 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *ar ConstParent *parent = &array_const_val->data.x_array.s_none.parent; LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent); - TypeTableEntry *usize = g->builtin_types.entry_usize; - LLVMValueRef indices[] = { - LLVMConstNull(usize->type_ref), - LLVMConstInt(usize->type_ref, index, false), - }; - return LLVMConstInBoundsGEP(base_ptr, indices, 2); + LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr))); + if (el_type == LLVMArrayTypeKind) { + TypeTableEntry *usize = g->builtin_types.entry_usize; + LLVMValueRef indices[] = { + LLVMConstNull(usize->type_ref), + LLVMConstInt(usize->type_ref, index, false), + }; + return LLVMConstInBoundsGEP(base_ptr, indices, 2); + } else if (el_type == LLVMStructTypeKind) { + TypeTableEntry *u32 = g->builtin_types.entry_u32; + LLVMValueRef indices[] = { + LLVMConstNull(u32->type_ref), + LLVMConstInt(u32->type_ref, index, false), + }; + return LLVMConstInBoundsGEP(base_ptr, indices, 2); + } else { + zig_unreachable(); + } } static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ConstExprValue *struct_const_val, size_t field_index) { @@ -3732,7 +3744,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un TypeTableEntry *u32 = g->builtin_types.entry_u32; LLVMValueRef indices[] = { LLVMConstNull(u32->type_ref), - LLVMConstInt(u32->type_ref, 0, false), + LLVMConstInt(u32->type_ref, 0, false), // TODO test const union with more aligned tag type than payload }; return LLVMConstInBoundsGEP(base_ptr, indices, 2); } |
