| author | |
| committer | |
| log | db50cf7049b6171a280767e7b1cd0bd215848c92 |
| tree | 0faa1954f9bb4ca06a26da0d1f8e3b66e70baa6b |
| parent | bad4b040cca553ae6845b18f268313f02077f6c1 |
| signature |
4 files changed, 56 insertions(+), 31 deletions(-)
src/analyze.cpp+25-16| ... | ... | @@ -1603,14 +1603,17 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc |
| 1603 | 1603 | } |
| 1604 | 1604 | |
| 1605 | 1605 | if (!calling_convention_allows_zig_types(fn_type_id.cc) && |
| 1606 | fn_type_id.return_type->id != ZigTypeIdVoid && | |
| 1607 | !type_allowed_in_extern(g, fn_type_id.return_type)) | |
| 1606 | fn_type_id.return_type->id != ZigTypeIdVoid) | |
| 1608 | 1607 | { |
| 1609 | add_node_error(g, fn_proto->return_type, | |
| 1610 | buf_sprintf("return type '%s' not allowed in function with calling convention '%s'", | |
| 1611 | buf_ptr(&fn_type_id.return_type->name), | |
| 1612 | calling_convention_name(fn_type_id.cc))); | |
| 1613 | return g->builtin_types.entry_invalid; | |
| 1608 | if ((err = type_resolve(g, fn_type_id.return_type, ResolveStatusSizeKnown))) | |
| 1609 | return g->builtin_types.entry_invalid; | |
| 1610 | if (!type_allowed_in_extern(g, fn_type_id.return_type)) { | |
| 1611 | add_node_error(g, fn_proto->return_type, | |
| 1612 | buf_sprintf("return type '%s' not allowed in function with calling convention '%s'", | |
| 1613 | buf_ptr(&fn_type_id.return_type->name), | |
| 1614 | calling_convention_name(fn_type_id.cc))); | |
| 1615 | return g->builtin_types.entry_invalid; | |
| 1616 | } | |
| 1614 | 1617 | } |
| 1615 | 1618 | |
| 1616 | 1619 | switch (fn_type_id.return_type->id) { |
| ... | ... | @@ -2018,6 +2021,17 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 2018 | 2021 | return ErrorNone; |
| 2019 | 2022 | } |
| 2020 | 2023 | |
| 2024 | ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field) { | |
| 2025 | Error err; | |
| 2026 | if (union_field->type_entry == nullptr) { | |
| 2027 | if ((err = ir_resolve_lazy(g, union_field->decl_node, union_field->type_val))) { | |
| 2028 | return nullptr; | |
| 2029 | } | |
| 2030 | union_field->type_entry = union_field->type_val->data.x_type; | |
| 2031 | } | |
| 2032 | return union_field->type_entry; | |
| 2033 | } | |
| 2034 | ||
| 2021 | 2035 | static Error resolve_union_type(CodeGen *g, ZigType *union_type) { |
| 2022 | 2036 | assert(union_type->id == ZigTypeIdUnion); |
| 2023 | 2037 | |
| ... | ... | @@ -2057,17 +2071,12 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { |
| 2057 | 2071 | union_type->data.unionation.resolve_loop_flag_other = true; |
| 2058 | 2072 | |
| 2059 | 2073 | for (uint32_t i = 0; i < field_count; i += 1) { |
| 2060 | AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); | |
| 2061 | 2074 | TypeUnionField *union_field = &union_type->data.unionation.fields[i]; |
| 2062 | ||
| 2063 | if (union_field->type_entry == nullptr) { | |
| 2064 | if ((err = ir_resolve_lazy(g, field_source_node, union_field->type_val))) { | |
| 2065 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | |
| 2066 | return err; | |
| 2067 | } | |
| 2068 | union_field->type_entry = union_field->type_val->data.x_type; | |
| 2075 | ZigType *field_type = resolve_union_field_type(g, union_field); | |
| 2076 | if (field_type == nullptr) { | |
| 2077 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; | |
| 2078 | return ErrorSemanticAnalyzeFail; | |
| 2069 | 2079 | } |
| 2070 | ZigType *field_type = union_field->type_entry; | |
| 2071 | 2080 | |
| 2072 | 2081 | if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { |
| 2073 | 2082 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
src/analyze.hpp+1| ... | ... | @@ -247,5 +247,6 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn); |
| 247 | 247 | bool fn_is_async(ZigFn *fn); |
| 248 | 248 | |
| 249 | 249 | Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align); |
| 250 | ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field); | |
| 250 | 251 | |
| 251 | 252 | #endif |
src/ir.cpp+26-9| ... | ... | @@ -6830,7 +6830,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod |
| 6830 | 6830 | const char modifier = *buf_ptr(asm_output->constraint); |
| 6831 | 6831 | if (modifier != '=') { |
| 6832 | 6832 | add_node_error(irb->codegen, node, |
| 6833 | buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported" | |
| 6833 | buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported." | |
| 6834 | 6834 | " Compiler TODO: see https://github.com/ziglang/zig/issues/215", |
| 6835 | 6835 | buf_ptr(asm_output->asm_symbolic_name), modifier)); |
| 6836 | 6836 | return irb->codegen->invalid_instruction; |
| ... | ... | @@ -8176,9 +8176,19 @@ bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { |
| 8176 | 8176 | return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); |
| 8177 | 8177 | } |
| 8178 | 8178 | |
| 8179 | static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) { | |
| 8180 | if (!exec || !exec->source_node || limit < 0) return; | |
| 8181 | add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); | |
| 8182 | ||
| 8183 | ir_add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1); | |
| 8184 | } | |
| 8185 | ||
| 8179 | 8186 | static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) { |
| 8180 | 8187 | ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); |
| 8181 | 8188 | invalidate_exec(exec, err_msg); |
| 8189 | if (exec->parent_exec) { | |
| 8190 | ir_add_call_stack_errors(codegen, exec, err_msg, 10); | |
| 8191 | } | |
| 8182 | 8192 | return err_msg; |
| 8183 | 8193 | } |
| 8184 | 8194 | |
| ... | ... | @@ -10783,8 +10793,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod |
| 10783 | 10793 | ir_gen(codegen, node, scope, ir_executable); |
| 10784 | 10794 | |
| 10785 | 10795 | if (ir_executable->first_err_trace_msg != nullptr) { |
| 10786 | codegen->trace_err = add_error_note(codegen, ir_executable->first_err_trace_msg, | |
| 10787 | source_node, buf_create_from_str("called from here")); | |
| 10796 | codegen->trace_err = ir_executable->first_err_trace_msg; | |
| 10788 | 10797 | return &codegen->invalid_instruction->value; |
| 10789 | 10798 | } |
| 10790 | 10799 | |
| ... | ... | @@ -11408,10 +11417,13 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so |
| 11408 | 11417 | return ira->codegen->invalid_instruction; |
| 11409 | 11418 | TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); |
| 11410 | 11419 | assert(union_field != nullptr); |
| 11411 | if ((err = type_resolve(ira->codegen, union_field->type_entry, ResolveStatusZeroBitsKnown))) | |
| 11420 | ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); | |
| 11421 | if (field_type == nullptr) | |
| 11422 | return ira->codegen->invalid_instruction; | |
| 11423 | if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) | |
| 11412 | 11424 | return ira->codegen->invalid_instruction; |
| 11413 | 11425 | |
| 11414 | switch (type_has_one_possible_value(ira->codegen, union_field->type_entry)) { | |
| 11426 | switch (type_has_one_possible_value(ira->codegen, field_type)) { | |
| 11415 | 11427 | case OnePossibleValueInvalid: |
| 11416 | 11428 | return ira->codegen->invalid_instruction; |
| 11417 | 11429 | case OnePossibleValueNo: { |
| ... | ... | @@ -11420,7 +11432,7 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so |
| 11420 | 11432 | ErrorMsg *msg = ir_add_error(ira, source_instr, |
| 11421 | 11433 | buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", |
| 11422 | 11434 | buf_ptr(&wanted_type->name), |
| 11423 | buf_ptr(&union_field->type_entry->name), | |
| 11435 | buf_ptr(&field_type->name), | |
| 11424 | 11436 | buf_ptr(union_field->name))); |
| 11425 | 11437 | add_error_note(ira->codegen, msg, field_node, |
| 11426 | 11438 | 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 |
| 11436 | 11448 | bigint_init_bigint(&result->value.data.x_union.tag, &val->data.x_enum_tag); |
| 11437 | 11449 | result->value.data.x_union.payload = create_const_vals(1); |
| 11438 | 11450 | result->value.data.x_union.payload->special = ConstValSpecialStatic; |
| 11439 | result->value.data.x_union.payload->type = union_field->type_entry; | |
| 11451 | result->value.data.x_union.payload->type = field_type; | |
| 11440 | 11452 | return result; |
| 11441 | 11453 | } |
| 11442 | 11454 | |
| ... | ... | @@ -11453,12 +11465,17 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so |
| 11453 | 11465 | buf_ptr(&wanted_type->name))); |
| 11454 | 11466 | for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { |
| 11455 | 11467 | TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; |
| 11456 | if (type_has_bits(union_field->type_entry)) { | |
| 11468 | ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); | |
| 11469 | if (field_type == nullptr) | |
| 11470 | return ira->codegen->invalid_instruction; | |
| 11471 | if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) | |
| 11472 | return ira->codegen->invalid_instruction; | |
| 11473 | if (type_has_bits(field_type)) { | |
| 11457 | 11474 | AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); |
| 11458 | 11475 | add_error_note(ira->codegen, msg, field_node, |
| 11459 | 11476 | buf_sprintf("field '%s' has type '%s'", |
| 11460 | 11477 | buf_ptr(union_field->name), |
| 11461 | buf_ptr(&union_field->type_entry->name))); | |
| 11478 | buf_ptr(&field_type->name))); | |
| 11462 | 11479 | } |
| 11463 | 11480 | } |
| 11464 | 11481 | return ira->codegen->invalid_instruction; |
test/compile_errors.zig+4-6| ... | ... | @@ -470,7 +470,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 470 | 470 | ); |
| 471 | 471 | |
| 472 | 472 | cases.add( |
| 473 | "Generic function where return type is self-referenced", | |
| 473 | "generic function where return type is self-referenced", | |
| 474 | 474 | \\fn Foo(comptime T: type) Foo(T) { |
| 475 | 475 | \\ return struct{ x: T }; |
| 476 | 476 | \\} |
| ... | ... | @@ -481,7 +481,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 481 | 481 | \\} |
| 482 | 482 | , |
| 483 | 483 | "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches", |
| 484 | "tmp.zig:1:29: note: referenced here", | |
| 485 | 484 | "tmp.zig:5:18: note: referenced here", |
| 486 | 485 | ); |
| 487 | 486 | |
| ... | ... | @@ -3597,7 +3596,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3597 | 3596 | ); |
| 3598 | 3597 | |
| 3599 | 3598 | cases.add( |
| 3600 | "non constant expression in array size outside function", | |
| 3599 | "non constant expression in array size", | |
| 3601 | 3600 | \\const Foo = struct { |
| 3602 | 3601 | \\ y: [get()]u8, |
| 3603 | 3602 | \\}; |
| ... | ... | @@ -3608,7 +3607,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3608 | 3607 | , |
| 3609 | 3608 | "tmp.zig:5:25: error: unable to evaluate constant expression", |
| 3610 | 3609 | "tmp.zig:2:12: note: referenced here", |
| 3611 | "tmp.zig:2:8: note: referenced here", | |
| 3612 | 3610 | ); |
| 3613 | 3611 | |
| 3614 | 3612 | cases.add( |
| ... | ... | @@ -4620,7 +4618,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4620 | 4618 | \\export fn entry() usize { return @sizeOf(@typeOf(foo)); } |
| 4621 | 4619 | , |
| 4622 | 4620 | "tmp.zig:2:26: error: index 1 outside argument list of size 1", |
| 4623 | "tmp.zig:6:15: note: referenced here", | |
| 4621 | "tmp.zig:6:15: note: called from here", | |
| 4624 | 4622 | ); |
| 4625 | 4623 | |
| 4626 | 4624 | cases.add( |
| ... | ... | @@ -5941,7 +5939,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5941 | 5939 | \\ var x: MultipleChoice = undefined; |
| 5942 | 5940 | \\} |
| 5943 | 5941 | , |
| 5944 | "tmp.zig:2:14: error: non-enum union field assignment", | |
| 5942 | "tmp.zig:2:14: error: untagged union field assignment", | |
| 5945 | 5943 | "tmp.zig:1:24: note: consider 'union(enum)' here", |
| 5946 | 5944 | ); |
| 5947 | 5945 |