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) {...@@ -771,23 +771,9 @@ static void ira_deref(IrAnalyze *ira) {
771 destroy(ira, "IrAnalyze");771 destroy(ira, "IrAnalyze");
772}772}
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) {
775 assert(get_src_ptr_type(const_val->type) != nullptr);775 assert(get_src_ptr_type(const_val->type) != nullptr);
776 assert(const_val->special == ConstValSpecialStatic);776 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
792 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) {778 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) {
793 case OnePossibleValueInvalid:779 case OnePossibleValueInvalid:
...@@ -798,6 +784,7 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {...@@ -798,6 +784,7 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
798 break;784 break;
799 }785 }
800786
787 ZigValue *result;
801 switch (const_val->data.x_ptr.special) {788 switch (const_val->data.x_ptr.special) {
802 case ConstPtrSpecialInvalid:789 case ConstPtrSpecialInvalid:
803 zig_unreachable();790 zig_unreachable();
...@@ -843,6 +830,26 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {...@@ -843,6 +830,26 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
843 return result;830 return result;
844}831}
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
846static bool is_tuple(ZigType *type) {853static bool is_tuple(ZigType *type) {
847 return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialInferredTuple;854 return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialInferredTuple;
848}855}
test/compile_errors.zig+16
...@@ -3,6 +3,22 @@ const builtin = @import("builtin");...@@ -3,6 +3,22 @@ const builtin = @import("builtin");
3const Target = @import("std").Target;3const Target = @import("std").Target;
44
5pub fn addCases(cases: *tests.CompileErrorContext) void {5pub 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
6 cases.addTest("type mismatch in C prototype with varargs",22 cases.addTest("type mismatch in C prototype with varargs",
7 \\const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void;23 \\const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void;
8 \\extern fn fn_decl(fmt: [*:0]u8, ...) void;24 \\extern fn fn_decl(fmt: [*:0]u8, ...) void;