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(
74517451 zir_operand: Zir.Inst.Ref,
74527452) CompileError!Air.Inst.Ref {
74537453 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 }
74547457 const operand = try sema.resolveInst(zir_operand);
74557458 if (dest_ty.tag() == .var_args_param) return operand;
74567459 return sema.coerce(block, dest_ty, operand, src);
......@@ -13688,7 +13691,8 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
1368813691 defer tracy.end();
1368913692
1369013693 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);
1369213696 const ty = try Type.ptr(sema.arena, sema.mod, .{
1369313697 .pointee_type = elem_type,
1369413698 .@"addrspace" = .generic,
......@@ -13697,6 +13701,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
1369713701 .@"volatile" = inst_data.is_volatile,
1369813702 .size = inst_data.size,
1369913703 });
13704 try sema.validatePtrTy(block, elem_ty_src, ty, inst_data.is_allowzero);
1370013705 return sema.addType(ty);
1370113706}
1370213707
......@@ -13704,9 +13709,12 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1370413709 const tracy = trace(@src());
1370513710 defer tracy.end();
1370613711
13707 // TODO better source location
13708 const src: LazySrcLoc = sema.src;
13709 const elem_ty_src: LazySrcLoc = .unneeded;
13712 const src: LazySrcLoc = sema.src; // TODO better source location
13713 const elem_ty_src: LazySrcLoc = sema.src; // TODO better source location
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
1371013718 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
1371113719 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);
1371213720 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
1371713725 const sentinel = if (inst_data.flags.has_sentinel) blk: {
1371813726 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
1371913727 extra_i += 1;
13720 break :blk (try sema.resolveInstConst(block, .unneeded, ref)).val;
13728 break :blk (try sema.resolveInstConst(block, sentinel_src, ref)).val;
1372113729 } else null;
1372213730
1372313731 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
1373913747 const address_space = if (inst_data.flags.has_addrspace) blk: {
1374013748 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
1374113749 extra_i += 1;
13742 break :blk try sema.analyzeAddrspace(block, .unneeded, ref, .pointer);
13750 break :blk try sema.analyzeAddrspace(block, addrspace_src, ref, .pointer);
1374313751 } else .generic;
1374413752
1374513753 const bit_offset = if (inst_data.flags.has_bit_range) blk: {
1374613754 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
1374713755 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);
1374913757 break :blk @intCast(u16, bit_offset);
1375013758 } else 0;
1375113759
1375213760 const host_size: u16 = if (inst_data.flags.has_bit_range) blk: {
1375313761 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
1375413762 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);
1375613764 break :blk @intCast(u16, host_size);
1375713765 } else 0;
1375813766
......@@ -13779,9 +13787,27 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1377913787 .@"volatile" = inst_data.flags.is_volatile,
1378013788 .size = inst_data.size,
1378113789 });
13790 try sema.validatePtrTy(block, elem_ty_src, ty, inst_data.flags.is_allowzero);
1378213791 return sema.addType(ty);
1378313792}
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
1378513811fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1378613812 const tracy = trace(@src());
1378713813 defer tracy.end();
test/cases/compile_errors/unreachable_variable.zig+1-1
......@@ -7,4 +7,4 @@ export fn f() void {
77// backend=stage2
88// target=native
99//
10// :2:25: error: expected type 'noreturn', found 'void'
10// :2:25: error: cannot cast to noreturn