authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-08 17:20:08-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-08 17:28:34-05:00
log1cb19d1a461d5181c8e367cdd863720e5e695823
tree4b3a76f8450ba9cf2dd8bb28573b1459f5e9e897
parentc2342dab0bbe3a7f887e0a88948aa8e36419382f
signature Commit is signed but in an unrecognized format.

fix anon struct literal field initialized with fn call


3 files changed, 109 insertions(+), 68 deletions(-)

src/analyze.cpp+15-6
......@@ -4165,13 +4165,22 @@ TypeEnumField *find_enum_type_field(ZigType *enum_type, Buf *name) {
41654165
41664166TypeStructField *find_struct_type_field(ZigType *type_entry, Buf *name) {
41674167 assert(type_entry->id == ZigTypeIdStruct);
4168 assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown));
4169 if (type_entry->data.structure.src_field_count == 0)
4170 return nullptr;
4171 auto entry = type_entry->data.structure.fields_by_name.maybe_get(name);
4172 if (entry == nullptr)
4168 if (type_entry->data.structure.resolve_status == ResolveStatusBeingInferred) {
4169 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
4170 TypeStructField *field = type_entry->data.structure.fields[i];
4171 if (buf_eql_buf(field->name, name))
4172 return field;
4173 }
41734174 return nullptr;
4174 return entry->value;
4175 } else {
4176 assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown));
4177 if (type_entry->data.structure.src_field_count == 0)
4178 return nullptr;
4179 auto entry = type_entry->data.structure.fields_by_name.maybe_get(name);
4180 if (entry == nullptr)
4181 return nullptr;
4182 return entry->value;
4183 }
41754184}
41764185
41774186TypeUnionField *find_union_type_field(ZigType *type_entry, Buf *name) {
src/ir.cpp+80-62
......@@ -666,7 +666,7 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
666666
667667 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) {
668668 case OnePossibleValueInvalid:
669 zig_unreachable();
669 return nullptr;
670670 case OnePossibleValueYes:
671671 return get_the_one_possible_value(g, const_val->type->data.pointer.child_type);
672672 case OnePossibleValueNo:
......@@ -9225,7 +9225,7 @@ ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_va
92259225{
92269226 Error err;
92279227 ZigValue *val = const_ptr_pointee_unchecked(codegen, const_val);
9228 assert(val != nullptr);
9228 if (val == nullptr) return nullptr;
92299229 assert(const_val->type->id == ZigTypeIdPointer);
92309230 ZigType *expected_type = const_val->type->data.pointer.child_type;
92319231 if (expected_type == codegen->builtin_types.entry_var) {
......@@ -12467,9 +12467,6 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
1246712467 if (type_is_invalid(value->value->type))
1246812468 return ira->codegen->invalid_instruction;
1246912469
12470 if ((err = type_resolve(ira->codegen, value->value->type, ResolveStatusZeroBitsKnown)))
12471 return ira->codegen->invalid_instruction;
12472
1247312470 if (instr_is_comptime(value)) {
1247412471 ZigValue *val = ir_resolve_const(ira, value, LazyOk);
1247512472 if (!val)
......@@ -13351,8 +13348,12 @@ static IrInstruction *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInst
1335113348 IrInstruction *struct_operand, TypeStructField *field)
1335213349{
1335313350 IrInstruction *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false);
13351 if (type_is_invalid(struct_ptr->value->type))
13352 return ira->codegen->invalid_instruction;
1335413353 IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, struct_ptr,
1335513354 struct_operand->value->type, false);
13355 if (type_is_invalid(field_ptr->value->type))
13356 return ira->codegen->invalid_instruction;
1335613357 return ir_get_deref(ira, source_instr, field_ptr, nullptr);
1335713358}
1335813359
......@@ -16919,6 +16920,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
1691916920 {
1692016921 result_loc_pass1 = no_result_loc();
1692116922 }
16923 bool was_written = result_loc_pass1->written;
1692216924 IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type,
1692316925 value, force_runtime, non_null_comptime, allow_discard);
1692416926 if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value->type)))
......@@ -16930,6 +16932,64 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
1693016932 result_loc->value->special = ConstValSpecialRuntime;
1693116933 }
1693216934
16935 InferredStructField *isf = result_loc->value->type->data.pointer.inferred_struct_field;
16936 if (!was_written && isf != nullptr) {
16937 // Now it's time to add the field to the struct type.
16938 uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count;
16939 uint32_t new_field_count = old_field_count + 1;
16940 isf->inferred_struct_type->data.structure.src_field_count = new_field_count;
16941 isf->inferred_struct_type->data.structure.fields = realloc_type_struct_fields(
16942 isf->inferred_struct_type->data.structure.fields, old_field_count, new_field_count);
16943
16944 TypeStructField *field = isf->inferred_struct_type->data.structure.fields[old_field_count];
16945 field->name = isf->field_name;
16946 field->type_entry = value_type;
16947 field->type_val = create_const_type(ira->codegen, field->type_entry);
16948 field->src_index = old_field_count;
16949 field->decl_node = value ? value->source_node : suspend_source_instr->source_node;
16950 if (value && instr_is_comptime(value)) {
16951 ZigValue *val = ir_resolve_const(ira, value, UndefOk);
16952 field->is_comptime = true;
16953 field->init_val = create_const_vals(1);
16954 copy_const_val(field->init_val, val);
16955 return result_loc;
16956 }
16957
16958 ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false);
16959 IrInstruction *casted_ptr;
16960 if (instr_is_comptime(result_loc)) {
16961 casted_ptr = ir_const(ira, suspend_source_instr, struct_ptr_type);
16962 copy_const_val(casted_ptr->value, result_loc->value);
16963 casted_ptr->value->type = struct_ptr_type;
16964 } else {
16965 casted_ptr = result_loc;
16966 }
16967 if (instr_is_comptime(casted_ptr)) {
16968 ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad);
16969 if (!ptr_val)
16970 return ira->codegen->invalid_instruction;
16971 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
16972 ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val,
16973 suspend_source_instr->source_node);
16974 struct_val->special = ConstValSpecialStatic;
16975 struct_val->data.x_struct.fields = realloc_const_vals_ptrs(struct_val->data.x_struct.fields,
16976 old_field_count, new_field_count);
16977
16978 ZigValue *field_val = struct_val->data.x_struct.fields[old_field_count];
16979 field_val->special = ConstValSpecialUndef;
16980 field_val->type = field->type_entry;
16981 field_val->parent.id = ConstParentIdStruct;
16982 field_val->parent.data.p_struct.struct_val = struct_val;
16983 field_val->parent.data.p_struct.field_index = old_field_count;
16984 }
16985 }
16986
16987 result_loc = ir_analyze_struct_field_ptr(ira, suspend_source_instr, field, casted_ptr,
16988 isf->inferred_struct_type, true);
16989 result_loc_pass1->resolved_loc = result_loc;
16990 }
16991
16992
1693316993 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, suspend_source_instr);
1693416994 ZigType *actual_elem_type = result_loc->value->type->data.pointer.child_type;
1693516995 if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional &&
......@@ -17362,62 +17422,6 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
1736217422 return ir_const_void(ira, source_instr);
1736317423 }
1736417424
17365 InferredStructField *isf = ptr->value->type->data.pointer.inferred_struct_field;
17366 if (allow_write_through_const && isf != nullptr) {
17367 // Now it's time to add the field to the struct type.
17368 uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count;
17369 uint32_t new_field_count = old_field_count + 1;
17370 isf->inferred_struct_type->data.structure.src_field_count = new_field_count;
17371 isf->inferred_struct_type->data.structure.fields = realloc_type_struct_fields(
17372 isf->inferred_struct_type->data.structure.fields, old_field_count, new_field_count);
17373
17374 TypeStructField *field = isf->inferred_struct_type->data.structure.fields[old_field_count];
17375 field->name = isf->field_name;
17376 field->type_entry = uncasted_value->value->type;
17377 field->type_val = create_const_type(ira->codegen, field->type_entry);
17378 field->src_index = old_field_count;
17379 field->decl_node = uncasted_value->source_node;
17380 if (instr_is_comptime(uncasted_value)) {
17381 ZigValue *uncasted_val = ir_resolve_const(ira, uncasted_value, UndefOk);
17382 field->is_comptime = true;
17383 field->init_val = create_const_vals(1);
17384 copy_const_val(field->init_val, uncasted_val);
17385 return ir_const_void(ira, source_instr);
17386 }
17387
17388 ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false);
17389 IrInstruction *casted_ptr;
17390 if (instr_is_comptime(ptr)) {
17391 casted_ptr = ir_const(ira, source_instr, struct_ptr_type);
17392 copy_const_val(casted_ptr->value, ptr->value);
17393 casted_ptr->value->type = struct_ptr_type;
17394 } else {
17395 casted_ptr = ptr;
17396 }
17397 if (instr_is_comptime(casted_ptr)) {
17398 ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad);
17399 if (!ptr_val)
17400 return ira->codegen->invalid_instruction;
17401 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
17402 ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val,
17403 source_instr->source_node);
17404 struct_val->special = ConstValSpecialStatic;
17405 struct_val->data.x_struct.fields = realloc_const_vals_ptrs(struct_val->data.x_struct.fields,
17406 old_field_count, new_field_count);
17407
17408 ZigValue *field_val = struct_val->data.x_struct.fields[old_field_count];
17409 field_val->special = ConstValSpecialUndef;
17410 field_val->type = field->type_entry;
17411 field_val->parent.id = ConstParentIdStruct;
17412 field_val->parent.data.p_struct.struct_val = struct_val;
17413 field_val->parent.data.p_struct.field_index = old_field_count;
17414 }
17415 }
17416
17417 ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, casted_ptr,
17418 isf->inferred_struct_type, true);
17419 }
17420
1742117425 if (ptr->value->type->data.pointer.is_const && !allow_write_through_const) {
1742217426 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
1742317427 return ira->codegen->invalid_instruction;
......@@ -19105,13 +19109,27 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1910519109 {
1910619110 ZigType *usize = ira->codegen->builtin_types.entry_usize;
1910719111 IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize);
19108 if (casted_elem_index == ira->codegen->invalid_instruction)
19112 if (type_is_invalid(casted_elem_index->value->type))
1910919113 return ira->codegen->invalid_instruction;
1911019114 ir_assert(instr_is_comptime(casted_elem_index), &elem_ptr_instruction->base);
1911119115 Buf *field_name = buf_alloc();
1911219116 bigint_append_buf(field_name, &casted_elem_index->value->data.x_bigint, 10);
1911319117 return ir_analyze_inferred_field_ptr(ira, field_name, &elem_ptr_instruction->base,
1911419118 array_ptr, array_type);
19119 } else if (is_tuple(array_type)) {
19120 uint64_t elem_index_scalar;
19121 if (!ir_resolve_usize(ira, elem_index, &elem_index_scalar))
19122 return ira->codegen->invalid_instruction;
19123 if (elem_index_scalar >= array_type->data.structure.src_field_count) {
19124 ir_add_error(ira, &elem_ptr_instruction->base, buf_sprintf(
19125 "field index %" ZIG_PRI_u64 " outside tuple '%s' which has %" PRIu32 " fields",
19126 elem_index_scalar, buf_ptr(&array_type->name),
19127 array_type->data.structure.src_field_count));
19128 return ira->codegen->invalid_instruction;
19129 }
19130 TypeStructField *field = array_type->data.structure.fields[elem_index_scalar];
19131 return ir_analyze_struct_field_ptr(ira, &elem_ptr_instruction->base, field, array_ptr,
19132 array_type, false);
1911519133 } else {
1911619134 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
1911719135 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name)));
test/stage1/behavior/struct.zig+14
......@@ -799,3 +799,17 @@ test "comptime struct field" {
799799 var foo: T = undefined;
800800 comptime expect(foo.b == 1234);
801801}
802
803test "anon struct literal field value initialized with fn call" {
804 const S = struct {
805 fn doTheTest() void {
806 var x = .{foo()};
807 expectEqualSlices(u8, x[0], "hi");
808 }
809 fn foo() []const u8 {
810 return "hi";
811 }
812 };
813 S.doTheTest();
814 comptime S.doTheTest();
815}