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