From 70a4794c57425d75505583e03919df983c4d8ccd Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 10 Feb 2020 10:57:40 -0500 Subject: [PATCH] fix compiler assertion when duplicating fields... ...in nested anonymous struct literals closes #4391 --- src/ir.cpp | 37 ++++++++++++++++++++++--------------- test/compile_errors.zig | 16 ++++++++++++++++ 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index f71fe73567..f73b5ede1b 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -771,23 +771,9 @@ static void ira_deref(IrAnalyze *ira) { destroy(ira, "IrAnalyze"); } -static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) { +static ZigValue *const_ptr_pointee_unchecked_no_isf(CodeGen *g, ZigValue *const_val) { assert(get_src_ptr_type(const_val->type) != nullptr); assert(const_val->special == ConstValSpecialStatic); - ZigValue *result; - - InferredStructField *isf = const_val->type->data.pointer.inferred_struct_field; - if (isf != nullptr) { - TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); - assert(field != nullptr); - if (field->is_comptime) { - assert(field->init_val != nullptr); - return field->init_val; - } - assert(const_val->data.x_ptr.special == ConstPtrSpecialRef); - ZigValue *struct_val = const_val->data.x_ptr.data.ref.pointee; - return struct_val->data.x_struct.fields[field->src_index]; - } switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { case OnePossibleValueInvalid: @@ -798,6 +784,7 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) { break; } + ZigValue *result; switch (const_val->data.x_ptr.special) { case ConstPtrSpecialInvalid: zig_unreachable(); @@ -843,6 +830,26 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) { return result; } +static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) { + assert(get_src_ptr_type(const_val->type) != nullptr); + assert(const_val->special == ConstValSpecialStatic); + + InferredStructField *isf = const_val->type->data.pointer.inferred_struct_field; + if (isf != nullptr) { + TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); + assert(field != nullptr); + if (field->is_comptime) { + assert(field->init_val != nullptr); + return field->init_val; + } + ZigValue *struct_val = const_ptr_pointee_unchecked_no_isf(g, const_val); + assert(struct_val->type->id == ZigTypeIdStruct); + return struct_val->data.x_struct.fields[field->src_index]; + } + + return const_ptr_pointee_unchecked_no_isf(g, const_val); +} + static bool is_tuple(ZigType *type) { return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialInferredTuple; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 45586ce0e0..cc2863a046 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -3,6 +3,22 @@ const builtin = @import("builtin"); const Target = @import("std").Target; pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.addTest("duplicate field in anonymous struct literal", + \\export fn entry() void { + \\ const anon = .{ + \\ .inner = .{ + \\ .a = .{ + \\ .something = "text", + \\ }, + \\ .a = .{}, + \\ }, + \\ }; + \\} + , &[_][]const u8{ + "tmp.zig:7:13: error: duplicate field", + "tmp.zig:4:13: note: other field here", + }); + cases.addTest("type mismatch in C prototype with varargs", \\const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void; \\extern fn fn_decl(fmt: [*:0]u8, ...) void;