authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-01 20:14:56+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-07 10:50:05+03:00
log1569b9c16590f8c5359003ae310093217e5fcf63
treedcbca3b5a40392934af46add4f4bdd7aeaf7e2b2
parent299836dbd94dd9af25b8485f58ba611b62909d54

Sema: validate pointer types


2 files changed, 35 insertions(+), 9 deletions(-)

src/Sema.zig+34-8
...@@ -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();
1368913692
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}
1370213707
...@@ -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();
1370613711
13707 // TODO better source location13712 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;
1372213730
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;
1374413752
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;
1375113759
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;
1375813766
...@@ -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}
1378413793
13794fn 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
13785fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13811fn 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();
test/cases/compile_errors/unreachable_variable.zig+1-1
...@@ -7,4 +7,4 @@ export fn f() void {...@@ -7,4 +7,4 @@ export fn f() void {
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :2:25: error: expected type 'noreturn', found 'void'10// :2:25: error: cannot cast to noreturn