From db50cf7049b6171a280767e7b1cd0bd215848c92 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 26 Aug 2019 22:38:45 -0400 Subject: [PATCH] fix more compile error regressions --- src/analyze.cpp | 41 +++++++++++++++++++++++++---------------- src/analyze.hpp | 1 + src/ir.cpp | 35 ++++++++++++++++++++++++++--------- test/compile_errors.zig | 10 ++++------ 4 files changed, 56 insertions(+), 31 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 366cb5979..f1df64b17 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1603,14 +1603,17 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc } if (!calling_convention_allows_zig_types(fn_type_id.cc) && - fn_type_id.return_type->id != ZigTypeIdVoid && - !type_allowed_in_extern(g, fn_type_id.return_type)) + fn_type_id.return_type->id != ZigTypeIdVoid) { - add_node_error(g, fn_proto->return_type, - buf_sprintf("return type '%s' not allowed in function with calling convention '%s'", - buf_ptr(&fn_type_id.return_type->name), - calling_convention_name(fn_type_id.cc))); - return g->builtin_types.entry_invalid; + if ((err = type_resolve(g, fn_type_id.return_type, ResolveStatusSizeKnown))) + return g->builtin_types.entry_invalid; + if (!type_allowed_in_extern(g, fn_type_id.return_type)) { + add_node_error(g, fn_proto->return_type, + buf_sprintf("return type '%s' not allowed in function with calling convention '%s'", + buf_ptr(&fn_type_id.return_type->name), + calling_convention_name(fn_type_id.cc))); + return g->builtin_types.entry_invalid; + } } switch (fn_type_id.return_type->id) { @@ -2018,6 +2021,17 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { return ErrorNone; } +ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field) { + Error err; + if (union_field->type_entry == nullptr) { + if ((err = ir_resolve_lazy(g, union_field->decl_node, union_field->type_val))) { + return nullptr; + } + union_field->type_entry = union_field->type_val->data.x_type; + } + return union_field->type_entry; +} + static Error resolve_union_type(CodeGen *g, ZigType *union_type) { assert(union_type->id == ZigTypeIdUnion); @@ -2057,17 +2071,12 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { union_type->data.unionation.resolve_loop_flag_other = true; for (uint32_t i = 0; i < field_count; i += 1) { - AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); TypeUnionField *union_field = &union_type->data.unionation.fields[i]; - - if (union_field->type_entry == nullptr) { - if ((err = ir_resolve_lazy(g, field_source_node, union_field->type_val))) { - union_type->data.unionation.resolve_status = ResolveStatusInvalid; - return err; - } - union_field->type_entry = union_field->type_val->data.x_type; + ZigType *field_type = resolve_union_field_type(g, union_field); + if (field_type == nullptr) { + union_type->data.unionation.resolve_status = ResolveStatusInvalid; + return ErrorSemanticAnalyzeFail; } - ZigType *field_type = union_field->type_entry; if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { union_type->data.unionation.resolve_status = ResolveStatusInvalid; diff --git a/src/analyze.hpp b/src/analyze.hpp index 63ad90579..ef079a94c 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -247,5 +247,6 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn); bool fn_is_async(ZigFn *fn); Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align); +ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field); #endif diff --git a/src/ir.cpp b/src/ir.cpp index f9f64d678..eb87706c5 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6830,7 +6830,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod const char modifier = *buf_ptr(asm_output->constraint); if (modifier != '=') { add_node_error(irb->codegen, node, - buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported" + buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported." " Compiler TODO: see https://github.com/ziglang/zig/issues/215", buf_ptr(asm_output->asm_symbolic_name), modifier)); return irb->codegen->invalid_instruction; @@ -8176,9 +8176,19 @@ bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); } +static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) { + if (!exec || !exec->source_node || limit < 0) return; + add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); + + ir_add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1); +} + static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) { ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); invalidate_exec(exec, err_msg); + if (exec->parent_exec) { + ir_add_call_stack_errors(codegen, exec, err_msg, 10); + } return err_msg; } @@ -10783,8 +10793,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod ir_gen(codegen, node, scope, ir_executable); if (ir_executable->first_err_trace_msg != nullptr) { - codegen->trace_err = add_error_note(codegen, ir_executable->first_err_trace_msg, - source_node, buf_create_from_str("called from here")); + codegen->trace_err = ir_executable->first_err_trace_msg; return &codegen->invalid_instruction->value; } @@ -11408,10 +11417,13 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so return ira->codegen->invalid_instruction; TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); assert(union_field != nullptr); - if ((err = type_resolve(ira->codegen, union_field->type_entry, ResolveStatusZeroBitsKnown))) + ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); + if (field_type == nullptr) + return ira->codegen->invalid_instruction; + if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) return ira->codegen->invalid_instruction; - switch (type_has_one_possible_value(ira->codegen, union_field->type_entry)) { + switch (type_has_one_possible_value(ira->codegen, field_type)) { case OnePossibleValueInvalid: return ira->codegen->invalid_instruction; case OnePossibleValueNo: { @@ -11420,7 +11432,7 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", buf_ptr(&wanted_type->name), - buf_ptr(&union_field->type_entry->name), + buf_ptr(&field_type->name), buf_ptr(union_field->name))); add_error_note(ira->codegen, msg, field_node, buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); @@ -11436,7 +11448,7 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so bigint_init_bigint(&result->value.data.x_union.tag, &val->data.x_enum_tag); result->value.data.x_union.payload = create_const_vals(1); result->value.data.x_union.payload->special = ConstValSpecialStatic; - result->value.data.x_union.payload->type = union_field->type_entry; + result->value.data.x_union.payload->type = field_type; return result; } @@ -11453,12 +11465,17 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so buf_ptr(&wanted_type->name))); for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; - if (type_has_bits(union_field->type_entry)) { + ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); + if (field_type == nullptr) + return ira->codegen->invalid_instruction; + if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) + return ira->codegen->invalid_instruction; + if (type_has_bits(field_type)) { AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); add_error_note(ira->codegen, msg, field_node, buf_sprintf("field '%s' has type '%s'", buf_ptr(union_field->name), - buf_ptr(&union_field->type_entry->name))); + buf_ptr(&field_type->name))); } } return ira->codegen->invalid_instruction; diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 49c836f6a..59687a6cc 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -470,7 +470,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { ); cases.add( - "Generic function where return type is self-referenced", + "generic function where return type is self-referenced", \\fn Foo(comptime T: type) Foo(T) { \\ return struct{ x: T }; \\} @@ -481,7 +481,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} , "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches", - "tmp.zig:1:29: note: referenced here", "tmp.zig:5:18: note: referenced here", ); @@ -3597,7 +3596,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { ); cases.add( - "non constant expression in array size outside function", + "non constant expression in array size", \\const Foo = struct { \\ y: [get()]u8, \\}; @@ -3608,7 +3607,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { , "tmp.zig:5:25: error: unable to evaluate constant expression", "tmp.zig:2:12: note: referenced here", - "tmp.zig:2:8: note: referenced here", ); cases.add( @@ -4620,7 +4618,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn entry() usize { return @sizeOf(@typeOf(foo)); } , "tmp.zig:2:26: error: index 1 outside argument list of size 1", - "tmp.zig:6:15: note: referenced here", + "tmp.zig:6:15: note: called from here", ); cases.add( @@ -5941,7 +5939,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ var x: MultipleChoice = undefined; \\} , - "tmp.zig:2:14: error: non-enum union field assignment", + "tmp.zig:2:14: error: untagged union field assignment", "tmp.zig:1:24: note: consider 'union(enum)' here", );