diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-02-26 23:50:04 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-02-26 23:50:04 -0500 |
| commit | 25761570f1bb4413020ebbfc959caa3429453517 (patch) | |
| tree | ac228c95e0393a8b36202864c60a4fd712a0e8d3 /src | |
| parent | 8dd0b4e1f12bc9f70ff6c312b35563595fdb4476 (diff) | |
| download | zig-25761570f1bb4413020ebbfc959caa3429453517.tar.gz zig-25761570f1bb4413020ebbfc959caa3429453517.zip | |
more robust const struct values
Diffstat (limited to 'src')
| -rw-r--r-- | src/analyze.cpp | 26 | ||||
| -rw-r--r-- | src/analyze.hpp | 1 | ||||
| -rw-r--r-- | src/ir.cpp | 22 |
3 files changed, 40 insertions, 9 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 842ddbdf48..03da4a26c7 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3485,10 +3485,11 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { ConstExprValue *element_val = &const_val->data.x_array.elements[i]; element_val->type = canon_wanted_type->data.array.child_type; init_const_undefined(g, element_val); - if (get_underlying_type(element_val->type)->id == TypeTableEntryIdArray) { - element_val->data.x_array.parent.id = ConstParentIdArray; - element_val->data.x_array.parent.data.p_array.array_val = const_val; - element_val->data.x_array.parent.data.p_array.elem_index = i; + ConstParent *parent = get_const_val_parent(element_val); + if (parent != nullptr) { + parent->id = ConstParentIdArray; + parent->data.p_array.array_val = const_val; + parent->data.p_array.elem_index = i; } } } else if (canon_wanted_type->id == TypeTableEntryIdStruct) { @@ -3502,6 +3503,12 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { field_val->type = canon_wanted_type->data.structure.fields[i].type_entry; assert(field_val->type); init_const_undefined(g, field_val); + ConstParent *parent = get_const_val_parent(field_val); + if (parent != nullptr) { + parent->id = ConstParentIdStruct; + parent->data.p_struct.struct_val = const_val; + parent->data.p_struct.field_index = i; + } } } else { const_val->special = ConstValSpecialUndef; @@ -4068,3 +4075,14 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { } zig_unreachable(); } + +ConstParent *get_const_val_parent(ConstExprValue *value) { + assert(value->type); + TypeTableEntry *canon_type = get_underlying_type(value->type); + if (canon_type->id == TypeTableEntryIdArray) { + return &value->data.x_array.parent; + } else if (canon_type->id == TypeTableEntryIdStruct) { + return &value->data.x_struct.parent; + } + return nullptr; +} diff --git a/src/analyze.hpp b/src/analyze.hpp index 49996f5ef0..4a2e62e432 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -147,5 +147,6 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_ void init_const_undefined(CodeGen *g, ConstExprValue *const_val); TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits); +ConstParent *get_const_val_parent(ConstExprValue *value); #endif diff --git a/src/ir.cpp b/src/ir.cpp index fcaab07e6b..8e614298ea 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10567,7 +10567,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru if (existing_assign_node) { ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field")); add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); - continue; + return ira->codegen->builtin_types.entry_invalid; } field_assign_nodes[field_index] = field->source_node; @@ -10602,6 +10602,17 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru if (const_val.special == ConstValSpecialStatic) { ConstExprValue *out_val = ir_build_const_from(ira, instruction); *out_val = const_val; + + for (size_t i = 0; i < instr_field_count; i += 1) { + ConstExprValue *field_val = &out_val->data.x_struct.fields[i]; + ConstParent *parent = get_const_val_parent(field_val); + if (parent != nullptr) { + parent->id = ConstParentIdStruct; + parent->data.p_struct.field_index = i; + parent->data.p_struct.struct_val = out_val; + } + } + return container_type; } @@ -10681,10 +10692,11 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira *out_val = const_val; for (size_t i = 0; i < elem_count; i += 1) { ConstExprValue *elem_val = &out_val->data.x_array.elements[i]; - if (elem_val->type->id == TypeTableEntryIdArray) { - elem_val->data.x_array.parent.id = ConstParentIdArray; - elem_val->data.x_array.parent.data.p_array.array_val = out_val; - elem_val->data.x_array.parent.data.p_array.elem_index = i; + ConstParent *parent = get_const_val_parent(elem_val); + if (parent != nullptr) { + parent->id = ConstParentIdArray; + parent->data.p_array.array_val = out_val; + parent->data.p_array.elem_index = i; } } return fixed_size_array_type; |
