aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-12-24 04:10:26 -0500
committerAndrew Kelley <superjoe30@gmail.com>2017-12-24 04:11:58 -0500
commit2a25398c869fcdefe8b6508974a5c463ca833520 (patch)
treecab802b768a4b2559a234c2a29c301435678bac3 /src/codegen.cpp
parent86397a532ec3c6699c39c8eeb966cd56b66c6c96 (diff)
downloadzig-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.cpp26
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);
}