| ... | @@ -7451,6 +7451,9 @@ fn analyzeAs( | ... | @@ -7451,6 +7451,9 @@ fn analyzeAs( |
| 7451 | zir_operand: Zir.Inst.Ref, | 7451 | zir_operand: Zir.Inst.Ref, |
| 7452 | ) CompileError!Air.Inst.Ref { | 7452 | ) CompileError!Air.Inst.Ref { |
| 7453 | const dest_ty = try sema.resolveType(block, src, zir_dest_type); | 7453 | const dest_ty = try sema.resolveType(block, src, zir_dest_type); |
| | 7454 | if (dest_ty.zigTypeTag() == .NoReturn) { |
| | 7455 | return sema.fail(block, src, "cannot cast to noreturn", .{}); |
| | 7456 | } |
| 7454 | const operand = try sema.resolveInst(zir_operand); | 7457 | const operand = try sema.resolveInst(zir_operand); |
| 7455 | if (dest_ty.tag() == .var_args_param) return operand; | 7458 | if (dest_ty.tag() == .var_args_param) return operand; |
| 7456 | return sema.coerce(block, dest_ty, operand, src); | 7459 | return sema.coerce(block, dest_ty, operand, src); |
| ... | @@ -13688,7 +13691,8 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -13688,7 +13691,8 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 13688 | defer tracy.end(); | 13691 | defer tracy.end(); |
| 13689 | | 13692 | |
| 13690 | const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple; | 13693 | const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple; |
| 13691 | const elem_type = try sema.resolveType(block, .unneeded, inst_data.elem_type); | 13694 | const elem_ty_src = sema.src; // TODO better source location |
| | 13695 | const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.elem_type); |
| 13692 | const ty = try Type.ptr(sema.arena, sema.mod, .{ | 13696 | const ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 13693 | .pointee_type = elem_type, | 13697 | .pointee_type = elem_type, |
| 13694 | .@"addrspace" = .generic, | 13698 | .@"addrspace" = .generic, |
| ... | @@ -13697,6 +13701,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -13697,6 +13701,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 13697 | .@"volatile" = inst_data.is_volatile, | 13701 | .@"volatile" = inst_data.is_volatile, |
| 13698 | .size = inst_data.size, | 13702 | .size = inst_data.size, |
| 13699 | }); | 13703 | }); |
| | 13704 | try sema.validatePtrTy(block, elem_ty_src, ty, inst_data.is_allowzero); |
| 13700 | return sema.addType(ty); | 13705 | return sema.addType(ty); |
| 13701 | } | 13706 | } |
| 13702 | | 13707 | |
| ... | @@ -13704,9 +13709,12 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -13704,9 +13709,12 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13704 | const tracy = trace(@src()); | 13709 | const tracy = trace(@src()); |
| 13705 | defer tracy.end(); | 13710 | defer tracy.end(); |
| 13706 | | 13711 | |
| 13707 | // TODO better source location | 13712 | const src: LazySrcLoc = sema.src; // TODO better source location |
| 13708 | const src: LazySrcLoc = sema.src; | 13713 | const elem_ty_src: LazySrcLoc = sema.src; // TODO better source location |
| 13709 | const elem_ty_src: LazySrcLoc = .unneeded; | 13714 | const sentinel_src: LazySrcLoc = sema.src; // TODO better source location |
| | 13715 | const addrspace_src: LazySrcLoc = sema.src; // TODO better source location |
| | 13716 | const bitoffset_src: LazySrcLoc = sema.src; // TODO better source location |
| | 13717 | const hostsize_src: LazySrcLoc = sema.src; // TODO better source location |
| 13710 | const inst_data = sema.code.instructions.items(.data)[inst].ptr_type; | 13718 | const inst_data = sema.code.instructions.items(.data)[inst].ptr_type; |
| 13711 | const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index); | 13719 | const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index); |
| 13712 | const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type); | 13720 | const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type); |
| ... | @@ -13717,7 +13725,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -13717,7 +13725,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13717 | const sentinel = if (inst_data.flags.has_sentinel) blk: { | 13725 | const sentinel = if (inst_data.flags.has_sentinel) blk: { |
| 13718 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); | 13726 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 13719 | extra_i += 1; | 13727 | extra_i += 1; |
| 13720 | break :blk (try sema.resolveInstConst(block, .unneeded, ref)).val; | 13728 | break :blk (try sema.resolveInstConst(block, sentinel_src, ref)).val; |
| 13721 | } else null; | 13729 | } else null; |
| 13722 | | 13730 | |
| 13723 | const abi_align: u32 = if (inst_data.flags.has_align) blk: { | 13731 | const abi_align: u32 = if (inst_data.flags.has_align) blk: { |
| ... | @@ -13739,20 +13747,20 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -13739,20 +13747,20 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13739 | const address_space = if (inst_data.flags.has_addrspace) blk: { | 13747 | const address_space = if (inst_data.flags.has_addrspace) blk: { |
| 13740 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); | 13748 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 13741 | extra_i += 1; | 13749 | extra_i += 1; |
| 13742 | break :blk try sema.analyzeAddrspace(block, .unneeded, ref, .pointer); | 13750 | break :blk try sema.analyzeAddrspace(block, addrspace_src, ref, .pointer); |
| 13743 | } else .generic; | 13751 | } else .generic; |
| 13744 | | 13752 | |
| 13745 | const bit_offset = if (inst_data.flags.has_bit_range) blk: { | 13753 | const bit_offset = if (inst_data.flags.has_bit_range) blk: { |
| 13746 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); | 13754 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 13747 | extra_i += 1; | 13755 | extra_i += 1; |
| 13748 | const bit_offset = try sema.resolveInt(block, .unneeded, ref, Type.u16); | 13756 | const bit_offset = try sema.resolveInt(block, bitoffset_src, ref, Type.u16); |
| 13749 | break :blk @intCast(u16, bit_offset); | 13757 | break :blk @intCast(u16, bit_offset); |
| 13750 | } else 0; | 13758 | } else 0; |
| 13751 | | 13759 | |
| 13752 | const host_size: u16 = if (inst_data.flags.has_bit_range) blk: { | 13760 | const host_size: u16 = if (inst_data.flags.has_bit_range) blk: { |
| 13753 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); | 13761 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 13754 | extra_i += 1; | 13762 | extra_i += 1; |
| 13755 | const host_size = try sema.resolveInt(block, .unneeded, ref, Type.u16); | 13763 | const host_size = try sema.resolveInt(block, hostsize_src, ref, Type.u16); |
| 13756 | break :blk @intCast(u16, host_size); | 13764 | break :blk @intCast(u16, host_size); |
| 13757 | } else 0; | 13765 | } else 0; |
| 13758 | | 13766 | |
| ... | @@ -13779,9 +13787,27 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -13779,9 +13787,27 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13779 | .@"volatile" = inst_data.flags.is_volatile, | 13787 | .@"volatile" = inst_data.flags.is_volatile, |
| 13780 | .size = inst_data.size, | 13788 | .size = inst_data.size, |
| 13781 | }); | 13789 | }); |
| | 13790 | try sema.validatePtrTy(block, elem_ty_src, ty, inst_data.flags.is_allowzero); |
| 13782 | return sema.addType(ty); | 13791 | return sema.addType(ty); |
| 13783 | } | 13792 | } |
| 13784 | | 13793 | |
| | 13794 | fn validatePtrTy(sema: *Sema, block: *Block, elem_src: LazySrcLoc, ty: Type, explicit_allowzer: bool) CompileError!void { |
| | 13795 | const ptr_info = ty.ptrInfo().data; |
| | 13796 | const pointee_tag = ptr_info.pointee_type.zigTypeTag(); |
| | 13797 | if (pointee_tag == .NoReturn) { |
| | 13798 | return sema.fail(block, elem_src, "pointer to noreturn not allowed", .{}); |
| | 13799 | } else if (ptr_info.size == .Many and pointee_tag == .Opaque) { |
| | 13800 | return sema.fail(block, elem_src, "unknown-length pointer to opaque not allowed", .{}); |
| | 13801 | } else if (ptr_info.size == .C) { |
| | 13802 | // TODO check extern type |
| | 13803 | if (pointee_tag == .Opaque) { |
| | 13804 | return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{}); |
| | 13805 | } else if (explicit_allowzer) { |
| | 13806 | return sema.fail(block, elem_src, "C pointers always allow address zero", .{}); |
| | 13807 | } |
| | 13808 | } |
| | 13809 | } |
| | 13810 | |
| 13785 | fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13811 | fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 13786 | const tracy = trace(@src()); | 13812 | const tracy = trace(@src()); |
| 13787 | defer tracy.end(); | 13813 | defer tracy.end(); |