From fcbb7426faac5e693ef195defe2d8d2a2eddadb1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 31 May 2018 10:56:59 -0400 Subject: use * for pointer type instead of & See #770 To help automatically translate code, see the zig-fmt-pointer-reform-2 branch. This will convert all & into *. Due to the syntax ambiguity (which is why we are making this change), even address-of & will turn into *, so you'll have to manually fix thes instances. You will be guaranteed to get compile errors for them - expected 'type', found 'foo' --- src/ir.cpp | 89 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 46 insertions(+), 43 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 6e944a8976..b1fac9f485 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -41,10 +41,6 @@ struct IrAnalyze { static const LVal LVAL_NONE = { false, false, false }; static const LVal LVAL_PTR = { true, false, false }; -static LVal make_lval_addr(bool is_const, bool is_volatile) { - return { true, is_const, is_volatile }; -} - enum ConstCastResultId { ConstCastResultIdOk, ConstCastResultIdErrSet, @@ -629,8 +625,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetEvalBranchQuo return IrInstructionIdSetEvalBranchQuota; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeOf *) { - return IrInstructionIdPtrTypeOf; +static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrType *) { + return IrInstructionIdPtrType; } static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { @@ -1196,11 +1192,11 @@ static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instru return new_instruction; } -static IrInstruction *ir_build_ptr_type_of(IrBuilder *irb, Scope *scope, AstNode *source_node, +static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value, uint32_t bit_offset_start, uint32_t bit_offset_end) { - IrInstructionPtrTypeOf *ptr_type_of_instruction = ir_build_instruction(irb, scope, source_node); + IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction(irb, scope, source_node); ptr_type_of_instruction->align_value = align_value; ptr_type_of_instruction->child_type = child_type; ptr_type_of_instruction->is_const = is_const; @@ -4609,14 +4605,8 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode } static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { - AstNode *expr_node; - if (node->type == NodeTypePrefixOpExpr) { - expr_node = node->data.prefix_op_expr.primary_expr; - } else if (node->type == NodeTypePtrDeref) { - expr_node = node->data.ptr_deref_expr.target; - } else { - zig_unreachable(); - } + assert(node->type == NodeTypePrefixOpExpr); + AstNode *expr_node = node->data.prefix_op_expr.primary_expr; IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); if (value == irb->codegen->invalid_instruction) @@ -4640,16 +4630,12 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction * return ir_build_ref(irb, scope, value->source_node, value, lval.is_const, lval.is_volatile); } -static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *node) { - assert(node->type == NodeTypeAddrOfExpr); - bool is_const = node->data.addr_of_expr.is_const; - bool is_volatile = node->data.addr_of_expr.is_volatile; - AstNode *expr_node = node->data.addr_of_expr.op_expr; - AstNode *align_expr = node->data.addr_of_expr.align_expr; - - if (align_expr == nullptr && !is_const && !is_volatile) { - return ir_gen_node_extra(irb, expr_node, scope, make_lval_addr(is_const, is_volatile)); - } +static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) { + assert(node->type == NodeTypePointerType); + bool is_const = node->data.pointer_type.is_const; + bool is_volatile = node->data.pointer_type.is_volatile; + AstNode *expr_node = node->data.pointer_type.op_expr; + AstNode *align_expr = node->data.pointer_type.align_expr; IrInstruction *align_value; if (align_expr != nullptr) { @@ -4665,27 +4651,27 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n return child_type; uint32_t bit_offset_start = 0; - if (node->data.addr_of_expr.bit_offset_start != nullptr) { - if (!bigint_fits_in_bits(node->data.addr_of_expr.bit_offset_start, 32, false)) { + if (node->data.pointer_type.bit_offset_start != nullptr) { + if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_start, 32, false)) { Buf *val_buf = buf_alloc(); - bigint_append_buf(val_buf, node->data.addr_of_expr.bit_offset_start, 10); + bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10); exec_add_error_node(irb->codegen, irb->exec, node, buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); return irb->codegen->invalid_instruction; } - bit_offset_start = bigint_as_unsigned(node->data.addr_of_expr.bit_offset_start); + bit_offset_start = bigint_as_unsigned(node->data.pointer_type.bit_offset_start); } uint32_t bit_offset_end = 0; - if (node->data.addr_of_expr.bit_offset_end != nullptr) { - if (!bigint_fits_in_bits(node->data.addr_of_expr.bit_offset_end, 32, false)) { + if (node->data.pointer_type.bit_offset_end != nullptr) { + if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_end, 32, false)) { Buf *val_buf = buf_alloc(); - bigint_append_buf(val_buf, node->data.addr_of_expr.bit_offset_end, 10); + bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_end, 10); exec_add_error_node(irb->codegen, irb->exec, node, buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); return irb->codegen->invalid_instruction; } - bit_offset_end = bigint_as_unsigned(node->data.addr_of_expr.bit_offset_end); + bit_offset_end = bigint_as_unsigned(node->data.pointer_type.bit_offset_end); } if ((bit_offset_start != 0 || bit_offset_end != 0) && bit_offset_start >= bit_offset_end) { @@ -4694,7 +4680,7 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n return irb->codegen->invalid_instruction; } - return ir_build_ptr_type_of(irb, scope, node, child_type, is_const, is_volatile, + return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, align_value, bit_offset_start, bit_offset_end); } @@ -4761,6 +4747,10 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpMaybe), lval); case PrefixOpUnwrapMaybe: return ir_gen_maybe_assert_ok(irb, scope, node, lval); + case PrefixOpAddrOf: { + AstNode *expr_node = node->data.prefix_op_expr.primary_expr; + return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR), lval); + } } zig_unreachable(); } @@ -6568,8 +6558,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval); case NodeTypePrefixOpExpr: return ir_gen_prefix_op_expr(irb, scope, node, lval); - case NodeTypeAddrOfExpr: - return ir_lval_wrap(irb, scope, ir_gen_address_of(irb, scope, node), lval); case NodeTypeContainerInitExpr: return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval); case NodeTypeVariableDeclaration: @@ -6592,14 +6580,23 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop return ir_build_load_ptr(irb, scope, node, ptr_instruction); } - case NodeTypePtrDeref: - return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpDereference, lval); + case NodeTypePtrDeref: { + assert(node->type == NodeTypePtrDeref); + AstNode *expr_node = node->data.ptr_deref_expr.target; + IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); + if (value == irb->codegen->invalid_instruction) + return value; + + return ir_build_un_op(irb, scope, node, IrUnOpDereference, value); + } case NodeTypeThisLiteral: return ir_lval_wrap(irb, scope, ir_gen_this_literal(irb, scope, node), lval); case NodeTypeBoolLiteral: return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval); case NodeTypeArrayType: return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval); + case NodeTypePointerType: + return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval); case NodeTypePromiseType: return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval); case NodeTypeStringLiteral: @@ -8961,6 +8958,7 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio ConstExprValue *pointee, TypeTableEntry *pointee_type, ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align) { + // TODO remove this special case for types if (pointee_type->id == TypeTableEntryIdMetaType) { TypeTableEntry *type_entry = pointee->data.x_type; if (type_entry->id == TypeTableEntryIdUnreachable) { @@ -18778,11 +18776,16 @@ static TypeTableEntry *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstr return usize; } -static TypeTableEntry *ir_analyze_instruction_ptr_type_of(IrAnalyze *ira, IrInstructionPtrTypeOf *instruction) { +static TypeTableEntry *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) { TypeTableEntry *child_type = ir_resolve_type(ira, instruction->child_type->other); if (type_is_invalid(child_type)) return ira->codegen->builtin_types.entry_invalid; + if (child_type->id == TypeTableEntryIdUnreachable) { + ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed")); + return ira->codegen->builtin_types.entry_invalid; + } + uint32_t align_bytes; if (instruction->align_value != nullptr) { if (!ir_resolve_align(ira, instruction->align_value->other, &align_bytes)) @@ -19606,8 +19609,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); case IrInstructionIdSetEvalBranchQuota: return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstructionSetEvalBranchQuota *)instruction); - case IrInstructionIdPtrTypeOf: - return ir_analyze_instruction_ptr_type_of(ira, (IrInstructionPtrTypeOf *)instruction); + case IrInstructionIdPtrType: + return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); case IrInstructionIdAlignCast: return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); case IrInstructionIdOpaqueType: @@ -19783,7 +19786,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdCheckStatementIsVoid: case IrInstructionIdPanic: case IrInstructionIdSetEvalBranchQuota: - case IrInstructionIdPtrTypeOf: + case IrInstructionIdPtrType: case IrInstructionIdSetAlignStack: case IrInstructionIdExport: case IrInstructionIdCancel: -- cgit v1.2.3 From 2f614c42fe4f28e5adda8163bd50d6d3507d6353 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 31 May 2018 18:14:35 -0400 Subject: ir: rip out special logic for using addr-of instruction for types See #588 --- src/all_types.hpp | 2 - src/ir.cpp | 155 ++++++++++++++---------------------------------- std/zig/parser_test.zig | 4 +- 3 files changed, 46 insertions(+), 115 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/all_types.hpp b/src/all_types.hpp index b9199c2757..d5906cae95 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2275,8 +2275,6 @@ struct IrInstructionVarPtr { IrInstruction base; VariableTableEntry *var; - bool is_const; - bool is_volatile; }; struct IrInstructionCall { diff --git a/src/ir.cpp b/src/ir.cpp index b1fac9f485..984cfd78d3 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -104,8 +104,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg); static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, IrInstruction *source_instr, IrInstruction *container_ptr, TypeTableEntry *container_type); -static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, - VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr); +static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, VariableTableEntry *var); static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval); @@ -1000,13 +999,9 @@ static IrInstruction *ir_build_bin_op_from(IrBuilder *irb, IrInstruction *old_in return new_instruction; } -static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, - VariableTableEntry *var, bool is_const, bool is_volatile) -{ +static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, VariableTableEntry *var) { IrInstructionVarPtr *instruction = ir_build_instruction(irb, scope, source_node); instruction->var = var; - instruction->is_const = is_const; - instruction->is_volatile = is_volatile; ir_ref_var(var); @@ -3515,8 +3510,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, VariableTableEntry *var = find_variable(irb->codegen, scope, variable_name); if (var) { - IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, node, var, - !lval.is_ptr || lval.is_const, lval.is_ptr && lval.is_volatile); + IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, node, var); if (lval.is_ptr) return var_ptr; else @@ -5140,7 +5134,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node); ir_build_var_decl(irb, child_scope, elem_node, elem_var, elem_var_type, nullptr, undefined_value); - IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var, false, false); + IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var); AstNode *index_var_source_node; VariableTableEntry *index_var; @@ -5158,7 +5152,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0); IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1); ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, nullptr, zero); - IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var, false, false); + IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var); IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond"); @@ -6387,7 +6381,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast IrInstruction *promise_result_type = ir_build_promise_result_type(irb, parent_scope, node, target_promise_type); ir_build_await_bookkeeping(irb, parent_scope, node, promise_result_type); ir_build_var_decl(irb, parent_scope, node, result_var, promise_result_type, nullptr, undefined_value); - IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, parent_scope, node, result_var, false, false); + IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, parent_scope, node, result_var); ir_build_store_ptr(irb, parent_scope, node, result_ptr_field_ptr, my_result_var_ptr); IrInstruction *save_token = ir_build_coro_save(irb, parent_scope, node, irb->exec->coro_handle); IrInstruction *promise_type_val = ir_build_const_type(irb, parent_scope, node, @@ -6708,15 +6702,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type); // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa ir_build_var_decl(irb, coro_scope, node, promise_var, coro_frame_type_value, nullptr, undef); - coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var, false, false); + coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var); VariableTableEntry *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node, get_maybe_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); ir_build_var_decl(irb, coro_scope, node, await_handle_var, await_handle_type_val, nullptr, null_value); - irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, - await_handle_var, false, false); + irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var); u8_ptr_type = ir_build_const_type(irb, coro_scope, node, get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false)); @@ -6856,7 +6849,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); IrInstruction *coro_mem_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_mem_ptr_maybe); IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false); - IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var, true, false); + IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var); IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr); IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false); size_t arg_count = 2; @@ -8958,35 +8951,15 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio ConstExprValue *pointee, TypeTableEntry *pointee_type, ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align) { - // TODO remove this special case for types - if (pointee_type->id == TypeTableEntryIdMetaType) { - TypeTableEntry *type_entry = pointee->data.x_type; - if (type_entry->id == TypeTableEntryIdUnreachable) { - ir_add_error(ira, instruction, buf_sprintf("pointer to noreturn not allowed")); - return ira->codegen->invalid_instruction; - } - - IrInstruction *const_instr = ir_get_const(ira, instruction); - ConstExprValue *const_val = &const_instr->value; - const_val->type = pointee_type; - type_ensure_zero_bits_known(ira->codegen, type_entry); - if (type_is_invalid(type_entry)) { - return ira->codegen->invalid_instruction; - } - const_val->data.x_type = get_pointer_to_type_extra(ira->codegen, type_entry, - ptr_is_const, ptr_is_volatile, get_abi_alignment(ira->codegen, type_entry), 0, 0); - return const_instr; - } else { - TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type, - ptr_is_const, ptr_is_volatile, ptr_align, 0, 0); - IrInstruction *const_instr = ir_get_const(ira, instruction); - ConstExprValue *const_val = &const_instr->value; - const_val->type = ptr_type; - const_val->data.x_ptr.special = ConstPtrSpecialRef; - const_val->data.x_ptr.mut = ptr_mut; - const_val->data.x_ptr.data.ref.pointee = pointee; - return const_instr; - } + TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type, + ptr_is_const, ptr_is_volatile, ptr_align, 0, 0); + IrInstruction *const_instr = ir_get_const(ira, instruction); + ConstExprValue *const_val = &const_instr->value; + const_val->type = ptr_type; + const_val->data.x_ptr.special = ConstPtrSpecialRef; + const_val->data.x_ptr.mut = ptr_mut; + const_val->data.x_ptr.data.ref.pointee = pointee; + return const_instr; } static TypeTableEntry *ir_analyze_const_ptr(IrAnalyze *ira, IrInstruction *instruction, @@ -9314,9 +9287,8 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi ConstExprValue *val = ir_resolve_const(ira, value, UndefOk); if (!val) return ira->codegen->invalid_instruction; - bool final_is_const = (value->value.type->id == TypeTableEntryIdMetaType) ? is_const : true; return ir_get_const_ptr(ira, source_instruction, val, value->value.type, - ConstPtrMutComptimeConst, final_is_const, is_volatile, + ConstPtrMutComptimeConst, is_const, is_volatile, get_abi_alignment(ira->codegen, value->value.type)); } @@ -10245,21 +10217,6 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc source_instruction->source_node, ptr); load_ptr_instruction->value.type = child_type; return load_ptr_instruction; - } else if (type_entry->id == TypeTableEntryIdMetaType) { - ConstExprValue *ptr_val = ir_resolve_const(ira, ptr, UndefBad); - if (!ptr_val) - return ira->codegen->invalid_instruction; - - TypeTableEntry *ptr_type = ptr_val->data.x_type; - if (ptr_type->id == TypeTableEntryIdPointer) { - TypeTableEntry *child_type = ptr_type->data.pointer.child_type; - return ir_create_const_type(&ira->new_irb, source_instruction->scope, - source_instruction->source_node, child_type); - } else { - ir_add_error(ira, source_instruction, - buf_sprintf("attempt to dereference non pointer type '%s'", buf_ptr(&ptr_type->name))); - return ira->codegen->invalid_instruction; - } } else { ir_add_error_node(ira, source_instruction->source_node, buf_sprintf("attempt to dereference non pointer type '%s'", @@ -11966,7 +11923,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i { VariableTableEntry *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; assert(coro_allocator_var != nullptr); - IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var, true, false); + IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var); IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst); assert(result->value.type != nullptr); return result; @@ -12147,7 +12104,7 @@ static VariableTableEntry *get_fn_var_by_index(FnTableEntry *fn_entry, size_t in } static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, - VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr) + VariableTableEntry *var) { if (var->mem_slot_index != SIZE_MAX && var->owner_exec->analysis == nullptr) { assert(ira->codegen->errors.length != 0); @@ -12173,8 +12130,8 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, } } - bool is_const = (var->value->type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const; - bool is_volatile = (var->value->type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false; + bool is_const = var->src_is_const; + bool is_volatile = false; if (mem_slot != nullptr) { switch (mem_slot->special) { case ConstValSpecialRuntime: @@ -12200,7 +12157,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, no_mem_slot: IrInstruction *var_ptr_instruction = ir_build_var_ptr(&ira->new_irb, - instruction->scope, instruction->source_node, var, is_const, is_volatile); + instruction->scope, instruction->source_node, var); var_ptr_instruction->value.type = get_pointer_to_type_extra(ira->codegen, var->value->type, var->src_is_const, is_volatile, var->align_bytes, 0, 0); type_ensure_zero_bits_known(ira->codegen, var->value->type); @@ -12486,7 +12443,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557")); return ira->codegen->builtin_types.entry_invalid; } - IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, arg, arg_var, true, false); + IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, arg, arg_var); if (type_is_invalid(arg_var_ptr_inst->value.type)) return ira->codegen->builtin_types.entry_invalid; @@ -13120,17 +13077,16 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP } static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction, - VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr) + VariableTableEntry *var) { - IrInstruction *result = ir_get_var_ptr(ira, instruction, var, is_const_ptr, is_volatile_ptr); + IrInstruction *result = ir_get_var_ptr(ira, instruction, var); ir_link_new_instruction(result, instruction); return result->value.type; } static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) { VariableTableEntry *var = var_ptr_instruction->var; - return ir_analyze_var_ptr(ira, &var_ptr_instruction->base, var, var_ptr_instruction->is_const, - var_ptr_instruction->is_volatile); + return ir_analyze_var_ptr(ira, &var_ptr_instruction->base, var); } static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, uint32_t new_align) { @@ -13152,11 +13108,6 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc return ira->codegen->builtin_types.entry_invalid; TypeTableEntry *ptr_type = array_ptr->value.type; - if (ptr_type->id == TypeTableEntryIdMetaType) { - ir_add_error(ira, &elem_ptr_instruction->base, - buf_sprintf("array access of non-array type '%s'", buf_ptr(&ptr_type->name))); - return ira->codegen->builtin_types.entry_invalid; - } assert(ptr_type->id == TypeTableEntryIdPointer); TypeTableEntry *array_type = ptr_type->data.pointer.child_type; @@ -13218,8 +13169,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc bool is_const = true; bool is_volatile = false; if (var) { - return ir_analyze_var_ptr(ira, &elem_ptr_instruction->base, var, - is_const, is_volatile); + return ir_analyze_var_ptr(ira, &elem_ptr_instruction->base, var); } else { return ir_analyze_const_ptr(ira, &elem_ptr_instruction->base, &ira->codegen->const_void_val, ira->codegen->builtin_types.entry_void, ConstPtrMutComptimeConst, is_const, is_volatile); @@ -13603,7 +13553,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node); } - return ir_analyze_var_ptr(ira, source_instruction, var, false, false); + return ir_analyze_var_ptr(ira, source_instruction, var); } case TldIdFn: { @@ -13652,14 +13602,8 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru if (type_is_invalid(container_ptr->value.type)) return ira->codegen->builtin_types.entry_invalid; - TypeTableEntry *container_type; - if (container_ptr->value.type->id == TypeTableEntryIdPointer) { - container_type = container_ptr->value.type->data.pointer.child_type; - } else if (container_ptr->value.type->id == TypeTableEntryIdMetaType) { - container_type = container_ptr->value.type; - } else { - zig_unreachable(); - } + TypeTableEntry *container_type = container_ptr->value.type->data.pointer.child_type; + assert(container_ptr->value.type->id == TypeTableEntryIdPointer); Buf *field_name = field_ptr_instruction->field_name_buffer; if (!field_name) { @@ -13732,17 +13676,9 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru if (!container_ptr_val) return ira->codegen->builtin_types.entry_invalid; - TypeTableEntry *child_type; - if (container_ptr->value.type->id == TypeTableEntryIdMetaType) { - TypeTableEntry *ptr_type = container_ptr_val->data.x_type; - assert(ptr_type->id == TypeTableEntryIdPointer); - child_type = ptr_type->data.pointer.child_type; - } else if (container_ptr->value.type->id == TypeTableEntryIdPointer) { - ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val); - child_type = child_val->data.x_type; - } else { - zig_unreachable(); - } + assert(container_ptr->value.type->id == TypeTableEntryIdPointer); + ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val); + TypeTableEntry *child_type = child_val->data.x_type; if (type_is_invalid(child_type)) { return ira->codegen->builtin_types.entry_invalid; @@ -17337,8 +17273,11 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio if (array_type->data.array.len == 0 && byte_alignment == 0) { byte_alignment = get_abi_alignment(ira->codegen, array_type->data.array.child_type); } + bool is_comptime_const = ptr_ptr->value.special == ConstValSpecialStatic && + ptr_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst; TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type, - ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, + ptr_type->data.pointer.is_const || is_comptime_const, + ptr_type->data.pointer.is_volatile, byte_alignment, 0, 0); return_type = get_slice_type(ira->codegen, slice_ptr_type); } else if (array_type->id == TypeTableEntryIdPointer) { @@ -17525,6 +17464,10 @@ static TypeTableEntry *ir_analyze_instruction_member_count(IrAnalyze *ira, IrIns return ira->codegen->builtin_types.entry_invalid; TypeTableEntry *container_type = ir_resolve_type(ira, container); + ensure_complete_type(ira->codegen, container_type); + if (type_is_invalid(container_type)) + return ira->codegen->builtin_types.entry_invalid; + uint64_t result; if (type_is_invalid(container_type)) { return ira->codegen->builtin_types.entry_invalid; @@ -17912,15 +17855,6 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, return ira->codegen->builtin_types.entry_invalid; TypeTableEntry *ptr_type = value->value.type; - // Because we don't have Pointer Reform yet, we can't have a pointer to a 'type'. - // Therefor, we have to check for type 'type' here, so we can output a correct error - // without asserting the assert below. - if (ptr_type->id == TypeTableEntryIdMetaType) { - ir_add_error(ira, value, - buf_sprintf("expected error union type, found '%s'", buf_ptr(&ptr_type->name))); - return ira->codegen->builtin_types.entry_invalid; - } - // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. assert(ptr_type->id == TypeTableEntryIdPointer); @@ -18697,8 +18631,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira, TldVar *tld_var = (TldVar *)tld; VariableTableEntry *var = tld_var->var; - IrInstruction *var_ptr = ir_get_var_ptr(ira, &instruction->base, var, - !lval.is_ptr || lval.is_const, lval.is_ptr && lval.is_volatile); + IrInstruction *var_ptr = ir_get_var_ptr(ira, &instruction->base, var); if (type_is_invalid(var_ptr->value.type)) return ira->codegen->builtin_types.entry_invalid; diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig index 8507470bcc..d90cc9ec22 100644 --- a/std/zig/parser_test.zig +++ b/std/zig/parser_test.zig @@ -1298,8 +1298,8 @@ test "zig fmt: struct declaration" { \\ f1: u8, \\ pub f3: u8, \\ - \\ fn method(self: &Self) Self { - \\ return *self; + \\ fn method(self: *Self) Self { + \\ return self.*; \\ } \\ \\ f2: u8, -- cgit v1.2.3 From 019217d7a23bee69bd5ceb38aeeb5f689d5c2a9c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 1 Jun 2018 00:07:40 -0400 Subject: fix regressions --- src/ir.cpp | 105 ++++++++++++++++++++++++++++++++++++++---------- test/compile_errors.zig | 2 +- test/gen_h.zig | 4 +- test/runtime_safety.zig | 46 ++++++++++----------- 4 files changed, 110 insertions(+), 47 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 984cfd78d3..d996b4a2be 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -9433,6 +9433,8 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); assert(union_field != nullptr); type_ensure_zero_bits_known(ira->codegen, union_field->type_entry); + if (type_is_invalid(union_field->type_entry)) + return ira->codegen->invalid_instruction; if (!union_field->type_entry->zero_bits) { AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at( union_field->enum_field->decl_index); @@ -10015,6 +10017,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst if (actual_type->id == TypeTableEntryIdNumLitFloat || actual_type->id == TypeTableEntryIdNumLitInt) { + ensure_complete_type(ira->codegen, wanted_type); + if (type_is_invalid(wanted_type)) + return ira->codegen->invalid_instruction; if (wanted_type->id == TypeTableEntryIdEnum) { IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.enumeration.tag_int_type, value); if (type_is_invalid(cast1->value.type)) @@ -12766,6 +12771,10 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op TypeTableEntry *type_entry = ir_resolve_type(ira, value); if (type_is_invalid(type_entry)) return ira->codegen->builtin_types.entry_invalid; + ensure_complete_type(ira->codegen, type_entry); + if (type_is_invalid(type_entry)) + return ira->codegen->builtin_types.entry_invalid; + switch (type_entry->id) { case TypeTableEntryIdInvalid: zig_unreachable(); @@ -13187,6 +13196,9 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc bool safety_check_on = elem_ptr_instruction->safety_check_on; ensure_complete_type(ira->codegen, return_type->data.pointer.child_type); + if (type_is_invalid(return_type->data.pointer.child_type)) + return ira->codegen->builtin_types.entry_invalid; + uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); uint64_t ptr_align = return_type->data.pointer.alignment; @@ -13696,7 +13708,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru } if (child_type->id == TypeTableEntryIdEnum) { ensure_complete_type(ira->codegen, child_type); - if (child_type->data.enumeration.is_invalid) + if (type_is_invalid(child_type)) return ira->codegen->builtin_types.entry_invalid; TypeEnumField *field = find_enum_type_field(child_type, field_name); @@ -14569,27 +14581,27 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira, return ira->codegen->builtin_types.entry_invalid; TypeTableEntry *ptr_type = value->value.type; - if (ptr_type->id == TypeTableEntryIdMetaType) { + assert(ptr_type->id == TypeTableEntryIdPointer); + + TypeTableEntry *type_entry = ptr_type->data.pointer.child_type; + if (type_is_invalid(type_entry)) { + return ira->codegen->builtin_types.entry_invalid; + } else if (type_entry->id == TypeTableEntryIdMetaType) { // surprise! actually this is just ??T not an unwrap maybe instruction - TypeTableEntry *ptr_type_ptr = ir_resolve_type(ira, value); - assert(ptr_type_ptr->id == TypeTableEntryIdPointer); - TypeTableEntry *child_type = ptr_type_ptr->data.pointer.child_type; + ConstExprValue *ptr_val = const_ptr_pointee(ira->codegen, &value->value); + assert(ptr_val->type->id == TypeTableEntryIdMetaType); + TypeTableEntry *child_type = ptr_val->data.x_type; + type_ensure_zero_bits_known(ira->codegen, child_type); TypeTableEntry *layer1 = get_maybe_type(ira->codegen, child_type); TypeTableEntry *layer2 = get_maybe_type(ira->codegen, layer1); - TypeTableEntry *result_type = get_pointer_to_type(ira->codegen, layer2, true); IrInstruction *const_instr = ir_build_const_type(&ira->new_irb, unwrap_maybe_instruction->base.scope, - unwrap_maybe_instruction->base.source_node, result_type); - ir_link_new_instruction(const_instr, &unwrap_maybe_instruction->base); - return const_instr->value.type; - } - - assert(ptr_type->id == TypeTableEntryIdPointer); - - TypeTableEntry *type_entry = ptr_type->data.pointer.child_type; - if (type_is_invalid(type_entry)) { - return ira->codegen->builtin_types.entry_invalid; + unwrap_maybe_instruction->base.source_node, layer2); + IrInstruction *result_instr = ir_get_ref(ira, &unwrap_maybe_instruction->base, const_instr, + ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile); + ir_link_new_instruction(result_instr, &unwrap_maybe_instruction->base); + return result_instr->value.type; } else if (type_entry->id != TypeTableEntryIdMaybe) { ir_add_error_node(ira, unwrap_maybe_instruction->value->source_node, buf_sprintf("expected nullable type, found '%s'", buf_ptr(&type_entry->name))); @@ -15115,6 +15127,8 @@ static TypeTableEntry *ir_analyze_container_init_fields_union(IrAnalyze *ira, Ir assert(container_type->id == TypeTableEntryIdUnion); ensure_complete_type(ira->codegen, container_type); + if (type_is_invalid(container_type)) + return ira->codegen->builtin_types.entry_invalid; if (instr_field_count != 1) { ir_add_error(ira, instruction, @@ -15182,6 +15196,8 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru } ensure_complete_type(ira->codegen, container_type); + if (type_is_invalid(container_type)) + return ira->codegen->builtin_types.entry_invalid; size_t actual_field_count = container_type->data.structure.src_field_count; @@ -15687,6 +15703,8 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira, return ira->codegen->builtin_types.entry_invalid; ensure_complete_type(ira->codegen, container_type); + if (type_is_invalid(container_type)) + return ira->codegen->builtin_types.entry_invalid; IrInstruction *field_name_value = instruction->field_name->other; Buf *field_name = ir_resolve_str(ira, field_name_value); @@ -15740,6 +15758,9 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na assert(type_info_var->type->id == TypeTableEntryIdMetaType); ensure_complete_type(ira->codegen, type_info_var->data.x_type); + if (type_is_invalid(type_info_var->data.x_type)) + return ira->codegen->builtin_types.entry_invalid; + type_info_type = type_info_var->data.x_type; assert(type_info_type->id == TypeTableEntryIdUnion); } @@ -15765,26 +15786,37 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na VariableTableEntry *var = tld->var; ensure_complete_type(ira->codegen, var->value->type); + if (type_is_invalid(var->value->type)) + return ira->codegen->builtin_types.entry_invalid; assert(var->value->type->id == TypeTableEntryIdMetaType); return var->value->data.x_type; } -static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, ScopeDecls *decls_scope) +static bool ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, ScopeDecls *decls_scope) { TypeTableEntry *type_info_definition_type = ir_type_info_get_type(ira, "Definition"); ensure_complete_type(ira->codegen, type_info_definition_type); + if (type_is_invalid(type_info_definition_type)) + return false; + ensure_field_index(type_info_definition_type, "name", 0); ensure_field_index(type_info_definition_type, "is_pub", 1); ensure_field_index(type_info_definition_type, "data", 2); TypeTableEntry *type_info_definition_data_type = ir_type_info_get_type(ira, "Data", type_info_definition_type); ensure_complete_type(ira->codegen, type_info_definition_data_type); + if (type_is_invalid(type_info_definition_data_type)) + return false; TypeTableEntry *type_info_fn_def_type = ir_type_info_get_type(ira, "FnDef", type_info_definition_data_type); ensure_complete_type(ira->codegen, type_info_fn_def_type); + if (type_is_invalid(type_info_fn_def_type)) + return false; TypeTableEntry *type_info_fn_def_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_def_type); ensure_complete_type(ira->codegen, type_info_fn_def_inline_type); + if (type_is_invalid(type_info_fn_def_inline_type)) + return false; // Loop through our definitions once to figure out how many definitions we will generate info for. auto decl_it = decls_scope->decl_table.entry_iterator(); @@ -15799,7 +15831,7 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop resolve_top_level_decl(ira->codegen, curr_entry->value, false, curr_entry->value->source_node); if (curr_entry->value->resolution != TldResolutionOk) { - return; + return false; } } @@ -15864,6 +15896,9 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop { VariableTableEntry *var = ((TldVar *)curr_entry->value)->var; ensure_complete_type(ira->codegen, var->value->type); + if (type_is_invalid(var->value->type)) + return false; + if (var->value->type->id == TypeTableEntryIdMetaType) { // We have a variable of type 'type', so it's actually a type definition. @@ -15991,6 +16026,9 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop { TypeTableEntry *type_entry = ((TldContainer *)curr_entry->value)->type_entry; ensure_complete_type(ira->codegen, type_entry); + if (type_is_invalid(type_entry)) + return false; + // This is a type. bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); @@ -16011,6 +16049,7 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop } assert(definition_index == definition_count); + return true; } static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry) @@ -16019,6 +16058,8 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t assert(!type_is_invalid(type_entry)); ensure_complete_type(ira->codegen, type_entry); + if (type_is_invalid(type_entry)) + return nullptr; const auto make_enum_field_val = [ira](ConstExprValue *enum_field_val, TypeEnumField *enum_field, TypeTableEntry *type_info_enum_field_type) { @@ -16246,7 +16287,8 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t } // defs: []TypeInfo.Definition ensure_field_index(result->type, "defs", 3); - ir_make_type_info_defs(ira, &fields[3], type_entry->data.enumeration.decls_scope); + if (!ir_make_type_info_defs(ira, &fields[3], type_entry->data.enumeration.decls_scope)) + return nullptr; break; } @@ -16401,7 +16443,8 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t } // defs: []TypeInfo.Definition ensure_field_index(result->type, "defs", 3); - ir_make_type_info_defs(ira, &fields[3], type_entry->data.unionation.decls_scope); + if (!ir_make_type_info_defs(ira, &fields[3], type_entry->data.unionation.decls_scope)) + return nullptr; break; } @@ -16412,6 +16455,8 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t buf_init_from_str(&ptr_field_name, "ptr"); TypeTableEntry *ptr_type = type_entry->data.structure.fields_by_name.get(&ptr_field_name)->type_entry; ensure_complete_type(ira->codegen, ptr_type); + if (type_is_invalid(ptr_type)) + return nullptr; buf_deinit(&ptr_field_name); result = create_ptr_like_type_info("Slice", ptr_type); @@ -16482,7 +16527,8 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t } // defs: []TypeInfo.Definition ensure_field_index(result->type, "defs", 2); - ir_make_type_info_defs(ira, &fields[2], type_entry->data.structure.decls_scope); + if (!ir_make_type_info_defs(ira, &fields[2], type_entry->data.structure.decls_scope)) + return nullptr; break; } @@ -17502,6 +17548,11 @@ static TypeTableEntry *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInst if (type_is_invalid(container_type)) return ira->codegen->builtin_types.entry_invalid; + ensure_complete_type(ira->codegen, container_type); + if (type_is_invalid(container_type)) + return ira->codegen->builtin_types.entry_invalid; + + uint64_t member_index; IrInstruction *index_value = instruction->member_index->other; if (!ir_resolve_usize(ira, index_value, &member_index)) @@ -17544,6 +17595,10 @@ static TypeTableEntry *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInst if (type_is_invalid(container_type)) return ira->codegen->builtin_types.entry_invalid; + ensure_complete_type(ira->codegen, container_type); + if (type_is_invalid(container_type)) + return ira->codegen->builtin_types.entry_invalid; + uint64_t member_index; IrInstruction *index_value = instruction->member_index->other; if (!ir_resolve_usize(ira, index_value, &member_index)) @@ -18485,7 +18540,12 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc return ira->codegen->builtin_types.entry_invalid; ensure_complete_type(ira->codegen, dest_type); + if (type_is_invalid(dest_type)) + return ira->codegen->builtin_types.entry_invalid; + ensure_complete_type(ira->codegen, src_type); + if (type_is_invalid(src_type)) + return ira->codegen->builtin_types.entry_invalid; if (get_codegen_ptr_type(src_type) != nullptr) { ir_add_error(ira, value, @@ -18724,6 +18784,9 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruc if (!ir_resolve_align(ira, instruction->align_value->other, &align_bytes)) return ira->codegen->builtin_types.entry_invalid; } else { + type_ensure_zero_bits_known(ira->codegen, child_type); + if (type_is_invalid(child_type)) + return ira->codegen->builtin_types.entry_invalid; align_bytes = get_abi_alignment(ira->codegen, child_type); } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 1297ed29ab..132dc8cd80 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -3232,7 +3232,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ fn bar(self: *const Foo) void {} \\}; , - ".tmp_source.zig:4:4: error: variable of type '*const (integer literal)' must be const or comptime", + ".tmp_source.zig:4:4: error: variable of type '*(integer literal)' must be const or comptime", ".tmp_source.zig:7:4: error: variable of type '(undefined)' must be const or comptime", ".tmp_source.zig:8:4: error: variable of type '(integer literal)' must be const or comptime", ".tmp_source.zig:9:4: error: variable of type '(float literal)' must be const or comptime", diff --git a/test/gen_h.zig b/test/gen_h.zig index 9559c3395c..e6a757ea6d 100644 --- a/test/gen_h.zig +++ b/test/gen_h.zig @@ -54,7 +54,7 @@ pub fn addCases(cases: *tests.GenHContext) void { cases.add("declare opaque type", \\export const Foo = @OpaqueType(); \\ - \\export fn entry(foo: ?&Foo) void { } + \\export fn entry(foo: ?*Foo) void { } , \\struct Foo; \\ @@ -64,7 +64,7 @@ pub fn addCases(cases: *tests.GenHContext) void { cases.add("array field-type", \\const Foo = extern struct { \\ A: [2]i32, - \\ B: [4]&u32, + \\ B: [4]*u32, \\}; \\export fn entry(foo: Foo, bar: [3]u8) void { } , diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig index 71d1d68764..61eba9458e 100644 --- a/test/runtime_safety.zig +++ b/test/runtime_safety.zig @@ -2,7 +2,7 @@ const tests = @import("tests.zig"); pub fn addCases(cases: *tests.CompareOutputContext) void { cases.addRuntimeSafety("calling panic", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() void { @@ -11,7 +11,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("out of bounds slice access", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() void { @@ -25,7 +25,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("integer addition overflow", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -38,7 +38,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("integer subtraction overflow", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -51,7 +51,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("integer multiplication overflow", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -64,7 +64,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("integer negation overflow", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -77,7 +77,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("signed integer division overflow", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -90,7 +90,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("signed shift left overflow", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -103,7 +103,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("unsigned shift left overflow", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -116,7 +116,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("signed shift right overflow", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -129,7 +129,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("unsigned shift right overflow", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -142,7 +142,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("integer division by zero", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() void { @@ -154,7 +154,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("exact division failure", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -167,7 +167,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -180,7 +180,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("value does not fit in shortening cast", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -193,7 +193,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -206,7 +206,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("unwrap error", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) { \\ @import("std").os.exit(126); // good \\ } @@ -221,7 +221,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("cast integer to global error and no code matches", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() void { @@ -233,7 +233,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("cast integer to non-global error set and no match", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\const Set1 = error{A, B}; @@ -247,7 +247,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("@alignCast misaligned", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { @@ -263,7 +263,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { ); cases.addRuntimeSafety("bad union field access", - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); \\} \\ @@ -277,7 +277,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\ bar(&f); \\} \\ - \\fn bar(f: &Foo) void { + \\fn bar(f: *Foo) void { \\ f.float = 12.34; \\} ); @@ -287,7 +287,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { cases.addRuntimeSafety("error return trace across suspend points", \\const std = @import("std"); \\ - \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn { + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ std.os.exit(126); \\} \\ -- cgit v1.2.3