authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-10 10:57:40-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-10 10:57:40-05:00
log70a4794c57425d75505583e03919df983c4d8ccd
tree86428ba6e9992eaa41b4e7491b90e424da909e0f
parent014f66e6de4aaf81f32c796b12f981326a479397
signaturelock-open Commit is signed but in an unrecognized format.

fix compiler assertion when duplicating fields...

...in nested anonymous struct literals closes #4391

2 files changed, 38 insertions(+), 15 deletions(-)

src/ir.cpp+22-15
......@@ -771,23 +771,9 @@ static void ira_deref(IrAnalyze *ira) {
771771 destroy(ira, "IrAnalyze");
772772}
773773
774static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
774static ZigValue *const_ptr_pointee_unchecked_no_isf(CodeGen *g, ZigValue *const_val) {
775775 assert(get_src_ptr_type(const_val->type) != nullptr);
776776 assert(const_val->special == ConstValSpecialStatic);
777 ZigValue *result;
778
779 InferredStructField *isf = const_val->type->data.pointer.inferred_struct_field;
780 if (isf != nullptr) {
781 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name);
782 assert(field != nullptr);
783 if (field->is_comptime) {
784 assert(field->init_val != nullptr);
785 return field->init_val;
786 }
787 assert(const_val->data.x_ptr.special == ConstPtrSpecialRef);
788 ZigValue *struct_val = const_val->data.x_ptr.data.ref.pointee;
789 return struct_val->data.x_struct.fields[field->src_index];
790 }
791777
792778 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) {
793779 case OnePossibleValueInvalid:
......@@ -798,6 +784,7 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
798784 break;
799785 }
800786
787 ZigValue *result;
801788 switch (const_val->data.x_ptr.special) {
802789 case ConstPtrSpecialInvalid:
803790 zig_unreachable();
......@@ -843,6 +830,26 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
843830 return result;
844831}
845832
833static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
834 assert(get_src_ptr_type(const_val->type) != nullptr);
835 assert(const_val->special == ConstValSpecialStatic);
836
837 InferredStructField *isf = const_val->type->data.pointer.inferred_struct_field;
838 if (isf != nullptr) {
839 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name);
840 assert(field != nullptr);
841 if (field->is_comptime) {
842 assert(field->init_val != nullptr);
843 return field->init_val;
844 }
845 ZigValue *struct_val = const_ptr_pointee_unchecked_no_isf(g, const_val);
846 assert(struct_val->type->id == ZigTypeIdStruct);
847 return struct_val->data.x_struct.fields[field->src_index];
848 }
849
850 return const_ptr_pointee_unchecked_no_isf(g, const_val);
851}
852
846853static bool is_tuple(ZigType *type) {
847854 return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialInferredTuple;
848855}
test/compile_errors.zig+16
......@@ -3,6 +3,22 @@ const builtin = @import("builtin");
33const Target = @import("std").Target;
44
55pub fn addCases(cases: *tests.CompileErrorContext) void {
6 cases.addTest("duplicate field in anonymous struct literal",
7 \\export fn entry() void {
8 \\ const anon = .{
9 \\ .inner = .{
10 \\ .a = .{
11 \\ .something = "text",
12 \\ },
13 \\ .a = .{},
14 \\ },
15 \\ };
16 \\}
17 , &[_][]const u8{
18 "tmp.zig:7:13: error: duplicate field",
19 "tmp.zig:4:13: note: other field here",
20 });
21
622 cases.addTest("type mismatch in C prototype with varargs",
723 \\const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void;
824 \\extern fn fn_decl(fmt: [*:0]u8, ...) void;