From 73a7747a9cfb180a92fa0d98f9387d5ad1f47fd2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 26 Aug 2019 12:43:36 -0400 Subject: fix some compile error regressions --- test/compile_errors.zig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'test/compile_errors.zig') diff --git a/test/compile_errors.zig b/test/compile_errors.zig index a6a1d0219b..7ae722366a 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -10,7 +10,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ : [bar] "=r" (-> usize) \\ ); \\} - , "tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs."); + , "tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs"); tc.target = tests.Target{ .Cross = tests.CrossTarget{ .arch = .x86_64, @@ -53,8 +53,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} , "tmp.zig:8:1: error: '@Frame(rangeSum)' depends on itself", - "tmp.zig:15:33: note: when analyzing type '@Frame(rangeSumIndirect)' here", - "tmp.zig:26:25: note: when analyzing type '@Frame(rangeSum)' here", + "tmp.zig:15:33: note: when analyzing type '@Frame(rangeSum)' here", + "tmp.zig:26:25: note: when analyzing type '@Frame(rangeSumIndirect)' here", ); cases.add( @@ -245,7 +245,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { , "tmp.zig:4:1: error: unable to determine async function frame of 'amain'", "tmp.zig:5:10: note: analysis of function 'other' depends on the frame", - "tmp.zig:8:13: note: depends on the frame here", + "tmp.zig:8:13: note: referenced here", ); cases.add( @@ -258,7 +258,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} , "tmp.zig:4:1: error: cannot resolve '@Frame(amain)': function not fully analyzed yet", - "tmp.zig:5:13: note: depends on its own frame here", + "tmp.zig:5:13: note: referenced here", ); cases.add( @@ -1091,7 +1091,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ return 5678; \\} , - "tmp.zig:2:12: error: `&&` is invalid. Note that `and` is boolean AND.", + "tmp.zig:2:12: error: `&&` is invalid. Note that `and` is boolean AND", ); cases.add( -- cgit v1.2.3 From d316f704501ff7fc809fdfb082226031ef875046 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 26 Aug 2019 14:01:59 -0400 Subject: fix regression on struct field with undefined type --- src/analyze.cpp | 59 +++++++++++++++++++++---------------------------- src/analyze.hpp | 5 ++--- src/ir.cpp | 24 +++++++++----------- src/ir.hpp | 2 +- test/compile_errors.zig | 2 +- 5 files changed, 40 insertions(+), 52 deletions(-) (limited to 'test/compile_errors.zig') diff --git a/src/analyze.cpp b/src/analyze.cpp index bba26b29ae..b9b8cae8aa 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -961,18 +961,14 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind return entry; } -ConstExprValue *analyze_const_value_allow_lazy(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, - Buf *type_name, bool allow_lazy) +ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, + Buf *type_name, UndefAllowed undef) { size_t backward_branch_count = 0; size_t backward_branch_quota = default_backward_branch_quota; return ir_eval_const_value(g, scope, node, type_entry, &backward_branch_count, &backward_branch_quota, - nullptr, nullptr, node, type_name, nullptr, nullptr, allow_lazy); -} - -ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name) { - return analyze_const_value_allow_lazy(g, scope, node, type_entry, type_name, false); + nullptr, nullptr, node, type_name, nullptr, nullptr, undef); } static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, ZigType *parent_type, @@ -1162,22 +1158,12 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, Cons } ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { - ConstExprValue *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, nullptr); + ConstExprValue *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, + nullptr, UndefBad); if (type_is_invalid(result->type)) return g->builtin_types.entry_invalid; - - assert(result->special != ConstValSpecialRuntime); - // Reject undefined as valid `type` type even though the specification - // allows it to be casted to anything. - // See also ir_resolve_type() - if (result->special == ConstValSpecialUndef) { - add_node_error(g, node, - buf_sprintf("expected type 'type', found '%s'", - buf_ptr(&g->builtin_types.entry_undef->name))); - return g->builtin_types.entry_invalid; - } - - assert(result->data.x_type != nullptr); + src_assert(result->special == ConstValSpecialStatic, node); + src_assert(result->data.x_type != nullptr, node); return result->data.x_type; } @@ -1225,7 +1211,8 @@ void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_cou } static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_t *result) { - ConstExprValue *align_result = analyze_const_value(g, scope, node, get_align_amt_type(g), nullptr); + ConstExprValue *align_result = analyze_const_value(g, scope, node, get_align_amt_type(g), + nullptr, UndefBad); if (type_is_invalid(align_result->type)) return false; @@ -1247,7 +1234,7 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf ** ZigType *ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, PtrLenUnknown, 0, 0, 0, false); ZigType *str_type = get_slice_type(g, ptr_type); - ConstExprValue *result_val = analyze_const_value(g, scope, node, str_type, nullptr); + ConstExprValue *result_val = analyze_const_value(g, scope, node, str_type, nullptr, UndefBad); if (type_is_invalid(result_val->type)) return false; @@ -2261,7 +2248,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { if (tag_value != nullptr) { // A user-specified value is available - ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, nullptr); + ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, + nullptr, UndefBad); if (type_is_invalid(result->type)) { enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; continue; @@ -2377,8 +2365,8 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { return ErrorSemanticAnalyzeFail; } - ConstExprValue *field_type_val = analyze_const_value_allow_lazy(g, scope, - field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, true); + ConstExprValue *field_type_val = analyze_const_value(g, scope, + field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef); if (type_is_invalid(field_type_val->type)) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; return ErrorSemanticAnalyzeFail; @@ -2660,8 +2648,8 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { return ErrorSemanticAnalyzeFail; } } else { - ConstExprValue *field_type_val = analyze_const_value_allow_lazy(g, scope, - field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, true); + ConstExprValue *field_type_val = analyze_const_value(g, scope, + field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef); if (type_is_invalid(field_type_val->type)) { union_type->data.unionation.resolve_status = ResolveStatusInvalid; return ErrorSemanticAnalyzeFail; @@ -2726,7 +2714,8 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { // In a second pass we will fill in the unspecified ones. if (tag_value != nullptr) { ZigType *tag_int_type = tag_type->data.enumeration.tag_int_type; - ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, nullptr); + ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, + nullptr, UndefBad); if (type_is_invalid(result->type)) { union_type->data.unionation.resolve_status = ResolveStatusInvalid; return ErrorSemanticAnalyzeFail; @@ -2929,7 +2918,7 @@ void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn) { fake_decl->data.symbol_expr.symbol = tld_fn->base.name; // call this for the side effects of casting to panic_fn_type - analyze_const_value(g, tld_fn->base.parent_scope, fake_decl, panic_fn_type, nullptr); + analyze_const_value(g, tld_fn->base.parent_scope, fake_decl, panic_fn_type, nullptr, UndefBad); } ZigType *get_test_fn_type(CodeGen *g) { @@ -3075,7 +3064,8 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) { assert(tld_comptime->base.source_node->type == NodeTypeCompTime); AstNode *expr_node = tld_comptime->base.source_node->data.comptime_expr.expr; - analyze_const_value(g, tld_comptime->base.parent_scope, expr_node, g->builtin_types.entry_void, nullptr); + analyze_const_value(g, tld_comptime->base.parent_scope, expr_node, g->builtin_types.entry_void, + nullptr, UndefBad); } static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { @@ -3443,8 +3433,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { if (explicit_type && explicit_type->id == ZigTypeIdInvalid) { implicit_type = explicit_type; } else if (var_decl->expr) { - init_value = analyze_const_value_allow_lazy(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, - var_decl->symbol, allow_lazy); + init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, + var_decl->symbol, allow_lazy ? LazyOk : UndefOk); assert(init_value); implicit_type = init_value->type; @@ -3599,7 +3589,8 @@ static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, Sco using_namespace->base.resolution = TldResolutionResolving; assert(using_namespace->base.source_node->type == NodeTypeUsingNamespace); ConstExprValue *result = analyze_const_value(g, &dest_decls_scope->base, - using_namespace->base.source_node->data.using_namespace.expr, g->builtin_types.entry_type, nullptr); + using_namespace->base.source_node->data.using_namespace.expr, g->builtin_types.entry_type, + nullptr, UndefBad); using_namespace->using_namespace_value = result; if (type_is_invalid(result->type)) { diff --git a/src/analyze.hpp b/src/analyze.hpp index 79a490ff78..d3c1df4a08 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -240,9 +240,8 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa void src_assert(bool ok, AstNode *source_node); bool is_container(ZigType *type_entry); -ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name); -ConstExprValue *analyze_const_value_allow_lazy(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, - Buf *type_name, bool allow_lazy); +ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, + Buf *type_name, UndefAllowed undef); void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn); bool fn_is_async(ZigFn *fn); diff --git a/src/ir.cpp b/src/ir.cpp index a6c14885ef..c61815b3bb 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -398,7 +398,7 @@ static void ir_ref_var(ZigVar *var) { ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { ConstExprValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type, ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr, - node, nullptr, ira->new_irb.exec, nullptr, false); + node, nullptr, ira->new_irb.exec, nullptr, UndefBad); if (type_is_invalid(result->type)) return ira->codegen->builtin_types.entry_invalid; @@ -10734,14 +10734,14 @@ static Error ir_resolve_const_val(CodeGen *codegen, IrExecutable *exec, AstNode buf_sprintf("unable to evaluate constant expression")); return ErrorSemanticAnalyzeFail; case ConstValSpecialUndef: - if (undef_allowed == UndefOk) + if (undef_allowed == UndefOk || undef_allowed == LazyOk) return ErrorNone; exec_add_error_node(codegen, exec, source_node, buf_sprintf("use of undefined value here causes undefined behavior")); return ErrorSemanticAnalyzeFail; case ConstValSpecialLazy: - if (undef_allowed == LazyOk) + if (undef_allowed == LazyOk || undef_allowed == LazyOkNoUndef) return ErrorNone; if ((err = ir_resolve_lazy(codegen, source_node, val))) @@ -10765,7 +10765,7 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota, ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, - IrExecutable *parent_exec, AstNode *expected_type_source_node, bool allow_lazy) + IrExecutable *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef_allowed) { Error err; @@ -10819,11 +10819,8 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod ConstExprValue *result = ir_exec_const_result(codegen, analyzed_executable); - if (!allow_lazy) { - if ((err = ir_resolve_lazy(codegen, node, result))) { - return &codegen->invalid_instruction->value; - } - } + if ((err = ir_resolve_const_val(codegen, analyzed_executable, node, result, undef_allowed))) + return &codegen->invalid_instruction->value; return result; } @@ -15578,7 +15575,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c AstNode *body_node = fn_entry->body_node; result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, - nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node, false); + nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node, + UndefOk); if (inferred_err_set_type != nullptr) { inferred_err_set_type->data.error_set.infer_fn = nullptr; @@ -15776,7 +15774,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, - nullptr, false); + nullptr, UndefBad); IrInstructionConst *const_instruction = ir_create_instruction(&ira->new_irb, impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); copy_const_val(&const_instruction->base.value, align_result, true); @@ -19129,7 +19127,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc Scope *analyze_scope = &get_container_scope(container_type)->base; // memoize it field->init_val = analyze_const_value(ira->codegen, analyze_scope, init_node, - field->type_entry, nullptr); + field->type_entry, nullptr, UndefOk); } if (type_is_invalid(field->init_val->type)) return ira->codegen->invalid_instruction; @@ -20640,7 +20638,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct ZigType *void_type = ira->codegen->builtin_types.entry_void; ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, - &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, false); + &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, UndefBad); if (type_is_invalid(cimport_result->type)) return ira->codegen->invalid_instruction; diff --git a/src/ir.hpp b/src/ir.hpp index 200a92b64f..3923ea28e8 100644 --- a/src/ir.hpp +++ b/src/ir.hpp @@ -16,7 +16,7 @@ bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry); ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota, ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, - IrExecutable *parent_exec, AstNode *expected_type_source_node, bool allow_lazy); + IrExecutable *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef); Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 7ae722366a..7e5e3dd601 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -404,7 +404,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ const foo: Foo = undefined; \\} , - "tmp.zig:2:8: error: expected type 'type', found '(undefined)'", + "tmp.zig:2:8: error: use of undefined value here causes undefined behavior", ); cases.add( -- cgit v1.2.3 From bad4b040cca553ae6845b18f268313f02077f6c1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 26 Aug 2019 18:35:36 -0400 Subject: miscellaneous fixes regarding compile errors --- src/all_types.hpp | 3 +++ src/analyze.cpp | 14 +++++----- src/analyze.hpp | 2 +- src/ir.cpp | 43 +++++++++++++++++++++++------ test/compile_errors.zig | 72 +++++++++++++++++++++++++------------------------ 5 files changed, 84 insertions(+), 50 deletions(-) (limited to 'test/compile_errors.zig') diff --git a/src/all_types.hpp b/src/all_types.hpp index 61e71c236c..3145635b45 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -363,8 +363,10 @@ struct LazyValueFnType { AstNode *proto_node; ConstExprValue **param_types; + AstNode **param_type_src_nodes; ConstExprValue *align_val; // can be null ConstExprValue *return_type; + AstNode *return_type_src_node; }; struct ConstExprValue { @@ -1026,6 +1028,7 @@ struct AstNodeEnumLiteral { struct AstNode { enum NodeType type; + bool already_traced_this_node; size_t line; size_t column; ZigType *owner; diff --git a/src/analyze.cpp b/src/analyze.cpp index b9b8cae8aa..366cb59797 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -63,10 +63,11 @@ ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg) { return err; } -ErrorMsg *add_node_error(CodeGen *g, const AstNode *node, Buf *msg) { +ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) { Token fake_token; fake_token.start_line = node->line; fake_token.start_column = node->column; + node->already_traced_this_node = true; return add_token_error(g, node->owner, &fake_token, msg); } @@ -1782,7 +1783,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; add_node_error(g, decl_node, - buf_sprintf("struct '%s' depends on its own size", buf_ptr(&struct_type->name))); + buf_sprintf("struct '%s' depends on itself", buf_ptr(&struct_type->name))); } return ErrorSemanticAnalyzeFail; } @@ -1936,7 +1937,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) { union_type->data.unionation.resolve_status = ResolveStatusInvalid; add_node_error(g, decl_node, - buf_sprintf("union '%s' depends on its own alignment", buf_ptr(&union_type->name))); + buf_sprintf("union '%s' depends on itself", buf_ptr(&union_type->name))); } return ErrorSemanticAnalyzeFail; } @@ -2047,7 +2048,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) { union_type->data.unionation.resolve_status = ResolveStatusInvalid; add_node_error(g, decl_node, - buf_sprintf("union '%s' depends on its own size", buf_ptr(&union_type->name))); + buf_sprintf("union '%s' depends on itself", buf_ptr(&union_type->name))); } return ErrorSemanticAnalyzeFail; } @@ -2452,7 +2453,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; add_node_error(g, decl_node, - buf_sprintf("struct '%s' depends on its own alignment", buf_ptr(&struct_type->name))); + buf_sprintf("struct '%s' depends on itself", buf_ptr(&struct_type->name))); } return ErrorSemanticAnalyzeFail; } @@ -3661,8 +3662,9 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool all } } - if (g->trace_err != nullptr && source_node != nullptr) { + if (g->trace_err != nullptr && source_node != nullptr && !source_node->already_traced_this_node) { g->trace_err = add_error_note(g, g->trace_err, source_node, buf_create_from_str("referenced here")); + source_node->already_traced_this_node = true; } } diff --git a/src/analyze.hpp b/src/analyze.hpp index d3c1df4a08..63ad905798 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -11,7 +11,7 @@ #include "all_types.hpp" void semantic_analyze(CodeGen *g); -ErrorMsg *add_node_error(CodeGen *g, const AstNode *node, Buf *msg); +ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg); ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg); ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg); ZigType *new_type_table_entry(ZigTypeId id); diff --git a/src/ir.cpp b/src/ir.cpp index 832983dbf7..f9f64d6789 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10818,6 +10818,8 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod } ConstExprValue *result = ir_exec_const_result(codegen, analyzed_executable); + if (type_is_invalid(result->type)) + return &codegen->invalid_instruction->value; if ((err = ir_resolve_const_val(codegen, analyzed_executable, node, result, undef_allowed))) return &codegen->invalid_instruction->value; @@ -14330,6 +14332,10 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, // since it's a comptime val there are no instructions for it. // we memcpy the init value here IrInstruction *deref = ir_get_deref(ira, var_ptr, var_ptr, nullptr); + if (type_is_invalid(deref->value.type)) { + var->var_type = ira->codegen->builtin_types.entry_invalid; + return ira->codegen->invalid_instruction; + } // If this assertion trips, something is wrong with the IR instructions, because // we expected the above deref to return a constant value, but it created a runtime // instruction. @@ -21957,6 +21963,11 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction if (slice_ptr == nullptr) return ira->codegen->invalid_instruction; + if (slice_ptr->special == ConstValSpecialUndef) { + ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); + return ira->codegen->invalid_instruction; + } + parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index]; if (parent_ptr->special == ConstValSpecialUndef) { ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); @@ -22836,6 +22847,7 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct size_t param_count = proto_node->data.fn_proto.params.length; lazy_fn_type->proto_node = proto_node; lazy_fn_type->param_types = allocate(param_count); + lazy_fn_type->param_type_src_nodes = allocate(param_count); for (size_t param_index = 0; param_index < param_count; param_index += 1) { AstNode *param_node = proto_node->data.fn_proto.params.at(param_index); @@ -22865,6 +22877,7 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct if (param_type_val == nullptr) return ira->codegen->invalid_instruction; lazy_fn_type->param_types[param_index] = param_type_val; + lazy_fn_type->param_type_src_nodes[param_index] = instruction->param_types[param_index]->source_node; } if (instruction->align_value != nullptr) { @@ -22876,6 +22889,7 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct lazy_fn_type->return_type = ir_resolve_const(ira, instruction->return_type->child, LazyOk); if (lazy_fn_type->return_type == nullptr) return ira->codegen->invalid_instruction; + lazy_fn_type->return_type_src_node = instruction->return_type->source_node; return result; } @@ -25187,7 +25201,10 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ } else { new_exec->first_err_trace_msg = ira->codegen->trace_err; } - if (new_exec->first_err_trace_msg != nullptr) { + if (new_exec->first_err_trace_msg != nullptr && + !old_instruction->source_node->already_traced_this_node) + { + old_instruction->source_node->already_traced_this_node = true; new_exec->first_err_trace_msg = add_error_note(ira->codegen, new_exec->first_err_trace_msg, old_instruction->source_node, buf_create_from_str("referenced here")); } @@ -25204,7 +25221,10 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ if (new_exec->first_err_trace_msg != nullptr) { codegen->trace_err = new_exec->first_err_trace_msg; - if (codegen->trace_err != nullptr) { + if (codegen->trace_err != nullptr && new_exec->source_node != nullptr && + !new_exec->source_node->already_traced_this_node) + { + new_exec->source_node->already_traced_this_node = true; codegen->trace_err = add_error_note(codegen, codegen->trace_err, new_exec->source_node, buf_create_from_str("referenced here")); } @@ -25435,14 +25455,15 @@ static ZigType *ir_resolve_lazy_fn_type(CodeGen *codegen, IrExecutable *exec, As param_info->type = nullptr; return get_generic_fn_type(codegen, &fn_type_id); } else { - ZigType *param_type = ir_resolve_const_type(codegen, exec, source_node, + AstNode *param_src_node = lazy_fn_type->param_type_src_nodes[fn_type_id.next_param_index]; + ZigType *param_type = ir_resolve_const_type(codegen, exec, param_src_node, lazy_fn_type->param_types[fn_type_id.next_param_index]); if (type_is_invalid(param_type)) return nullptr; switch (type_requires_comptime(codegen, param_type)) { case ReqCompTimeYes: if (!calling_convention_allows_zig_types(fn_type_id.cc)) { - exec_add_error_node(codegen, exec, source_node, + exec_add_error_node(codegen, exec, param_src_node, buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); return nullptr; @@ -25459,7 +25480,7 @@ static ZigType *ir_resolve_lazy_fn_type(CodeGen *codegen, IrExecutable *exec, As if ((err = type_resolve(codegen, param_type, ResolveStatusZeroBitsKnown))) return nullptr; if (!type_has_bits(param_type)) { - exec_add_error_node(codegen, exec, source_node, + exec_add_error_node(codegen, exec, param_src_node, buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); return nullptr; @@ -25474,11 +25495,13 @@ static ZigType *ir_resolve_lazy_fn_type(CodeGen *codegen, IrExecutable *exec, As return nullptr; } - fn_type_id.return_type = ir_resolve_const_type(codegen, exec, source_node, lazy_fn_type->return_type); + fn_type_id.return_type = ir_resolve_const_type(codegen, exec, lazy_fn_type->return_type_src_node, + lazy_fn_type->return_type); if (type_is_invalid(fn_type_id.return_type)) return nullptr; if (fn_type_id.return_type->id == ZigTypeIdOpaque) { - exec_add_error_node(codegen, exec, source_node, buf_create_from_str("return type cannot be opaque")); + exec_add_error_node(codegen, exec, lazy_fn_type->return_type_src_node, + buf_create_from_str("return type cannot be opaque")); return nullptr; } @@ -25653,11 +25676,15 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) { Error err; if ((err = ir_resolve_lazy_raw(codegen, source_node, val))) { - if (codegen->trace_err != nullptr) { + if (codegen->trace_err != nullptr && !source_node->already_traced_this_node) { + source_node->already_traced_this_node = true; codegen->trace_err = add_error_note(codegen, codegen->trace_err, source_node, buf_create_from_str("referenced here")); } return err; } + if (type_is_invalid(val->type)) { + return ErrorSemanticAnalyzeFail; + } return ErrorNone; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 7e5e3dd601..49c836f6a3 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -481,7 +481,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} , "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches", - "tmp.zig:1:29: note: called from here", + "tmp.zig:1:29: note: referenced here", + "tmp.zig:5:18: note: referenced here", ); cases.add( @@ -645,7 +646,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\const A = struct { a : A, }; \\export fn entry() usize { return @sizeOf(A); } , - "tmp.zig:1:11: error: struct 'A' contains itself", + "tmp.zig:1:11: error: struct 'A' depends on itself", ); cases.add( @@ -655,7 +656,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\const C = struct { a : A, }; \\export fn entry() usize { return @sizeOf(A); } , - "tmp.zig:1:11: error: struct 'A' contains itself", + "tmp.zig:1:11: error: struct 'A' depends on itself", ); cases.add( @@ -670,7 +671,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ return @sizeOf(@typeOf(foo.x)); \\} , - "tmp.zig:1:13: error: struct 'Foo' contains itself", + "tmp.zig:1:13: error: struct 'Foo' depends on itself", "tmp.zig:8:28: note: referenced here", ); @@ -689,7 +690,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} , "tmp.zig:7:9: error: dependency loop detected", - "tmp.zig:2:19: note: called from here", + "tmp.zig:2:19: note: referenced here", "tmp.zig:10:21: note: referenced here", ); @@ -703,7 +704,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ var s: Foo = Foo.E; \\} , - "tmp.zig:1:17: error: 'Foo' depends on itself", + "tmp.zig:1:17: error: enum 'Foo' depends on itself", ); cases.add( @@ -866,7 +867,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { break :x tc; }); - cases.addTest( + cases.add( "export generic function", \\export fn foo(num: var) i32 { \\ return 0; @@ -875,17 +876,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:1:15: error: parameter of type 'var' not allowed in function with calling convention 'ccc'", ); - cases.addTest( + cases.add( "C pointer to c_void", \\export fn a() void { \\ var x: *c_void = undefined; \\ var y: [*c]c_void = x; \\} , - "tmp.zig:3:12: error: C pointers cannot point opaque types", + "tmp.zig:3:16: error: C pointers cannot point opaque types", ); - cases.addTest( + cases.add( "directly embedding opaque type in struct and union", \\const O = @OpaqueType(); \\const Foo = struct { @@ -906,7 +907,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:7:10: error: opaque types have unknown size and therefore cannot be directly embedded in unions", ); - cases.addTest( + cases.add( "implicit cast between C pointer and Zig pointer - bad const/align/child", \\export fn a() void { \\ var x: [*c]u8 = undefined; @@ -942,7 +943,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:23:22: error: expected type '[*c]u32', found '*u8'", ); - cases.addTest( + cases.add( "implicit casting null c pointer to zig pointer", \\comptime { \\ var c_ptr: [*c]u8 = 0; @@ -952,7 +953,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:3:24: error: null pointer casted to type '*u8'", ); - cases.addTest( + cases.add( "implicit casting undefined c pointer to zig pointer", \\comptime { \\ var c_ptr: [*c]u8 = undefined; @@ -962,7 +963,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:3:24: error: use of undefined value here causes undefined behavior", ); - cases.addTest( + cases.add( "implicit casting C pointers which would mess up null semantics", \\export fn entry() void { \\ var slice: []const u8 = "aoeu"; @@ -987,7 +988,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:13:35: note: mutable '[*c]const u8' allows illegal null values stored to type '[*]u8'", ); - cases.addTest( + cases.add( "implicit casting too big integers to C pointers", \\export fn a() void { \\ var ptr: [*c]u8 = (1 << 64) + 1; @@ -1001,14 +1002,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:6:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'", ); - cases.addTest( + cases.add( "C pointer pointing to non C ABI compatible type or has align attr", \\const Foo = struct {}; \\export fn a() void { \\ const T = [*c]Foo; \\} , - "tmp.zig:3:15: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'", + "tmp.zig:3:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'", ); cases.addCase(x: { @@ -1029,7 +1030,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { break :x tc; }); - cases.addTest( + cases.add( "assign to invalid dereference", \\export fn entry() void { \\ 'a'.* = 1; @@ -1038,7 +1039,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:2:8: error: attempt to dereference non-pointer type 'comptime_int'", ); - cases.addTest( + cases.add( "take slice of invalid dereference", \\export fn entry() void { \\ const x = 'a'.*[0..]; @@ -1047,7 +1048,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:2:18: error: attempt to dereference non-pointer type 'comptime_int'", ); - cases.addTest( + cases.add( "@truncate undefined value", \\export fn entry() void { \\ var z = @truncate(u8, u16(undefined)); @@ -1935,7 +1936,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "unknown length pointer to opaque", \\export const T = [*]@OpaqueType(); , - "tmp.zig:1:18: error: unknown-length pointer to opaque", + "tmp.zig:1:21: error: unknown-length pointer to opaque", ); cases.add( @@ -2924,7 +2925,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\fn a() *noreturn {} \\export fn entry() void { _ = a(); } , - "tmp.zig:1:8: error: pointer to noreturn not allowed", + "tmp.zig:1:9: error: pointer to noreturn not allowed", ); cases.add( @@ -3606,8 +3607,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn entry() usize { return @sizeOf(@typeOf(Foo)); } , "tmp.zig:5:25: error: unable to evaluate constant expression", - "tmp.zig:2:12: note: called from here", - "tmp.zig:2:8: note: called from here", + "tmp.zig:2:12: note: referenced here", + "tmp.zig:2:8: note: referenced here", ); cases.add( @@ -3701,7 +3702,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn entry() usize { return @sizeOf(@typeOf(y)); } , "tmp.zig:3:14: error: division by zero", - "tmp.zig:1:14: note: called from here", + "tmp.zig:1:14: note: referenced here", ); cases.add( @@ -4133,7 +4134,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn entry() usize { return @sizeOf(@typeOf(seventh_fib_number)); } , "tmp.zig:3:21: error: evaluation exceeded 1000 backwards branches", - "tmp.zig:3:21: note: called from here", + "tmp.zig:1:37: note: referenced here", + "tmp.zig:6:50: note: referenced here", ); cases.add( @@ -4174,7 +4176,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn entry() usize { return @sizeOf(@typeOf(a)); } , "tmp.zig:6:26: error: unable to evaluate constant expression", - "tmp.zig:4:17: note: called from here", + "tmp.zig:4:17: note: referenced here", ); cases.add( @@ -4257,7 +4259,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn entry() usize { return @sizeOf(@typeOf(y)); } , "tmp.zig:3:12: error: negation caused overflow", - "tmp.zig:1:14: note: called from here", + "tmp.zig:1:14: note: referenced here", ); cases.add( @@ -4270,7 +4272,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn entry() usize { return @sizeOf(@typeOf(y)); } , "tmp.zig:3:14: error: operation caused overflow", - "tmp.zig:1:14: note: called from here", + "tmp.zig:1:14: note: referenced here", ); cases.add( @@ -4283,7 +4285,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn entry() usize { return @sizeOf(@typeOf(y)); } , "tmp.zig:3:14: error: operation caused overflow", - "tmp.zig:1:14: note: called from here", + "tmp.zig:1:14: note: referenced here", ); cases.add( @@ -4296,7 +4298,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn entry() usize { return @sizeOf(@typeOf(y)); } , "tmp.zig:3:14: error: operation caused overflow", - "tmp.zig:1:14: note: called from here", + "tmp.zig:1:14: note: referenced here", ); cases.add( @@ -4388,7 +4390,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} , "tmp.zig:3:7: error: unable to evaluate constant expression", - "tmp.zig:16:19: note: called from here", + "tmp.zig:16:19: note: referenced here", ); cases.add( @@ -4618,7 +4620,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: called from here", + "tmp.zig:6:15: note: referenced here", ); cases.add( @@ -4717,7 +4719,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} , "tmp.zig:10:14: error: unable to evaluate constant expression", - "tmp.zig:6:20: note: called from here", + "tmp.zig:6:20: note: referenced here", ); cases.add( @@ -5864,7 +5866,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} , "tmp.zig:4:25: error: aoeu", - "tmp.zig:1:36: note: called from here", + "tmp.zig:1:36: note: referenced here", "tmp.zig:12:20: note: referenced here", ); -- cgit v1.2.3 From db50cf7049b6171a280767e7b1cd0bd215848c92 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 26 Aug 2019 22:38:45 -0400 Subject: 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(-) (limited to 'test/compile_errors.zig') diff --git a/src/analyze.cpp b/src/analyze.cpp index 366cb59797..f1df64b17e 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 63ad905798..ef079a94cd 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 f9f64d6789..eb87706c57 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 49c836f6a3..59687a6cc3 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", ); -- cgit v1.2.3 From d9ed55f017bdd23054cd1d7f50ac1da517b5a5e4 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 27 Aug 2019 12:54:50 -0400 Subject: fix not properly casting align values and add check for alignment specified on enum fields --- src/all_types.hpp | 43 ++++++------- src/analyze.cpp | 19 +++--- src/ir.cpp | 156 +++++++++++++++++++++++------------------------- test/compile_errors.zig | 27 +++++++++ 4 files changed, 137 insertions(+), 108 deletions(-) (limited to 'test/compile_errors.zig') diff --git a/src/all_types.hpp b/src/all_types.hpp index 3145635b45..83dcb8ba10 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -315,58 +315,61 @@ enum LazyValueId { }; struct LazyValue { - IrExecutable *exec; LazyValueId id; }; struct LazyValueAlignOf { LazyValue base; - ConstExprValue *target_type_val; - AstNode *target_type_src_node; + IrAnalyze *ira; + IrInstruction *target_type; }; struct LazyValueSliceType { LazyValue base; + + IrAnalyze *ira; + ZigType *elem_type; + IrInstruction *align_inst; // can be null + bool is_const; bool is_volatile; bool is_allowzero; - - ZigType *elem_type; - ConstExprValue *align_val; // can be null }; struct LazyValuePtrType { LazyValue base; - bool is_const; - bool is_volatile; - bool is_allowzero; - ConstExprValue *elem_type_val; - AstNode *elem_type_src_node; - ConstExprValue *align_val; // can be null + IrAnalyze *ira; + IrInstruction *elem_type; + IrInstruction *align_inst; // can be null + PtrLen ptr_len; uint32_t bit_offset_in_host; + uint32_t host_int_bytes; + bool is_const; + bool is_volatile; + bool is_allowzero; }; struct LazyValueOptType { LazyValue base; - ConstExprValue *payload_type_val; - AstNode *payload_type_src_node; + IrAnalyze *ira; + IrInstruction *payload_type; }; struct LazyValueFnType { LazyValue base; - bool is_generic; + IrAnalyze *ira; AstNode *proto_node; - ConstExprValue **param_types; - AstNode **param_type_src_nodes; - ConstExprValue *align_val; // can be null - ConstExprValue *return_type; - AstNode *return_type_src_node; + IrInstruction **param_types; + IrInstruction *align_inst; // can be null + IrInstruction *return_type; + + bool is_generic; }; struct ConstExprValue { diff --git a/src/analyze.cpp b/src/analyze.cpp index dde6e3defc..e0223dd9f7 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1000,7 +1000,7 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi case LazyValueIdPtrType: { LazyValuePtrType *lazy_ptr_type = reinterpret_cast(type_val->data.x_lazy); - if (parent_type_val == lazy_ptr_type->elem_type_val) { + if (parent_type_val == &lazy_ptr_type->elem_type->value) { // Does a struct which contains a pointer field to itself have bits? Yes. *is_zero_bits = false; return ErrorNone; @@ -1008,7 +1008,7 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi if (parent_type_val == nullptr) { parent_type_val = type_val; } - return type_val_resolve_zero_bits(g, lazy_ptr_type->elem_type_val, parent_type, + return type_val_resolve_zero_bits(g, &lazy_ptr_type->elem_type->value, parent_type, parent_type_val, is_zero_bits); } } @@ -1061,17 +1061,17 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue } case LazyValueIdPtrType: { LazyValuePtrType *lazy_ptr_type = reinterpret_cast(type_val->data.x_lazy); - return type_val_resolve_requires_comptime(g, lazy_ptr_type->elem_type_val); + return type_val_resolve_requires_comptime(g, &lazy_ptr_type->elem_type->value); } case LazyValueIdOptType: { LazyValueOptType *lazy_opt_type = reinterpret_cast(type_val->data.x_lazy); - return type_val_resolve_requires_comptime(g, lazy_opt_type->payload_type_val); + return type_val_resolve_requires_comptime(g, &lazy_opt_type->payload_type->value); } case LazyValueIdFnType: { LazyValueFnType *lazy_fn_type = reinterpret_cast(type_val->data.x_lazy); if (lazy_fn_type->is_generic) return ReqCompTimeYes; - switch (type_val_resolve_requires_comptime(g, lazy_fn_type->return_type)) { + switch (type_val_resolve_requires_comptime(g, &lazy_fn_type->return_type->value)) { case ReqCompTimeInvalid: return ReqCompTimeInvalid; case ReqCompTimeYes: @@ -1084,7 +1084,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue AstNode *param_node = lazy_fn_type->proto_node->data.fn_proto.params.at(i); bool param_is_var_args = param_node->data.param_decl.is_var_args; if (param_is_var_args) break; - switch (type_val_resolve_requires_comptime(g, lazy_fn_type->param_types[i])) { + switch (type_val_resolve_requires_comptime(g, &lazy_fn_type->param_types[i]->value)) { case ReqCompTimeInvalid: return ReqCompTimeInvalid; case ReqCompTimeYes: @@ -1124,7 +1124,7 @@ Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t return ErrorNone; case LazyValueIdOptType: { LazyValueOptType *lazy_opt_type = reinterpret_cast(type_val->data.x_lazy); - return type_val_resolve_abi_align(g, lazy_opt_type->payload_type_val, abi_align); + return type_val_resolve_abi_align(g, &lazy_opt_type->payload_type->value, abi_align); } } zig_unreachable(); @@ -2245,6 +2245,11 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { buf_sprintf("structs and unions, not enums, support field types")); add_error_note(g, msg, decl_node, buf_sprintf("consider 'union(enum)' here")); + } else if (field_node->data.struct_field.align_expr != nullptr) { + ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.align_expr, + buf_sprintf("structs and unions, not enums, support field alignment")); + add_error_note(g, msg, decl_node, + buf_sprintf("consider 'union(enum)' here")); } auto field_entry = enum_type->data.enumeration.fields_by_name.put_unique(type_enum_field->name, type_enum_field); diff --git a/src/ir.cpp b/src/ir.cpp index be0fd1ba64..c1656a1711 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -16190,14 +16190,13 @@ static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp result->value.special = ConstValSpecialLazy; LazyValueOptType *lazy_opt_type = allocate(1); + lazy_opt_type->ira = ira; result->value.data.x_lazy = &lazy_opt_type->base; lazy_opt_type->base.id = LazyValueIdOptType; - lazy_opt_type->base.exec = ira->new_irb.exec; - lazy_opt_type->payload_type_val = ir_resolve_type_lazy(ira, instruction->value->child); - if (lazy_opt_type->payload_type_val == nullptr) + lazy_opt_type->payload_type = instruction->value->child; + if (ir_resolve_type_lazy(ira, lazy_opt_type->payload_type) == nullptr) return ira->codegen->invalid_instruction; - lazy_opt_type->payload_type_src_node = instruction->value->source_node; return result; } @@ -17936,13 +17935,13 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, result->value.special = ConstValSpecialLazy; LazyValueSliceType *lazy_slice_type = allocate(1); + lazy_slice_type->ira = ira; result->value.data.x_lazy = &lazy_slice_type->base; lazy_slice_type->base.id = LazyValueIdSliceType; - lazy_slice_type->base.exec = ira->new_irb.exec; if (slice_type_instruction->align_value != nullptr) { - lazy_slice_type->align_val = ir_resolve_const(ira, slice_type_instruction->align_value->child, LazyOk); - if (lazy_slice_type->align_val == nullptr) + lazy_slice_type->align_inst = slice_type_instruction->align_value->child; + if (ir_resolve_const(ira, lazy_slice_type->align_inst, LazyOk) == nullptr) return ira->codegen->invalid_instruction; } @@ -22371,14 +22370,13 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct result->value.special = ConstValSpecialLazy; LazyValueAlignOf *lazy_align_of = allocate(1); + lazy_align_of->ira = ira; result->value.data.x_lazy = &lazy_align_of->base; lazy_align_of->base.id = LazyValueIdAlignOf; - lazy_align_of->base.exec = ira->new_irb.exec; - lazy_align_of->target_type_val = ir_resolve_type_lazy(ira, instruction->type_value->child); - if (lazy_align_of->target_type_val == nullptr) + lazy_align_of->target_type = instruction->type_value->child; + if (ir_resolve_type_lazy(ira, lazy_align_of->target_type) == nullptr) return ira->codegen->invalid_instruction; - lazy_align_of->target_type_src_node = instruction->type_value->source_node; return result; } @@ -22856,9 +22854,9 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct result->value.special = ConstValSpecialLazy; LazyValueFnType *lazy_fn_type = allocate(1); + lazy_fn_type->ira = ira; result->value.data.x_lazy = &lazy_fn_type->base; lazy_fn_type->base.id = LazyValueIdFnType; - lazy_fn_type->base.exec = ira->new_irb.exec; if (proto_node->data.fn_proto.auto_err_set) { ir_add_error(ira, &instruction->base, @@ -22868,8 +22866,7 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct size_t param_count = proto_node->data.fn_proto.params.length; lazy_fn_type->proto_node = proto_node; - lazy_fn_type->param_types = allocate(param_count); - lazy_fn_type->param_type_src_nodes = allocate(param_count); + lazy_fn_type->param_types = allocate(param_count); for (size_t param_index = 0; param_index < param_count; param_index += 1) { AstNode *param_node = proto_node->data.fn_proto.params.at(param_index); @@ -22895,23 +22892,20 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct IrInstruction *param_type_value = instruction->param_types[param_index]->child; if (type_is_invalid(param_type_value->value.type)) return ira->codegen->invalid_instruction; - ConstExprValue *param_type_val = ir_resolve_const(ira, param_type_value, LazyOk); - if (param_type_val == nullptr) + if (ir_resolve_const(ira, param_type_value, LazyOk) == nullptr) return ira->codegen->invalid_instruction; - lazy_fn_type->param_types[param_index] = param_type_val; - lazy_fn_type->param_type_src_nodes[param_index] = instruction->param_types[param_index]->source_node; + lazy_fn_type->param_types[param_index] = param_type_value; } if (instruction->align_value != nullptr) { - lazy_fn_type->align_val = ir_resolve_const(ira, instruction->align_value->child, LazyOk); - if (lazy_fn_type->align_val == nullptr) + lazy_fn_type->align_inst = instruction->align_value->child; + if (ir_resolve_const(ira, lazy_fn_type->align_inst, LazyOk) == nullptr) return ira->codegen->invalid_instruction; } - lazy_fn_type->return_type = ir_resolve_const(ira, instruction->return_type->child, LazyOk); - if (lazy_fn_type->return_type == nullptr) + lazy_fn_type->return_type = instruction->return_type->child; + if (ir_resolve_const(ira, lazy_fn_type->return_type, LazyOk) == nullptr) return ira->codegen->invalid_instruction; - lazy_fn_type->return_type_src_node = instruction->return_type->source_node; return result; } @@ -23890,18 +23884,17 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct result->value.special = ConstValSpecialLazy; LazyValuePtrType *lazy_ptr_type = allocate(1); + lazy_ptr_type->ira = ira; result->value.data.x_lazy = &lazy_ptr_type->base; lazy_ptr_type->base.id = LazyValueIdPtrType; - lazy_ptr_type->base.exec = ira->new_irb.exec; - lazy_ptr_type->elem_type_val = ir_resolve_type_lazy(ira, instruction->child_type->child); - if (lazy_ptr_type->elem_type_val == nullptr) + lazy_ptr_type->elem_type = instruction->child_type->child; + if (ir_resolve_type_lazy(ira, lazy_ptr_type->elem_type) == nullptr) return ira->codegen->invalid_instruction; - lazy_ptr_type->elem_type_src_node = instruction->child_type->source_node; if (instruction->align_value != nullptr) { - lazy_ptr_type->align_val = ir_resolve_const(ira, instruction->align_value->child, LazyOk); - if (lazy_ptr_type->align_val == nullptr) + lazy_ptr_type->align_inst = instruction->align_value->child; + if (ir_resolve_const(ira, lazy_ptr_type->align_inst, LazyOk) == nullptr) return ira->codegen->invalid_instruction; } @@ -25446,9 +25439,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { zig_unreachable(); } -static ZigType *ir_resolve_lazy_fn_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, - LazyValueFnType *lazy_fn_type) -{ +static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, LazyValueFnType *lazy_fn_type) { Error err; AstNode *proto_node = lazy_fn_type->proto_node; @@ -25465,7 +25456,7 @@ static ZigType *ir_resolve_lazy_fn_type(CodeGen *codegen, IrExecutable *exec, As fn_type_id.param_count = fn_type_id.next_param_index; continue; } else if (fn_type_id.cc == CallingConventionUnspecified) { - return get_generic_fn_type(codegen, &fn_type_id); + return get_generic_fn_type(ira->codegen, &fn_type_id); } else { zig_unreachable(); } @@ -25475,34 +25466,33 @@ static ZigType *ir_resolve_lazy_fn_type(CodeGen *codegen, IrExecutable *exec, As if (lazy_fn_type->param_types[fn_type_id.next_param_index] == nullptr) { param_info->type = nullptr; - return get_generic_fn_type(codegen, &fn_type_id); + return get_generic_fn_type(ira->codegen, &fn_type_id); } else { - AstNode *param_src_node = lazy_fn_type->param_type_src_nodes[fn_type_id.next_param_index]; - ZigType *param_type = ir_resolve_const_type(codegen, exec, param_src_node, - lazy_fn_type->param_types[fn_type_id.next_param_index]); + IrInstruction *param_type_inst = lazy_fn_type->param_types[fn_type_id.next_param_index]; + ZigType *param_type = ir_resolve_type(ira, param_type_inst); if (type_is_invalid(param_type)) return nullptr; - switch (type_requires_comptime(codegen, param_type)) { + switch (type_requires_comptime(ira->codegen, param_type)) { case ReqCompTimeYes: if (!calling_convention_allows_zig_types(fn_type_id.cc)) { - exec_add_error_node(codegen, exec, param_src_node, + ir_add_error(ira, param_type_inst, buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); return nullptr; } param_info->type = param_type; fn_type_id.next_param_index += 1; - return get_generic_fn_type(codegen, &fn_type_id); + return get_generic_fn_type(ira->codegen, &fn_type_id); case ReqCompTimeInvalid: return nullptr; case ReqCompTimeNo: break; } if (!calling_convention_allows_zig_types(fn_type_id.cc)) { - if ((err = type_resolve(codegen, param_type, ResolveStatusZeroBitsKnown))) + if ((err = type_resolve(ira->codegen, param_type, ResolveStatusZeroBitsKnown))) return nullptr; if (!type_has_bits(param_type)) { - exec_add_error_node(codegen, exec, param_src_node, + ir_add_error(ira, param_type_inst, buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); return nullptr; @@ -25512,37 +25502,35 @@ static ZigType *ir_resolve_lazy_fn_type(CodeGen *codegen, IrExecutable *exec, As } } - if (lazy_fn_type->align_val != nullptr) { - if (!ir_resolve_const_align(codegen, exec, source_node, lazy_fn_type->align_val, &fn_type_id.alignment)) + if (lazy_fn_type->align_inst != nullptr) { + if (!ir_resolve_align(ira, lazy_fn_type->align_inst, &fn_type_id.alignment)) return nullptr; } - fn_type_id.return_type = ir_resolve_const_type(codegen, exec, lazy_fn_type->return_type_src_node, - lazy_fn_type->return_type); + fn_type_id.return_type = ir_resolve_type(ira, lazy_fn_type->return_type); if (type_is_invalid(fn_type_id.return_type)) return nullptr; if (fn_type_id.return_type->id == ZigTypeIdOpaque) { - exec_add_error_node(codegen, exec, lazy_fn_type->return_type_src_node, - buf_create_from_str("return type cannot be opaque")); + ir_add_error(ira, lazy_fn_type->return_type, buf_create_from_str("return type cannot be opaque")); return nullptr; } - return get_fn_type(codegen, &fn_type_id); + return get_fn_type(ira->codegen, &fn_type_id); } -static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) { +static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) { Error err; if (val->special != ConstValSpecialLazy) return ErrorNone; - IrExecutable *exec = val->data.x_lazy->exec; switch (val->data.x_lazy->id) { case LazyValueIdInvalid: zig_unreachable(); case LazyValueIdAlignOf: { LazyValueAlignOf *lazy_align_of = reinterpret_cast(val->data.x_lazy); + IrAnalyze *ira = lazy_align_of->ira; - if (lazy_align_of->target_type_val->special == ConstValSpecialStatic) { - switch (lazy_align_of->target_type_val->data.x_type->id) { + if (lazy_align_of->target_type->value.special == ConstValSpecialStatic) { + switch (lazy_align_of->target_type->value.data.x_type->id) { case ZigTypeIdInvalid: zig_unreachable(); case ZigTypeIdMetaType: @@ -25556,9 +25544,9 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx case ZigTypeIdArgTuple: case ZigTypeIdVoid: case ZigTypeIdOpaque: - exec_add_error_node(codegen, exec, lazy_align_of->target_type_src_node, + ir_add_error(ira, lazy_align_of->target_type, buf_sprintf("no align available for type '%s'", - buf_ptr(&lazy_align_of->target_type_val->data.x_type->name))); + buf_ptr(&lazy_align_of->target_type->value.data.x_type->name))); return ErrorSemanticAnalyzeFail; case ZigTypeIdBool: case ZigTypeIdInt: @@ -25580,8 +25568,11 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx } uint32_t align_in_bytes; - if ((err = type_val_resolve_abi_align(codegen, lazy_align_of->target_type_val, &align_in_bytes))) + if ((err = type_val_resolve_abi_align(ira->codegen, &lazy_align_of->target_type->value, + &align_in_bytes))) + { return err; + } val->special = ConstValSpecialStatic; assert(val->type->id == ZigTypeIdComptimeInt); @@ -25590,69 +25581,72 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx } case LazyValueIdSliceType: { LazyValueSliceType *lazy_slice_type = reinterpret_cast(val->data.x_lazy); + IrAnalyze *ira = lazy_slice_type->ira; + uint32_t align_bytes = 0; - if (lazy_slice_type->align_val != nullptr) { - if (!ir_resolve_const_align(codegen, exec, source_node, lazy_slice_type->align_val, &align_bytes)) + if (lazy_slice_type->align_inst != nullptr) { + if (!ir_resolve_align(ira, lazy_slice_type->align_inst, &align_bytes)) return ErrorSemanticAnalyzeFail; } ResolveStatus needed_status = (align_bytes == 0) ? ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; - if ((err = type_resolve(codegen, lazy_slice_type->elem_type, needed_status))) + if ((err = type_resolve(ira->codegen, lazy_slice_type->elem_type, needed_status))) return err; - ZigType *slice_ptr_type = get_pointer_to_type_extra(codegen, lazy_slice_type->elem_type, + ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, lazy_slice_type->elem_type, lazy_slice_type->is_const, lazy_slice_type->is_volatile, PtrLenUnknown, align_bytes, 0, 0, lazy_slice_type->is_allowzero); val->special = ConstValSpecialStatic; assert(val->type->id == ZigTypeIdMetaType); - val->data.x_type = get_slice_type(codegen, slice_ptr_type); + val->data.x_type = get_slice_type(ira->codegen, slice_ptr_type); return ErrorNone; } case LazyValueIdPtrType: { LazyValuePtrType *lazy_ptr_type = reinterpret_cast(val->data.x_lazy); + IrAnalyze *ira = lazy_ptr_type->ira; + uint32_t align_bytes = 0; - if (lazy_ptr_type->align_val != nullptr) { - if (!ir_resolve_const_align(codegen, exec, source_node, lazy_ptr_type->align_val, &align_bytes)) + if (lazy_ptr_type->align_inst != nullptr) { + if (!ir_resolve_align(ira, lazy_ptr_type->align_inst, &align_bytes)) return ErrorSemanticAnalyzeFail; } - ZigType *elem_type = ir_resolve_const_type(codegen, exec, lazy_ptr_type->elem_type_src_node, - lazy_ptr_type->elem_type_val); + ZigType *elem_type = ir_resolve_type(ira, lazy_ptr_type->elem_type); if (type_is_invalid(elem_type)) return ErrorSemanticAnalyzeFail; if (elem_type->id == ZigTypeIdUnreachable) { - exec_add_error_node(codegen, exec, lazy_ptr_type->elem_type_src_node, + ir_add_error(ira, lazy_ptr_type->elem_type, buf_create_from_str("pointer to noreturn not allowed")); return ErrorSemanticAnalyzeFail; } else if (elem_type->id == ZigTypeIdOpaque && lazy_ptr_type->ptr_len == PtrLenUnknown) { - exec_add_error_node(codegen, exec, lazy_ptr_type->elem_type_src_node, + ir_add_error(ira, lazy_ptr_type->elem_type, buf_create_from_str("unknown-length pointer to opaque")); return ErrorSemanticAnalyzeFail; } else if (lazy_ptr_type->ptr_len == PtrLenC) { - if (!type_allowed_in_extern(codegen, elem_type)) { - exec_add_error_node(codegen, exec, lazy_ptr_type->elem_type_src_node, + if (!type_allowed_in_extern(ira->codegen, elem_type)) { + ir_add_error(ira, lazy_ptr_type->elem_type, buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", buf_ptr(&elem_type->name))); return ErrorSemanticAnalyzeFail; } else if (elem_type->id == ZigTypeIdOpaque) { - exec_add_error_node(codegen, exec, lazy_ptr_type->elem_type_src_node, + ir_add_error(ira, lazy_ptr_type->elem_type, buf_sprintf("C pointers cannot point opaque types")); return ErrorSemanticAnalyzeFail; } else if (lazy_ptr_type->is_allowzero) { - exec_add_error_node(codegen, exec, lazy_ptr_type->elem_type_src_node, + ir_add_error(ira, lazy_ptr_type->elem_type, buf_sprintf("C pointers always allow address zero")); return ErrorSemanticAnalyzeFail; } } if (align_bytes != 0) { - if ((err = type_resolve(codegen, elem_type, ResolveStatusAlignmentKnown))) + if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) return err; if (!type_has_bits(elem_type)) align_bytes = 0; } bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC; assert(val->type->id == ZigTypeIdMetaType); - val->data.x_type = get_pointer_to_type_extra(codegen, elem_type, + val->data.x_type = get_pointer_to_type_extra(ira->codegen, elem_type, lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes, lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes, allow_zero); @@ -25661,29 +25655,29 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx } case LazyValueIdOptType: { LazyValueOptType *lazy_opt_type = reinterpret_cast(val->data.x_lazy); + IrAnalyze *ira = lazy_opt_type->ira; - ZigType *payload_type = ir_resolve_const_type(codegen, exec, lazy_opt_type->payload_type_src_node, - lazy_opt_type->payload_type_val); + ZigType *payload_type = ir_resolve_type(ira, lazy_opt_type->payload_type); if (type_is_invalid(payload_type)) return ErrorSemanticAnalyzeFail; if (payload_type->id == ZigTypeIdOpaque || payload_type->id == ZigTypeIdUnreachable) { - exec_add_error_node(codegen, exec, lazy_opt_type->payload_type_src_node, + ir_add_error(ira, lazy_opt_type->payload_type, buf_sprintf("type '%s' cannot be optional", buf_ptr(&payload_type->name))); return ErrorSemanticAnalyzeFail; } - if ((err = type_resolve(codegen, payload_type, ResolveStatusSizeKnown))) + if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) return err; assert(val->type->id == ZigTypeIdMetaType); - val->data.x_type = get_optional_type(codegen, payload_type); + val->data.x_type = get_optional_type(ira->codegen, payload_type); val->special = ConstValSpecialStatic; return ErrorNone; } case LazyValueIdFnType: { - ZigType *fn_type = ir_resolve_lazy_fn_type(codegen, exec, source_node, - reinterpret_cast(val->data.x_lazy)); + LazyValueFnType *lazy_fn_type = reinterpret_cast(val->data.x_lazy); + ZigType *fn_type = ir_resolve_lazy_fn_type(lazy_fn_type->ira, source_node, lazy_fn_type); if (fn_type == nullptr) return ErrorSemanticAnalyzeFail; val->special = ConstValSpecialStatic; @@ -25697,7 +25691,7 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) { Error err; - if ((err = ir_resolve_lazy_raw(codegen, source_node, val))) { + if ((err = ir_resolve_lazy_raw(source_node, val))) { if (codegen->trace_err != nullptr && !source_node->already_traced_this_node) { source_node->already_traced_this_node = true; codegen->trace_err = add_error_note(codegen, codegen->trace_err, source_node, diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 59687a6cc3..bc2d43706f 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,33 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + "alignment of enum field specified", + \\const Number = enum { + \\ a, + \\ b align(i32), + \\}; + \\export fn entry1() void { + \\ var x: Number = undefined; + \\} + , + "tmp.zig:3:13: error: structs and unions, not enums, support field alignment", + "tmp.zig:1:16: note: consider 'union(enum)' here", + ); + + cases.add( + "bad alignment type", + \\export fn entry1() void { + \\ var x: []align(true) i32 = undefined; + \\} + \\export fn entry2() void { + \\ var x: *align(f64(12.34)) i32 = undefined; + \\} + , + "tmp.zig:2:20: error: expected type 'u29', found 'bool'", + "tmp.zig:5:22: error: fractional component prevents float value 12.340000 from being casted to type 'u29'", + ); + cases.addCase(x: { var tc = cases.create("variable in inline assembly template cannot be found", \\export fn entry() void { -- cgit v1.2.3