| author | |
| committer | |
| log | d72917320449f449bcdeb6a20d5a98b1dfb901d4 |
| tree | 04a1887e12b989d78813189e2e89ddfd620d0b9b |
| parent | 29815fe9de50be3b07e39cd02ccfcc801a54c455 |
22 files changed, 271 insertions(+), 221 deletions(-)
src/AstGen.zig+8-39| ... | ... | @@ -1347,7 +1347,7 @@ fn arrayInitExpr( |
| 1347 | 1347 | } |
| 1348 | 1348 | } |
| 1349 | 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 | 1351 | break :inst .{ |
| 1352 | 1352 | .array = array_type_inst, |
| 1353 | 1353 | .elem = .none, |
| ... | ... | @@ -2332,7 +2332,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner |
| 2332 | 2332 | .err_union_code, |
| 2333 | 2333 | .err_union_code_ptr, |
| 2334 | 2334 | .ptr_type, |
| 2335 | .ptr_type_simple, | |
| 2335 | .overflow_arithmetic_ptr, | |
| 2336 | 2336 | .enum_literal, |
| 2337 | 2337 | .merge_error_sets, |
| 2338 | 2338 | .error_union_type, |
| ... | ... | @@ -3110,24 +3110,6 @@ fn ptrType( |
| 3110 | 3110 | |
| 3111 | 3111 | const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type); |
| 3112 | 3112 | |
| 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 | 3113 | var sentinel_ref: Zir.Inst.Ref = .none; |
| 3132 | 3114 | var align_ref: Zir.Inst.Ref = .none; |
| 3133 | 3115 | var addrspace_ref: Zir.Inst.Ref = .none; |
| ... | ... | @@ -3160,7 +3142,10 @@ fn ptrType( |
| 3160 | 3142 | try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.PtrType).Struct.fields.len + |
| 3161 | 3143 | trailing_count); |
| 3162 | 3144 | |
| 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 | 3149 | if (sentinel_ref != .none) { |
| 3165 | 3150 | gz.astgen.extra.appendAssumeCapacity(@enumToInt(sentinel_ref)); |
| 3166 | 3151 | } |
| ... | ... | @@ -7588,15 +7573,7 @@ fn builtinCall( |
| 7588 | 7573 | .shl_with_overflow => { |
| 7589 | 7574 | const int_type = try typeExpr(gz, scope, params[0]); |
| 7590 | 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 = .{ | |
| 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 | } }); | |
| 7576 | const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]); | |
| 7600 | 7577 | const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]); |
| 7601 | 7578 | const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, params[2]); |
| 7602 | 7579 | const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]); |
| ... | ... | @@ -7987,15 +7964,7 @@ fn overflowArithmetic( |
| 7987 | 7964 | tag: Zir.Inst.Extended, |
| 7988 | 7965 | ) InnerError!Zir.Inst.Ref { |
| 7989 | 7966 | const int_type = try typeExpr(gz, scope, params[0]); |
| 7990 | const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{ | |
| 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 | } }); | |
| 7967 | const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]); | |
| 7999 | 7968 | const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]); |
| 8000 | 7969 | const rhs = try expr(gz, scope, .{ .ty = int_type }, params[2]); |
| 8001 | 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 | 2466 | |
| 2467 | 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 | } |
| 2471 | 2555 | |
| ... | ... | @@ -2739,6 +2823,24 @@ pub const LazySrcLoc = union(enum) { |
| 2739 | 2823 | /// The source location points to the operand of an unary expression. |
| 2740 | 2824 | /// The Decl is determined contextually. |
| 2741 | 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, | |
| 2742 | 2844 | |
| 2743 | 2845 | pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease; |
| 2744 | 2846 | |
| ... | ... | @@ -2803,6 +2905,12 @@ pub const LazySrcLoc = union(enum) { |
| 2803 | 2905 | .node_offset_array_type_sentinel, |
| 2804 | 2906 | .node_offset_array_type_elem, |
| 2805 | 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 | 2915 | .file_scope = decl.getFileScope(), |
| 2808 | 2916 | .parent_decl_node = decl.src_node, |
src/Sema.zig+43-48| ... | ... | @@ -768,7 +768,7 @@ fn analyzeBodyInner( |
| 768 | 768 | .optional_type => try sema.zirOptionalType(block, inst), |
| 769 | 769 | .param_type => try sema.zirParamType(block, inst), |
| 770 | 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 | 772 | .ref => try sema.zirRef(block, inst), |
| 773 | 773 | .ret_err_value_code => try sema.zirRetErrValueCode(inst), |
| 774 | 774 | .shr => try sema.zirShr(block, inst, .shr), |
| ... | ... | @@ -13835,22 +13835,21 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool { |
| 13835 | 13835 | }; |
| 13836 | 13836 | } |
| 13837 | 13837 | |
| 13838 | fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | |
| 13838 | fn zirOverflowArithmeticPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | |
| 13839 | 13839 | const tracy = trace(@src()); |
| 13840 | 13840 | defer tracy.end(); |
| 13841 | 13841 | |
| 13842 | const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple; | |
| 13843 | const elem_ty_src = sema.src; // TODO better source location | |
| 13844 | const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.elem_type); | |
| 13842 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | |
| 13843 | const elem_ty_src = inst_data.src(); | |
| 13844 | const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.operand); | |
| 13845 | 13845 | const ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 13846 | 13846 | .pointee_type = elem_type, |
| 13847 | 13847 | .@"addrspace" = .generic, |
| 13848 | .mutable = inst_data.is_mutable, | |
| 13849 | .@"allowzero" = inst_data.is_allowzero or inst_data.size == .C, | |
| 13850 | .@"volatile" = inst_data.is_volatile, | |
| 13851 | .size = inst_data.size, | |
| 13848 | .mutable = true, | |
| 13849 | .@"allowzero" = false, | |
| 13850 | .@"volatile" = false, | |
| 13851 | .size = .One, | |
| 13852 | 13852 | }); |
| 13853 | try sema.validatePtrTy(block, elem_ty_src, ty); | |
| 13854 | 13853 | return sema.addType(ty); |
| 13855 | 13854 | } |
| 13856 | 13855 | |
| ... | ... | @@ -13858,14 +13857,15 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13858 | 13857 | const tracy = trace(@src()); |
| 13859 | 13858 | defer tracy.end(); |
| 13860 | 13859 | |
| 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 | 13860 | const inst_data = sema.code.instructions.items(.data)[inst].ptr_type; |
| 13868 | 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 | 13869 | const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type); |
| 13870 | 13870 | const target = sema.mod.getTarget(); |
| 13871 | 13871 | |
| ... | ... | @@ -13880,8 +13880,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13880 | 13880 | const abi_align: u32 = if (inst_data.flags.has_align) blk: { |
| 13881 | 13881 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 13882 | 13882 | extra_i += 1; |
| 13883 | const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), src); | |
| 13884 | const val = try sema.resolveConstValue(block, src, coerced); | |
| 13883 | const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src); | |
| 13884 | const val = try sema.resolveConstValue(block, align_src, coerced); | |
| 13885 | 13885 | // Check if this happens to be the lazy alignment of our element type, in |
| 13886 | 13886 | // which case we can make this 0 without resolving it. |
| 13887 | 13887 | if (val.castTag(.lazy_align)) |payload| { |
| ... | ... | @@ -13889,7 +13889,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13889 | 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 | 13893 | break :blk @intCast(u32, abi_align); |
| 13894 | 13894 | } else 0; |
| 13895 | 13895 | |
| ... | ... | @@ -13914,7 +13914,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13914 | 13914 | } else 0; |
| 13915 | 13915 | |
| 13916 | 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 | } |
| 13919 | 13919 | |
| 13920 | 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 | 13924 | try sema.resolveTypeLayout(block, elem_ty_src, elem_ty); |
| 13925 | 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 | } | |
| 13942 | 13927 | |
| 13943 | fn validatePtrTy(sema: *Sema, block: *Block, elem_src: LazySrcLoc, ty: Type) CompileError!void { | |
| 13944 | const ptr_info = ty.ptrInfo().data; | |
| 13945 | const pointee_tag = ptr_info.pointee_type.zigTypeTag(); | |
| 13946 | if (pointee_tag == .NoReturn) { | |
| 13947 | return sema.fail(block, elem_src, "pointer to noreturn not allowed", .{}); | |
| 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; | |
| 13928 | if (elem_ty.zigTypeTag() == .NoReturn) { | |
| 13929 | return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{}); | |
| 13930 | } else if (inst_data.size == .Many and elem_ty.zigTypeTag() == .Opaque) { | |
| 13931 | return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{}); | |
| 13932 | } else if (inst_data.size == .C) { | |
| 13952 | 13933 | if (!(try sema.validateExternType(elem_ty, .other))) { |
| 13953 | 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 | 13936 | errdefer msg.destroy(sema.gpa); |
| 13956 | 13937 | |
| 13957 | 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); | |
| 13959 | 13940 | |
| 13960 | 13941 | try sema.addDeclaredHereNote(msg, elem_ty); |
| 13961 | 13942 | break :msg msg; |
| 13962 | 13943 | }; |
| 13963 | 13944 | return sema.failWithOwnedErrorMsg(block, msg); |
| 13964 | 13945 | } |
| 13965 | if (pointee_tag == .Opaque) { | |
| 13966 | return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{}); | |
| 13946 | if (elem_ty.zigTypeTag() == .Opaque) { | |
| 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 | } |
| 13970 | 13965 | |
| 13971 | 13966 | fn 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 | 534 | /// Obtains the return type of the in-scope function. |
| 535 | 535 | /// Uses the `node` union field. |
| 536 | 536 | ret_type, |
| 537 | /// Create a pointer type that does not have a sentinel, alignment, address space, or bit range specified. | |
| 538 | /// Uses the `ptr_type_simple` union field. | |
| 539 | ptr_type_simple, | |
| 537 | /// Create a pointer type for overflow arithmetic. | |
| 538 | /// TODO remove when doing https://github.com/ziglang/zig/issues/10248 | |
| 539 | overflow_arithmetic_ptr, | |
| 540 | 540 | /// Create a pointer type which can have a sentinel, alignment, address space, and/or bit range. |
| 541 | 541 | /// Uses the `ptr_type` union field. |
| 542 | 542 | ptr_type, |
| ... | ... | @@ -1121,7 +1121,7 @@ pub const Inst = struct { |
| 1121 | 1121 | .err_union_code, |
| 1122 | 1122 | .err_union_code_ptr, |
| 1123 | 1123 | .ptr_type, |
| 1124 | .ptr_type_simple, | |
| 1124 | .overflow_arithmetic_ptr, | |
| 1125 | 1125 | .ensure_err_payload_void, |
| 1126 | 1126 | .enum_literal, |
| 1127 | 1127 | .merge_error_sets, |
| ... | ... | @@ -1417,7 +1417,7 @@ pub const Inst = struct { |
| 1417 | 1417 | .err_union_code, |
| 1418 | 1418 | .err_union_code_ptr, |
| 1419 | 1419 | .ptr_type, |
| 1420 | .ptr_type_simple, | |
| 1420 | .overflow_arithmetic_ptr, | |
| 1421 | 1421 | .enum_literal, |
| 1422 | 1422 | .merge_error_sets, |
| 1423 | 1423 | .error_union_type, |
| ... | ... | @@ -1659,7 +1659,7 @@ pub const Inst = struct { |
| 1659 | 1659 | .ret_err_value_code = .str_tok, |
| 1660 | 1660 | .ret_ptr = .node, |
| 1661 | 1661 | .ret_type = .node, |
| 1662 | .ptr_type_simple = .ptr_type_simple, | |
| 1662 | .overflow_arithmetic_ptr = .un_node, | |
| 1663 | 1663 | .ptr_type = .ptr_type, |
| 1664 | 1664 | .slice_start = .pl_node, |
| 1665 | 1665 | .slice_end = .pl_node, |
| ... | ... | @@ -2499,13 +2499,6 @@ pub const Inst = struct { |
| 2499 | 2499 | node: i32, |
| 2500 | 2500 | int: u64, |
| 2501 | 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 | 2502 | ptr_type: struct { |
| 2510 | 2503 | flags: packed struct { |
| 2511 | 2504 | is_allowzero: bool, |
| ... | ... | @@ -2608,7 +2601,6 @@ pub const Inst = struct { |
| 2608 | 2601 | node, |
| 2609 | 2602 | int, |
| 2610 | 2603 | float, |
| 2611 | ptr_type_simple, | |
| 2612 | 2604 | ptr_type, |
| 2613 | 2605 | int_type, |
| 2614 | 2606 | bool_br, |
| ... | ... | @@ -2869,6 +2861,7 @@ pub const Inst = struct { |
| 2869 | 2861 | /// 4. host_size: Ref // if `has_bit_range` flag is set |
| 2870 | 2862 | pub const PtrType = struct { |
| 2871 | 2863 | elem_type: Ref, |
| 2864 | src_node: i32, | |
| 2872 | 2865 | }; |
| 2873 | 2866 | |
| 2874 | 2867 | pub const ArrayTypeSentinel = struct { |
src/print_zir.zig+3-20| ... | ... | @@ -233,6 +233,7 @@ const Writer = struct { |
| 233 | 233 | .validate_struct_init_ty, |
| 234 | 234 | .make_ptr_const, |
| 235 | 235 | .validate_deref, |
| 236 | .overflow_arithmetic_ptr, | |
| 236 | 237 | => try self.writeUnNode(stream, inst), |
| 237 | 238 | |
| 238 | 239 | .ref, |
| ... | ... | @@ -247,7 +248,6 @@ const Writer = struct { |
| 247 | 248 | |
| 248 | 249 | .array_type_sentinel => try self.writeArrayTypeSentinel(stream, inst), |
| 249 | 250 | .param_type => try self.writeParamType(stream, inst), |
| 250 | .ptr_type_simple => try self.writePtrTypeSimple(stream, inst), | |
| 251 | 251 | .ptr_type => try self.writePtrType(stream, inst), |
| 252 | 252 | .int => try self.writeInt(stream, inst), |
| 253 | 253 | .int_big => try self.writeIntBig(stream, inst), |
| ... | ... | @@ -601,24 +601,6 @@ const Writer = struct { |
| 601 | 601 | try stream.print(", {d})", .{inst_data.param_index}); |
| 602 | 602 | } |
| 603 | 603 | |
| 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 | 604 | fn writePtrType( |
| 623 | 605 | self: *Writer, |
| 624 | 606 | stream: anytype, |
| ... | ... | @@ -660,7 +642,8 @@ const Writer = struct { |
| 660 | 642 | try self.writeInstRef(stream, @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index])); |
| 661 | 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 | } |
| 665 | 648 | |
| 666 | 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 @@ |
| 1 | const Foo = struct {}; | |
| 2 | export 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 @@ |
| 1 | export 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 | 7 | // backend=stage2 |
| 8 | 8 | // target=native |
| 9 | 9 | // |
| 10 | // :1:1: 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' | |
| 10 | // :2:16: error: C pointers cannot point to non-C-ABI-compatible type 'void' | |
| 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 | 7 | // backend=stage2 |
| 8 | 8 | // 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 @@ |
| 1 | fn a() *noreturn {} | |
| 2 | export 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 | 7 | // backend=stage2 |
| 8 | 8 | // target=native |
| 9 | 9 | // |
| 10 | // :2:19: error: type '[]u8' does not support array initialization syntax | |
| 11 | // :2:19: note: inferred array length is specified with an underscore: '[_]u8' | |
| 10 | // :2:15: error: type '[]u8' does not support array initialization syntax | |
| 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 @@ |
| 1 | extern fn foo(ptr: fn(*void) callconv(.C) void) void; | |
| 2 | ||
| 3 | export fn entry() void { | |
| 4 | foo(bar); | |
| 5 | } | |
| 6 | ||
| 7 | fn bar(x: *void) callconv(.C) void { _ = x; } | |
| 8 | export 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 @@ |
| 1 | export fn foo1() void { | |
| 2 | const a: *[1]u8 = undefined; | |
| 3 | var b: []u8 = a; | |
| 4 | _ = b; | |
| 5 | } | |
| 6 | export fn foo2() void { | |
| 7 | comptime { | |
| 8 | var a: *[1]u8 = undefined; | |
| 9 | var b: []u8 = a; | |
| 10 | _ = b; | |
| 11 | } | |
| 12 | } | |
| 13 | export 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 @@ |
| 1 | const Foo = struct {}; | |
| 2 | export 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 @@ |
| 1 | export 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 @@ |
| 1 | extern fn foo(ptr: fn(*void) callconv(.C) void) void; | |
| 2 | ||
| 3 | export fn entry() void { | |
| 4 | foo(bar); | |
| 5 | } | |
| 6 | ||
| 7 | fn bar(x: *void) callconv(.C) void { _ = x; } | |
| 8 | export 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 @@ |
| 1 | export fn foo1() void { | |
| 2 | const a: *[1]u8 = undefined; | |
| 3 | var b: []u8 = a; | |
| 4 | _ = b; | |
| 5 | } | |
| 6 | export fn foo2() void { | |
| 7 | comptime { | |
| 8 | var a: *[1]u8 = undefined; | |
| 9 | var b: []u8 = a; | |
| 10 | _ = b; | |
| 11 | } | |
| 12 | } | |
| 13 | export 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 @@ |
| 1 | fn a() *noreturn {} | |
| 2 | export 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 @@ |
| 1 | export 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 @@ |
| 1 | const resolutions = [*][*]const u8{ | |
| 2 | "[320 240 ]", | |
| 3 | null, | |
| 4 | }; | |
| 5 | comptime { | |
| 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 @@ |
| 1 | export 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 @@ |
| 1 | const resolutions = [*][*]const u8{ | |
| 2 | "[320 240 ]", | |
| 3 | null, | |
| 4 | }; | |
| 5 | comptime { | |
| 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 |