authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-12 16:08:23+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-21 12:21:30-07:00
logd72917320449f449bcdeb6a20d5a98b1dfb901d4
tree04a1887e12b989d78813189e2e89ddfd620d0b9b
parent29815fe9de50be3b07e39cd02ccfcc801a54c455

stage2: better pointer source location


22 files changed, 271 insertions(+), 221 deletions(-)

src/AstGen.zig+8-39
...@@ -1347,7 +1347,7 @@ fn arrayInitExpr(...@@ -1347,7 +1347,7 @@ fn arrayInitExpr(
1347 }1347 }
1348 }1348 }
1349 const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);1349 const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);
1350 _ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, node);1350 _ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, array_init.ast.type_expr);
1351 break :inst .{1351 break :inst .{
1352 .array = array_type_inst,1352 .array = array_type_inst,
1353 .elem = .none,1353 .elem = .none,
...@@ -2332,7 +2332,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner...@@ -2332,7 +2332,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
2332 .err_union_code,2332 .err_union_code,
2333 .err_union_code_ptr,2333 .err_union_code_ptr,
2334 .ptr_type,2334 .ptr_type,
2335 .ptr_type_simple,2335 .overflow_arithmetic_ptr,
2336 .enum_literal,2336 .enum_literal,
2337 .merge_error_sets,2337 .merge_error_sets,
2338 .error_union_type,2338 .error_union_type,
...@@ -3110,24 +3110,6 @@ fn ptrType(...@@ -3110,24 +3110,6 @@ fn ptrType(
31103110
3111 const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);3111 const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);
31123112
3113 const simple = ptr_info.ast.align_node == 0 and
3114 ptr_info.ast.addrspace_node == 0 and
3115 ptr_info.ast.sentinel == 0 and
3116 ptr_info.ast.bit_range_start == 0;
3117
3118 if (simple) {
3119 const result = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
3120 .ptr_type_simple = .{
3121 .is_allowzero = ptr_info.allowzero_token != null,
3122 .is_mutable = ptr_info.const_token == null,
3123 .is_volatile = ptr_info.volatile_token != null,
3124 .size = ptr_info.size,
3125 .elem_type = elem_type,
3126 },
3127 } });
3128 return rvalue(gz, rl, result, node);
3129 }
3130
3131 var sentinel_ref: Zir.Inst.Ref = .none;3113 var sentinel_ref: Zir.Inst.Ref = .none;
3132 var align_ref: Zir.Inst.Ref = .none;3114 var align_ref: Zir.Inst.Ref = .none;
3133 var addrspace_ref: Zir.Inst.Ref = .none;3115 var addrspace_ref: Zir.Inst.Ref = .none;
...@@ -3160,7 +3142,10 @@ fn ptrType(...@@ -3160,7 +3142,10 @@ fn ptrType(
3160 try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.PtrType).Struct.fields.len +3142 try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.PtrType).Struct.fields.len +
3161 trailing_count);3143 trailing_count);
31623144
3163 const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.PtrType{ .elem_type = elem_type });3145 const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.PtrType{
3146 .elem_type = elem_type,
3147 .src_node = gz.nodeIndexToRelative(node),
3148 });
3164 if (sentinel_ref != .none) {3149 if (sentinel_ref != .none) {
3165 gz.astgen.extra.appendAssumeCapacity(@enumToInt(sentinel_ref));3150 gz.astgen.extra.appendAssumeCapacity(@enumToInt(sentinel_ref));
3166 }3151 }
...@@ -7588,15 +7573,7 @@ fn builtinCall(...@@ -7588,15 +7573,7 @@ fn builtinCall(
7588 .shl_with_overflow => {7573 .shl_with_overflow => {
7589 const int_type = try typeExpr(gz, scope, params[0]);7574 const int_type = try typeExpr(gz, scope, params[0]);
7590 const log2_int_type = try gz.addUnNode(.log2_int_type, int_type, params[0]);7575 const log2_int_type = try gz.addUnNode(.log2_int_type, int_type, params[0]);
7591 const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{7576 const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]);
7592 .ptr_type_simple = .{
7593 .is_allowzero = false,
7594 .is_mutable = true,
7595 .is_volatile = false,
7596 .size = .One,
7597 .elem_type = int_type,
7598 },
7599 } });
7600 const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);7577 const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);
7601 const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, params[2]);7578 const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, params[2]);
7602 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);7579 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);
...@@ -7987,15 +7964,7 @@ fn overflowArithmetic(...@@ -7987,15 +7964,7 @@ fn overflowArithmetic(
7987 tag: Zir.Inst.Extended,7964 tag: Zir.Inst.Extended,
7988) InnerError!Zir.Inst.Ref {7965) InnerError!Zir.Inst.Ref {
7989 const int_type = try typeExpr(gz, scope, params[0]);7966 const int_type = try typeExpr(gz, scope, params[0]);
7990 const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{7967 const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]);
7991 .ptr_type_simple = .{
7992 .is_allowzero = false,
7993 .is_mutable = true,
7994 .is_volatile = false,
7995 .size = .One,
7996 .elem_type = int_type,
7997 },
7998 } });
7999 const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);7968 const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);
8000 const rhs = try expr(gz, scope, .{ .ty = int_type }, params[2]);7969 const rhs = try expr(gz, scope, .{ .ty = int_type }, params[2]);
8001 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);7970 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);
src/Module.zig+108
...@@ -2466,6 +2466,90 @@ pub const SrcLoc = struct {...@@ -2466,6 +2466,90 @@ pub const SrcLoc = struct {
24662466
2467 return nodeToSpan(tree, node_datas[node].lhs);2467 return nodeToSpan(tree, node_datas[node].lhs);
2468 },2468 },
2469 .node_offset_ptr_elem => |node_off| {
2470 const tree = try src_loc.file_scope.getTree(gpa);
2471 const node_tags = tree.nodes.items(.tag);
2472 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2473
2474 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2475 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2476 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2477 .ptr_type => tree.ptrType(parent_node),
2478 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2479 else => unreachable,
2480 };
2481 return nodeToSpan(tree, full.ast.child_type);
2482 },
2483 .node_offset_ptr_sentinel => |node_off| {
2484 const tree = try src_loc.file_scope.getTree(gpa);
2485 const node_tags = tree.nodes.items(.tag);
2486 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2487
2488 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2489 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2490 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2491 .ptr_type => tree.ptrType(parent_node),
2492 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2493 else => unreachable,
2494 };
2495 return nodeToSpan(tree, full.ast.sentinel);
2496 },
2497 .node_offset_ptr_align => |node_off| {
2498 const tree = try src_loc.file_scope.getTree(gpa);
2499 const node_tags = tree.nodes.items(.tag);
2500 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2501
2502 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2503 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2504 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2505 .ptr_type => tree.ptrType(parent_node),
2506 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2507 else => unreachable,
2508 };
2509 return nodeToSpan(tree, full.ast.align_node);
2510 },
2511 .node_offset_ptr_addrspace => |node_off| {
2512 const tree = try src_loc.file_scope.getTree(gpa);
2513 const node_tags = tree.nodes.items(.tag);
2514 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2515
2516 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2517 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2518 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2519 .ptr_type => tree.ptrType(parent_node),
2520 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2521 else => unreachable,
2522 };
2523 return nodeToSpan(tree, full.ast.addrspace_node);
2524 },
2525 .node_offset_ptr_bitoffset => |node_off| {
2526 const tree = try src_loc.file_scope.getTree(gpa);
2527 const node_tags = tree.nodes.items(.tag);
2528 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2529
2530 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2531 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2532 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2533 .ptr_type => tree.ptrType(parent_node),
2534 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2535 else => unreachable,
2536 };
2537 return nodeToSpan(tree, full.ast.bit_range_start);
2538 },
2539 .node_offset_ptr_hostsize => |node_off| {
2540 const tree = try src_loc.file_scope.getTree(gpa);
2541 const node_tags = tree.nodes.items(.tag);
2542 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2543
2544 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2545 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2546 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2547 .ptr_type => tree.ptrType(parent_node),
2548 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2549 else => unreachable,
2550 };
2551 return nodeToSpan(tree, full.ast.bit_range_end);
2552 },
2469 }2553 }
2470 }2554 }
24712555
...@@ -2739,6 +2823,24 @@ pub const LazySrcLoc = union(enum) {...@@ -2739,6 +2823,24 @@ pub const LazySrcLoc = union(enum) {
2739 /// The source location points to the operand of an unary expression.2823 /// The source location points to the operand of an unary expression.
2740 /// The Decl is determined contextually.2824 /// The Decl is determined contextually.
2741 node_offset_un_op: i32,2825 node_offset_un_op: i32,
2826 /// The source location points to the elem type of a pointer.
2827 /// The Decl is determined contextually.
2828 node_offset_ptr_elem: i32,
2829 /// The source location points to the sentinel of a pointer.
2830 /// The Decl is determined contextually.
2831 node_offset_ptr_sentinel: i32,
2832 /// The source location points to the align expr of a pointer.
2833 /// The Decl is determined contextually.
2834 node_offset_ptr_align: i32,
2835 /// The source location points to the addrspace expr of a pointer.
2836 /// The Decl is determined contextually.
2837 node_offset_ptr_addrspace: i32,
2838 /// The source location points to the bit-offset of a pointer.
2839 /// The Decl is determined contextually.
2840 node_offset_ptr_bitoffset: i32,
2841 /// The source location points to the host size of a pointer.
2842 /// The Decl is determined contextually.
2843 node_offset_ptr_hostsize: i32,
27422844
2743 pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;2845 pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;
27442846
...@@ -2803,6 +2905,12 @@ pub const LazySrcLoc = union(enum) {...@@ -2803,6 +2905,12 @@ pub const LazySrcLoc = union(enum) {
2803 .node_offset_array_type_sentinel,2905 .node_offset_array_type_sentinel,
2804 .node_offset_array_type_elem,2906 .node_offset_array_type_elem,
2805 .node_offset_un_op,2907 .node_offset_un_op,
2908 .node_offset_ptr_elem,
2909 .node_offset_ptr_sentinel,
2910 .node_offset_ptr_align,
2911 .node_offset_ptr_addrspace,
2912 .node_offset_ptr_bitoffset,
2913 .node_offset_ptr_hostsize,
2806 => .{2914 => .{
2807 .file_scope = decl.getFileScope(),2915 .file_scope = decl.getFileScope(),
2808 .parent_decl_node = decl.src_node,2916 .parent_decl_node = decl.src_node,
src/Sema.zig+43-48
...@@ -768,7 +768,7 @@ fn analyzeBodyInner(...@@ -768,7 +768,7 @@ fn analyzeBodyInner(
768 .optional_type => try sema.zirOptionalType(block, inst),768 .optional_type => try sema.zirOptionalType(block, inst),
769 .param_type => try sema.zirParamType(block, inst),769 .param_type => try sema.zirParamType(block, inst),
770 .ptr_type => try sema.zirPtrType(block, inst),770 .ptr_type => try sema.zirPtrType(block, inst),
771 .ptr_type_simple => try sema.zirPtrTypeSimple(block, inst),771 .overflow_arithmetic_ptr => try sema.zirOverflowArithmeticPtr(block, inst),
772 .ref => try sema.zirRef(block, inst),772 .ref => try sema.zirRef(block, inst),
773 .ret_err_value_code => try sema.zirRetErrValueCode(inst),773 .ret_err_value_code => try sema.zirRetErrValueCode(inst),
774 .shr => try sema.zirShr(block, inst, .shr),774 .shr => try sema.zirShr(block, inst, .shr),
...@@ -13835,22 +13835,21 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool {...@@ -13835,22 +13835,21 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool {
13835 };13835 };
13836}13836}
1383713837
13838fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13838fn zirOverflowArithmeticPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13839 const tracy = trace(@src());13839 const tracy = trace(@src());
13840 defer tracy.end();13840 defer tracy.end();
1384113841
13842 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple;13842 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
13843 const elem_ty_src = sema.src; // TODO better source location13843 const elem_ty_src = inst_data.src();
13844 const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.elem_type);13844 const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.operand);
13845 const ty = try Type.ptr(sema.arena, sema.mod, .{13845 const ty = try Type.ptr(sema.arena, sema.mod, .{
13846 .pointee_type = elem_type,13846 .pointee_type = elem_type,
13847 .@"addrspace" = .generic,13847 .@"addrspace" = .generic,
13848 .mutable = inst_data.is_mutable,13848 .mutable = true,
13849 .@"allowzero" = inst_data.is_allowzero or inst_data.size == .C,13849 .@"allowzero" = false,
13850 .@"volatile" = inst_data.is_volatile,13850 .@"volatile" = false,
13851 .size = inst_data.size,13851 .size = .One,
13852 });13852 });
13853 try sema.validatePtrTy(block, elem_ty_src, ty);
13854 return sema.addType(ty);13853 return sema.addType(ty);
13855}13854}
1385613855
...@@ -13858,14 +13857,15 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13858,14 +13857,15 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13858 const tracy = trace(@src());13857 const tracy = trace(@src());
13859 defer tracy.end();13858 defer tracy.end();
1386013859
13861 const src: LazySrcLoc = sema.src; // TODO better source location
13862 const elem_ty_src: LazySrcLoc = sema.src; // TODO better source location
13863 const sentinel_src: LazySrcLoc = sema.src; // TODO better source location
13864 const addrspace_src: LazySrcLoc = sema.src; // TODO better source location
13865 const bitoffset_src: LazySrcLoc = sema.src; // TODO better source location
13866 const hostsize_src: LazySrcLoc = sema.src; // TODO better source location
13867 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;13860 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
13868 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);13861 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);
13862 const elem_ty_src: LazySrcLoc = .{ .node_offset_ptr_elem = extra.data.src_node };
13863 const sentinel_src: LazySrcLoc = .{ .node_offset_ptr_sentinel = extra.data.src_node };
13864 const align_src: LazySrcLoc = .{ .node_offset_ptr_align = extra.data.src_node };
13865 const addrspace_src: LazySrcLoc = .{ .node_offset_ptr_addrspace = extra.data.src_node };
13866 const bitoffset_src: LazySrcLoc = .{ .node_offset_ptr_bitoffset = extra.data.src_node };
13867 const hostsize_src: LazySrcLoc = .{ .node_offset_ptr_hostsize = extra.data.src_node };
13868
13869 const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type);13869 const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type);
13870 const target = sema.mod.getTarget();13870 const target = sema.mod.getTarget();
1387113871
...@@ -13880,8 +13880,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13880,8 +13880,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13880 const abi_align: u32 = if (inst_data.flags.has_align) blk: {13880 const abi_align: u32 = if (inst_data.flags.has_align) blk: {
13881 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);13881 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
13882 extra_i += 1;13882 extra_i += 1;
13883 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), src);13883 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src);
13884 const val = try sema.resolveConstValue(block, src, coerced);13884 const val = try sema.resolveConstValue(block, align_src, coerced);
13885 // Check if this happens to be the lazy alignment of our element type, in13885 // Check if this happens to be the lazy alignment of our element type, in
13886 // which case we can make this 0 without resolving it.13886 // which case we can make this 0 without resolving it.
13887 if (val.castTag(.lazy_align)) |payload| {13887 if (val.castTag(.lazy_align)) |payload| {
...@@ -13889,7 +13889,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13889,7 +13889,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13889 break :blk 0;13889 break :blk 0;
13890 }13890 }
13891 }13891 }
13892 const abi_align = (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?;13892 const abi_align = (try val.getUnsignedIntAdvanced(target, sema.kit(block, align_src))).?;
13893 break :blk @intCast(u32, abi_align);13893 break :blk @intCast(u32, abi_align);
13894 } else 0;13894 } else 0;
1389513895
...@@ -13914,7 +13914,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13914,7 +13914,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13914 } else 0;13914 } else 0;
1391513915
13916 if (host_size != 0 and bit_offset >= host_size * 8) {13916 if (host_size != 0 and bit_offset >= host_size * 8) {
13917 return sema.fail(block, src, "bit offset starts after end of host integer", .{});13917 return sema.fail(block, bitoffset_src, "bit offset starts after end of host integer", .{});
13918 }13918 }
1391913919
13920 const elem_ty = if (abi_align == 0)13920 const elem_ty = if (abi_align == 0)
...@@ -13924,48 +13924,43 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13924,48 +13924,43 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13924 try sema.resolveTypeLayout(block, elem_ty_src, elem_ty);13924 try sema.resolveTypeLayout(block, elem_ty_src, elem_ty);
13925 break :t elem_ty;13925 break :t elem_ty;
13926 };13926 };
13927 const ty = try Type.ptr(sema.arena, sema.mod, .{
13928 .pointee_type = elem_ty,
13929 .sentinel = sentinel,
13930 .@"align" = abi_align,
13931 .@"addrspace" = address_space,
13932 .bit_offset = bit_offset,
13933 .host_size = host_size,
13934 .mutable = inst_data.flags.is_mutable,
13935 .@"allowzero" = inst_data.flags.is_allowzero,
13936 .@"volatile" = inst_data.flags.is_volatile,
13937 .size = inst_data.size,
13938 });
13939 try sema.validatePtrTy(block, elem_ty_src, ty);
13940 return sema.addType(ty);
13941}
1394213927
13943fn validatePtrTy(sema: *Sema, block: *Block, elem_src: LazySrcLoc, ty: Type) CompileError!void {13928 if (elem_ty.zigTypeTag() == .NoReturn) {
13944 const ptr_info = ty.ptrInfo().data;13929 return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{});
13945 const pointee_tag = ptr_info.pointee_type.zigTypeTag();13930 } else if (inst_data.size == .Many and elem_ty.zigTypeTag() == .Opaque) {
13946 if (pointee_tag == .NoReturn) {13931 return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{});
13947 return sema.fail(block, elem_src, "pointer to noreturn not allowed", .{});13932 } else if (inst_data.size == .C) {
13948 } else if (ptr_info.size == .Many and pointee_tag == .Opaque) {
13949 return sema.fail(block, elem_src, "unknown-length pointer to opaque not allowed", .{});
13950 } else if (ptr_info.size == .C) {
13951 const elem_ty = ptr_info.pointee_type;
13952 if (!(try sema.validateExternType(elem_ty, .other))) {13933 if (!(try sema.validateExternType(elem_ty, .other))) {
13953 const msg = msg: {13934 const msg = msg: {
13954 const msg = try sema.errMsg(block, elem_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});13935 const msg = try sema.errMsg(block, elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});
13955 errdefer msg.destroy(sema.gpa);13936 errdefer msg.destroy(sema.gpa);
1395613937
13957 const src_decl = sema.mod.declPtr(block.src_decl);13938 const src_decl = sema.mod.declPtr(block.src_decl);
13958 try sema.explainWhyTypeIsNotExtern(block, elem_src, msg, elem_src.toSrcLoc(src_decl), elem_ty, .other);13939 try sema.explainWhyTypeIsNotExtern(block, elem_ty_src, msg, elem_ty_src.toSrcLoc(src_decl), elem_ty, .other);
1395913940
13960 try sema.addDeclaredHereNote(msg, elem_ty);13941 try sema.addDeclaredHereNote(msg, elem_ty);
13961 break :msg msg;13942 break :msg msg;
13962 };13943 };
13963 return sema.failWithOwnedErrorMsg(block, msg);13944 return sema.failWithOwnedErrorMsg(block, msg);
13964 }13945 }
13965 if (pointee_tag == .Opaque) {13946 if (elem_ty.zigTypeTag() == .Opaque) {
13966 return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{});13947 return sema.fail(block, elem_ty_src, "C pointers cannot point to opaque types", .{});
13967 }13948 }
13968 }13949 }
13950
13951 const ty = try Type.ptr(sema.arena, sema.mod, .{
13952 .pointee_type = elem_ty,
13953 .sentinel = sentinel,
13954 .@"align" = abi_align,
13955 .@"addrspace" = address_space,
13956 .bit_offset = bit_offset,
13957 .host_size = host_size,
13958 .mutable = inst_data.flags.is_mutable,
13959 .@"allowzero" = inst_data.flags.is_allowzero,
13960 .@"volatile" = inst_data.flags.is_volatile,
13961 .size = inst_data.size,
13962 });
13963 return sema.addType(ty);
13969}13964}
1397013965
13971fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13966fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
src/Zir.zig+7-14
...@@ -534,9 +534,9 @@ pub const Inst = struct {...@@ -534,9 +534,9 @@ pub const Inst = struct {
534 /// Obtains the return type of the in-scope function.534 /// Obtains the return type of the in-scope function.
535 /// Uses the `node` union field.535 /// Uses the `node` union field.
536 ret_type,536 ret_type,
537 /// Create a pointer type that does not have a sentinel, alignment, address space, or bit range specified.537 /// Create a pointer type for overflow arithmetic.
538 /// Uses the `ptr_type_simple` union field.538 /// TODO remove when doing https://github.com/ziglang/zig/issues/10248
539 ptr_type_simple,539 overflow_arithmetic_ptr,
540 /// Create a pointer type which can have a sentinel, alignment, address space, and/or bit range.540 /// Create a pointer type which can have a sentinel, alignment, address space, and/or bit range.
541 /// Uses the `ptr_type` union field.541 /// Uses the `ptr_type` union field.
542 ptr_type,542 ptr_type,
...@@ -1121,7 +1121,7 @@ pub const Inst = struct {...@@ -1121,7 +1121,7 @@ pub const Inst = struct {
1121 .err_union_code,1121 .err_union_code,
1122 .err_union_code_ptr,1122 .err_union_code_ptr,
1123 .ptr_type,1123 .ptr_type,
1124 .ptr_type_simple,1124 .overflow_arithmetic_ptr,
1125 .ensure_err_payload_void,1125 .ensure_err_payload_void,
1126 .enum_literal,1126 .enum_literal,
1127 .merge_error_sets,1127 .merge_error_sets,
...@@ -1417,7 +1417,7 @@ pub const Inst = struct {...@@ -1417,7 +1417,7 @@ pub const Inst = struct {
1417 .err_union_code,1417 .err_union_code,
1418 .err_union_code_ptr,1418 .err_union_code_ptr,
1419 .ptr_type,1419 .ptr_type,
1420 .ptr_type_simple,1420 .overflow_arithmetic_ptr,
1421 .enum_literal,1421 .enum_literal,
1422 .merge_error_sets,1422 .merge_error_sets,
1423 .error_union_type,1423 .error_union_type,
...@@ -1659,7 +1659,7 @@ pub const Inst = struct {...@@ -1659,7 +1659,7 @@ pub const Inst = struct {
1659 .ret_err_value_code = .str_tok,1659 .ret_err_value_code = .str_tok,
1660 .ret_ptr = .node,1660 .ret_ptr = .node,
1661 .ret_type = .node,1661 .ret_type = .node,
1662 .ptr_type_simple = .ptr_type_simple,1662 .overflow_arithmetic_ptr = .un_node,
1663 .ptr_type = .ptr_type,1663 .ptr_type = .ptr_type,
1664 .slice_start = .pl_node,1664 .slice_start = .pl_node,
1665 .slice_end = .pl_node,1665 .slice_end = .pl_node,
...@@ -2499,13 +2499,6 @@ pub const Inst = struct {...@@ -2499,13 +2499,6 @@ pub const Inst = struct {
2499 node: i32,2499 node: i32,
2500 int: u64,2500 int: u64,
2501 float: f64,2501 float: f64,
2502 ptr_type_simple: struct {
2503 is_allowzero: bool,
2504 is_mutable: bool,
2505 is_volatile: bool,
2506 size: std.builtin.Type.Pointer.Size,
2507 elem_type: Ref,
2508 },
2509 ptr_type: struct {2502 ptr_type: struct {
2510 flags: packed struct {2503 flags: packed struct {
2511 is_allowzero: bool,2504 is_allowzero: bool,
...@@ -2608,7 +2601,6 @@ pub const Inst = struct {...@@ -2608,7 +2601,6 @@ pub const Inst = struct {
2608 node,2601 node,
2609 int,2602 int,
2610 float,2603 float,
2611 ptr_type_simple,
2612 ptr_type,2604 ptr_type,
2613 int_type,2605 int_type,
2614 bool_br,2606 bool_br,
...@@ -2869,6 +2861,7 @@ pub const Inst = struct {...@@ -2869,6 +2861,7 @@ pub const Inst = struct {
2869 /// 4. host_size: Ref // if `has_bit_range` flag is set2861 /// 4. host_size: Ref // if `has_bit_range` flag is set
2870 pub const PtrType = struct {2862 pub const PtrType = struct {
2871 elem_type: Ref,2863 elem_type: Ref,
2864 src_node: i32,
2872 };2865 };
28732866
2874 pub const ArrayTypeSentinel = struct {2867 pub const ArrayTypeSentinel = struct {
src/print_zir.zig+3-20
...@@ -233,6 +233,7 @@ const Writer = struct {...@@ -233,6 +233,7 @@ const Writer = struct {
233 .validate_struct_init_ty,233 .validate_struct_init_ty,
234 .make_ptr_const,234 .make_ptr_const,
235 .validate_deref,235 .validate_deref,
236 .overflow_arithmetic_ptr,
236 => try self.writeUnNode(stream, inst),237 => try self.writeUnNode(stream, inst),
237238
238 .ref,239 .ref,
...@@ -247,7 +248,6 @@ const Writer = struct {...@@ -247,7 +248,6 @@ const Writer = struct {
247248
248 .array_type_sentinel => try self.writeArrayTypeSentinel(stream, inst),249 .array_type_sentinel => try self.writeArrayTypeSentinel(stream, inst),
249 .param_type => try self.writeParamType(stream, inst),250 .param_type => try self.writeParamType(stream, inst),
250 .ptr_type_simple => try self.writePtrTypeSimple(stream, inst),
251 .ptr_type => try self.writePtrType(stream, inst),251 .ptr_type => try self.writePtrType(stream, inst),
252 .int => try self.writeInt(stream, inst),252 .int => try self.writeInt(stream, inst),
253 .int_big => try self.writeIntBig(stream, inst),253 .int_big => try self.writeIntBig(stream, inst),
...@@ -601,24 +601,6 @@ const Writer = struct {...@@ -601,24 +601,6 @@ const Writer = struct {
601 try stream.print(", {d})", .{inst_data.param_index});601 try stream.print(", {d})", .{inst_data.param_index});
602 }602 }
603603
604 fn writePtrTypeSimple(
605 self: *Writer,
606 stream: anytype,
607 inst: Zir.Inst.Index,
608 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {
609 const inst_data = self.code.instructions.items(.data)[inst].ptr_type_simple;
610 const str_allowzero = if (inst_data.is_allowzero) "allowzero, " else "";
611 const str_const = if (!inst_data.is_mutable) "const, " else "";
612 const str_volatile = if (inst_data.is_volatile) "volatile, " else "";
613 try self.writeInstRef(stream, inst_data.elem_type);
614 try stream.print(", {s}{s}{s}{s})", .{
615 str_allowzero,
616 str_const,
617 str_volatile,
618 @tagName(inst_data.size),
619 });
620 }
621
622 fn writePtrType(604 fn writePtrType(
623 self: *Writer,605 self: *Writer,
624 stream: anytype,606 stream: anytype,
...@@ -660,7 +642,8 @@ const Writer = struct {...@@ -660,7 +642,8 @@ const Writer = struct {
660 try self.writeInstRef(stream, @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]));642 try self.writeInstRef(stream, @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]));
661 try stream.writeAll(")");643 try stream.writeAll(")");
662 }644 }
663 try stream.writeAll(")");645 try stream.writeAll(") ");
646 try self.writeSrc(stream, LazySrcLoc.nodeOffset(extra.data.src_node));
664 }647 }
665648
666 fn writeInt(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {649 fn writeInt(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
test/cases/compile_errors/C_pointer_pointing_to_non_C_ABI_compatible_type_or_has_align_attr.zig created+14
...@@ -0,0 +1,14 @@
1const Foo = struct {};
2export fn a() void {
3 const T = [*c]Foo;
4 var t: T = undefined;
5 _ = t;
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :3:19: error: C pointers cannot point to non-C-ABI-compatible type 'tmp.Foo'
13// :3:19: note: only structs with packed or extern layout are extern compatible
14// :1:13: note: struct declared here
test/cases/compile_errors/C_pointer_to_anyopaque.zig created+11
...@@ -0,0 +1,11 @@
1export fn a() void {
2 var x: *anyopaque = undefined;
3 var y: [*c]anyopaque = x;
4 _ = y;
5}
6
7// error
8// backend=stage2
9// target=native
10//
11// :3:16: error: C pointers cannot point to opaque types
test/cases/compile_errors/c_pointer_to_void.zig+2-2
...@@ -7,5 +7,5 @@ export fn entry() void {...@@ -7,5 +7,5 @@ export fn entry() void {
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :1:1: error: C pointers cannot point to non-C-ABI-compatible type 'void'10// :2:16: error: C pointers cannot point to non-C-ABI-compatible type 'void'
11// :1:1: note: 'void' is a zero bit type; for C 'void' use 'anyopaque'11// :2:16: note: 'void' is a zero bit type; for C 'void' use 'anyopaque'
test/cases/compile_errors/container_init_with_non-type.zig+1-1
...@@ -7,4 +7,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(a)); }...@@ -7,4 +7,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(a)); }
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :2:15: error: expected type 'type', found 'i32'10// :2:11: error: expected type 'type', found 'i32'
test/cases/compile_errors/pointer_to_noreturn.zig created+8
...@@ -0,0 +1,8 @@
1fn a() *noreturn {}
2export fn entry() void { _ = a(); }
3
4// error
5// backend=stage2
6// target=native
7//
8// :1:9: error: pointer to noreturn not allowed
test/cases/compile_errors/slice_passed_as_array_init_type_with_elems.zig+2-2
...@@ -7,5 +7,5 @@ export fn entry() void {...@@ -7,5 +7,5 @@ export fn entry() void {
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :2:19: error: type '[]u8' does not support array initialization syntax10// :2:15: error: type '[]u8' does not support array initialization syntax
11// :2:19: note: inferred array length is specified with an underscore: '[_]u8'11// :2:15: note: inferred array length is specified with an underscore: '[_]u8'
test/cases/compile_errors/stage1/attempt_to_use_0_bit_type_in_extern_fn.zig created+17
...@@ -0,0 +1,17 @@
1extern fn foo(ptr: fn(*void) callconv(.C) void) void;
2
3export fn entry() void {
4 foo(bar);
5}
6
7fn bar(x: *void) callconv(.C) void { _ = x; }
8export fn entry2() void {
9 bar(&{});
10}
11
12// error
13// backend=stage1
14// target=native
15//
16// tmp.zig:1:23: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'
17// tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'
test/cases/compile_errors/stage1/issue_2687_coerce_from_undefined_array_pointer_to_slice.zig created+27
...@@ -0,0 +1,27 @@
1export fn foo1() void {
2 const a: *[1]u8 = undefined;
3 var b: []u8 = a;
4 _ = b;
5}
6export fn foo2() void {
7 comptime {
8 var a: *[1]u8 = undefined;
9 var b: []u8 = a;
10 _ = b;
11 }
12}
13export fn foo3() void {
14 comptime {
15 const a: *[1]u8 = undefined;
16 var b: []u8 = a;
17 _ = b;
18 }
19}
20
21// error
22// backend=stage1
23// target=native
24//
25// tmp.zig:3:19: error: use of undefined value here causes undefined behavior
26// tmp.zig:9:23: error: use of undefined value here causes undefined behavior
27// tmp.zig:16:23: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/obj/C_pointer_pointing_to_non_C_ABI_compatible_type_or_has_align_attr.zig deleted-12
...@@ -1,12 +0,0 @@
1const Foo = struct {};
2export fn a() void {
3 const T = [*c]Foo;
4 var t: T = undefined;
5 _ = t;
6}
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:3:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'
test/cases/compile_errors/stage1/obj/C_pointer_to_anyopaque.zig deleted-11
...@@ -1,11 +0,0 @@
1export fn a() void {
2 var x: *anyopaque = undefined;
3 var y: [*c]anyopaque = x;
4 _ = y;
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:3:16: error: C pointers cannot point to opaque types
test/cases/compile_errors/stage1/obj/attempt_to_use_0_bit_type_in_extern_fn.zig deleted-17
...@@ -1,17 +0,0 @@
1extern fn foo(ptr: fn(*void) callconv(.C) void) void;
2
3export fn entry() void {
4 foo(bar);
5}
6
7fn bar(x: *void) callconv(.C) void { _ = x; }
8export fn entry2() void {
9 bar(&{});
10}
11
12// error
13// backend=stage1
14// target=native
15//
16// tmp.zig:1:23: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'
17// tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'
test/cases/compile_errors/stage1/obj/issue_2687_coerce_from_undefined_array_pointer_to_slice.zig deleted-27
...@@ -1,27 +0,0 @@
1export fn foo1() void {
2 const a: *[1]u8 = undefined;
3 var b: []u8 = a;
4 _ = b;
5}
6export fn foo2() void {
7 comptime {
8 var a: *[1]u8 = undefined;
9 var b: []u8 = a;
10 _ = b;
11 }
12}
13export fn foo3() void {
14 comptime {
15 const a: *[1]u8 = undefined;
16 var b: []u8 = a;
17 _ = b;
18 }
19}
20
21// error
22// backend=stage1
23// target=native
24//
25// tmp.zig:3:19: error: use of undefined value here causes undefined behavior
26// tmp.zig:9:23: error: use of undefined value here causes undefined behavior
27// tmp.zig:16:23: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/obj/pointer_to_noreturn.zig deleted-8
...@@ -1,8 +0,0 @@
1fn a() *noreturn {}
2export fn entry() void { _ = a(); }
3
4// error
5// backend=stage1
6// target=native
7//
8// tmp.zig:1:9: error: pointer to noreturn not allowed
test/cases/compile_errors/stage1/obj/unknown_length_pointer_to_opaque.zig deleted-7
...@@ -1,7 +0,0 @@
1export const T = [*]opaque {};
2
3// error
4// backend=stage1
5// target=native
6//
7// tmp.zig:1:21: error: unknown-length pointer to opaque
test/cases/compile_errors/stage1/obj/using_an_unknown_len_ptr_type_instead_of_array.zig deleted-13
...@@ -1,13 +0,0 @@
1const resolutions = [*][*]const u8{
2 "[320 240 ]",
3 null,
4};
5comptime {
6 _ = resolutions;
7}
8
9// error
10// backend=stage1
11// target=native
12//
13// tmp.zig:1:21: error: expected array type or [_], found '[*][*]const u8'
test/cases/compile_errors/unknown_length_pointer_to_opaque.zig created+7
...@@ -0,0 +1,7 @@
1export const T = [*]opaque {};
2
3// error
4// backend=stage2
5// target=native
6//
7// :1:21: error: unknown-length pointer to opaque not allowed
test/cases/compile_errors/using_an_unknown_len_ptr_type_instead_of_array.zig created+13
...@@ -0,0 +1,13 @@
1const resolutions = [*][*]const u8{
2 "[320 240 ]",
3 null,
4};
5comptime {
6 _ = resolutions;
7}
8
9// error
10// backend=stage2
11// target=native
12//
13// :1:22: error: type '[*][*]const u8' does not support array initialization syntax