| ... | ... | @@ -126,6 +126,7 @@ const crash_report = @import("crash_report.zig"); |
| 126 | 126 | const build_options = @import("build_options"); |
| 127 | 127 | const Compilation = @import("Compilation.zig"); |
| 128 | 128 | const InternPool = @import("InternPool.zig"); |
| 129 | const Alignment = InternPool.Alignment; |
| 129 | 130 | |
| 130 | 131 | pub const default_branch_quota = 1000; |
| 131 | 132 | pub const default_reference_trace_len = 2; |
| ... | ... | @@ -708,7 +709,7 @@ pub const Block = struct { |
| 708 | 709 | } |
| 709 | 710 | |
| 710 | 711 | /// `alignment` value of 0 means to use ABI alignment. |
| 711 | | pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value, alignment: u64) !Decl.Index { |
| 712 | pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value, alignment: Alignment) !Decl.Index { |
| 712 | 713 | const sema = wad.block.sema; |
| 713 | 714 | // Do this ahead of time because `createAnonymousDecl` depends on calling |
| 714 | 715 | // `type.hasRuntimeBits()`. |
| ... | ... | @@ -718,8 +719,7 @@ pub const Block = struct { |
| 718 | 719 | .val = val, |
| 719 | 720 | }); |
| 720 | 721 | const new_decl = sema.mod.declPtr(new_decl_index); |
| 721 | | // TODO: migrate Decl alignment to use `InternPool.Alignment` |
| 722 | | new_decl.@"align" = @intCast(u32, alignment); |
| 722 | new_decl.alignment = alignment; |
| 723 | 723 | errdefer sema.mod.abortAnonDecl(new_decl_index); |
| 724 | 724 | wad.finished = true; |
| 725 | 725 | try sema.mod.finalizeAnonDecl(new_decl_index); |
| ... | ... | @@ -1847,7 +1847,10 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) |
| 1847 | 1847 | |
| 1848 | 1848 | // var addrs: [err_return_trace_addr_count]usize = undefined; |
| 1849 | 1849 | const err_return_trace_addr_count = 32; |
| 1850 | | const addr_arr_ty = try Type.array(sema.arena, err_return_trace_addr_count, null, Type.usize, mod); |
| 1850 | const addr_arr_ty = try mod.arrayType(.{ |
| 1851 | .len = err_return_trace_addr_count, |
| 1852 | .child = .usize_type, |
| 1853 | }); |
| 1851 | 1854 | const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty)); |
| 1852 | 1855 | |
| 1853 | 1856 | // var st: StackTrace = undefined; |
| ... | ... | @@ -2192,9 +2195,9 @@ fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool. |
| 2192 | 2195 | .Array => return ip.stringEqlSlice(field_name, "len"), |
| 2193 | 2196 | .Pointer => { |
| 2194 | 2197 | const ptr_info = ty.ptrInfo(mod); |
| 2195 | | if (ptr_info.size == .Slice) { |
| 2198 | if (ptr_info.flags.size == .Slice) { |
| 2196 | 2199 | return ip.stringEqlSlice(field_name, "ptr") or ip.stringEqlSlice(field_name, "len"); |
| 2197 | | } else if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) { |
| 2200 | } else if (ptr_info.child.toType().zigTypeTag(mod) == .Array) { |
| 2198 | 2201 | return ip.stringEqlSlice(field_name, "len"); |
| 2199 | 2202 | } else return false; |
| 2200 | 2203 | }, |
| ... | ... | @@ -2408,11 +2411,11 @@ fn analyzeAsAlign( |
| 2408 | 2411 | block: *Block, |
| 2409 | 2412 | src: LazySrcLoc, |
| 2410 | 2413 | air_ref: Air.Inst.Ref, |
| 2411 | | ) !u32 { |
| 2414 | ) !Alignment { |
| 2412 | 2415 | const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty, "alignment must be comptime-known"); |
| 2413 | | const alignment = @intCast(u32, alignment_big); // We coerce to u16 in the prev line. |
| 2416 | const alignment = @intCast(u32, alignment_big); // We coerce to u29 in the prev line. |
| 2414 | 2417 | try sema.validateAlign(block, src, alignment); |
| 2415 | | return alignment; |
| 2418 | return Alignment.fromNonzeroByteUnits(alignment); |
| 2416 | 2419 | } |
| 2417 | 2420 | |
| 2418 | 2421 | fn validateAlign( |
| ... | ... | @@ -2434,7 +2437,7 @@ pub fn resolveAlign( |
| 2434 | 2437 | block: *Block, |
| 2435 | 2438 | src: LazySrcLoc, |
| 2436 | 2439 | zir_ref: Zir.Inst.Ref, |
| 2437 | | ) !u32 { |
| 2440 | ) !Alignment { |
| 2438 | 2441 | const air_ref = try sema.resolveInst(zir_ref); |
| 2439 | 2442 | return sema.analyzeAsAlign(block, src, air_ref); |
| 2440 | 2443 | } |
| ... | ... | @@ -2550,7 +2553,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 2550 | 2553 | const decl_index = try anon_decl.finish( |
| 2551 | 2554 | pointee_ty, |
| 2552 | 2555 | (try mod.intern(.{ .undef = pointee_ty.toIntern() })).toValue(), |
| 2553 | | alignment.toByteUnits(0), |
| 2556 | alignment, |
| 2554 | 2557 | ); |
| 2555 | 2558 | sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.decl_index = decl_index; |
| 2556 | 2559 | if (alignment != .none) { |
| ... | ... | @@ -2626,9 +2629,9 @@ fn coerceResultPtr( |
| 2626 | 2629 | } |
| 2627 | 2630 | } |
| 2628 | 2631 | |
| 2629 | | const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 2630 | | .pointee_type = pointee_ty, |
| 2631 | | .@"addrspace" = addr_space, |
| 2632 | const ptr_ty = try mod.ptrType(.{ |
| 2633 | .child = pointee_ty.toIntern(), |
| 2634 | .flags = .{ .address_space = addr_space }, |
| 2632 | 2635 | }); |
| 2633 | 2636 | |
| 2634 | 2637 | var new_ptr = ptr; |
| ... | ... | @@ -2656,9 +2659,9 @@ fn coerceResultPtr( |
| 2656 | 2659 | // Array coerced to Vector where element size is not equal but coercible. |
| 2657 | 2660 | .aggregate_init => { |
| 2658 | 2661 | const ty_pl = air_datas[trash_inst].ty_pl; |
| 2659 | | const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 2660 | | .pointee_type = try sema.analyzeAsType(block, src, ty_pl.ty), |
| 2661 | | .@"addrspace" = addr_space, |
| 2662 | const ptr_operand_ty = try mod.ptrType(.{ |
| 2663 | .child = (try sema.analyzeAsType(block, src, ty_pl.ty)).toIntern(), |
| 2664 | .flags = .{ .address_space = addr_space }, |
| 2662 | 2665 | }); |
| 2663 | 2666 | |
| 2664 | 2667 | if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| { |
| ... | ... | @@ -2670,9 +2673,9 @@ fn coerceResultPtr( |
| 2670 | 2673 | .bitcast => { |
| 2671 | 2674 | const ty_op = air_datas[trash_inst].ty_op; |
| 2672 | 2675 | const operand_ty = sema.typeOf(ty_op.operand); |
| 2673 | | const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 2674 | | .pointee_type = operand_ty, |
| 2675 | | .@"addrspace" = addr_space, |
| 2676 | const ptr_operand_ty = try mod.ptrType(.{ |
| 2677 | .child = operand_ty.toIntern(), |
| 2678 | .flags = .{ .address_space = addr_space }, |
| 2676 | 2679 | }); |
| 2677 | 2680 | if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| { |
| 2678 | 2681 | new_ptr = try sema.addConstant(ptr_operand_ty, try mod.getCoerced(ptr_val, ptr_operand_ty)); |
| ... | ... | @@ -3382,13 +3385,13 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 3382 | 3385 | |
| 3383 | 3386 | if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) { |
| 3384 | 3387 | const fn_ret_ty = try sema.resolveTypeFields(sema.fn_ret_ty); |
| 3385 | | return sema.analyzeComptimeAlloc(block, fn_ret_ty, 0); |
| 3388 | return sema.analyzeComptimeAlloc(block, fn_ret_ty, .none); |
| 3386 | 3389 | } |
| 3387 | 3390 | |
| 3388 | 3391 | const target = sema.mod.getTarget(); |
| 3389 | | const ptr_type = try Type.ptr(sema.arena, sema.mod, .{ |
| 3390 | | .pointee_type = sema.fn_ret_ty, |
| 3391 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 3392 | const ptr_type = try sema.mod.ptrType(.{ |
| 3393 | .child = sema.fn_ret_ty.toIntern(), |
| 3394 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 3392 | 3395 | }); |
| 3393 | 3396 | |
| 3394 | 3397 | if (block.inlining != null) { |
| ... | ... | @@ -3560,12 +3563,12 @@ fn zirAllocExtended( |
| 3560 | 3563 | break :blk try sema.resolveType(block, ty_src, type_ref); |
| 3561 | 3564 | } else undefined; |
| 3562 | 3565 | |
| 3563 | | const alignment: u32 = if (small.has_align) blk: { |
| 3566 | const alignment = if (small.has_align) blk: { |
| 3564 | 3567 | const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 3565 | 3568 | extra_index += 1; |
| 3566 | 3569 | const alignment = try sema.resolveAlign(block, align_src, align_ref); |
| 3567 | 3570 | break :blk alignment; |
| 3568 | | } else 0; |
| 3571 | } else .none; |
| 3569 | 3572 | |
| 3570 | 3573 | if (block.is_comptime or small.is_comptime) { |
| 3571 | 3574 | if (small.has_type) { |
| ... | ... | @@ -3575,7 +3578,7 @@ fn zirAllocExtended( |
| 3575 | 3578 | .tag = .inferred_alloc_comptime, |
| 3576 | 3579 | .data = .{ .inferred_alloc_comptime = .{ |
| 3577 | 3580 | .decl_index = undefined, |
| 3578 | | .alignment = InternPool.Alignment.fromByteUnits(alignment), |
| 3581 | .alignment = alignment, |
| 3579 | 3582 | .is_const = small.is_const, |
| 3580 | 3583 | } }, |
| 3581 | 3584 | }); |
| ... | ... | @@ -3589,10 +3592,12 @@ fn zirAllocExtended( |
| 3589 | 3592 | } |
| 3590 | 3593 | const target = sema.mod.getTarget(); |
| 3591 | 3594 | try sema.resolveTypeLayout(var_ty); |
| 3592 | | const ptr_type = try Type.ptr(sema.arena, sema.mod, .{ |
| 3593 | | .pointee_type = var_ty, |
| 3594 | | .@"align" = alignment, |
| 3595 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 3595 | const ptr_type = try sema.mod.ptrType(.{ |
| 3596 | .child = var_ty.toIntern(), |
| 3597 | .flags = .{ |
| 3598 | .alignment = alignment, |
| 3599 | .address_space = target_util.defaultAddressSpace(target, .local), |
| 3600 | }, |
| 3596 | 3601 | }); |
| 3597 | 3602 | return block.addTy(.alloc, ptr_type); |
| 3598 | 3603 | } |
| ... | ... | @@ -3600,7 +3605,7 @@ fn zirAllocExtended( |
| 3600 | 3605 | const result_index = try block.addInstAsIndex(.{ |
| 3601 | 3606 | .tag = .inferred_alloc, |
| 3602 | 3607 | .data = .{ .inferred_alloc = .{ |
| 3603 | | .alignment = InternPool.Alignment.fromByteUnits(alignment), |
| 3608 | .alignment = alignment, |
| 3604 | 3609 | .is_const = small.is_const, |
| 3605 | 3610 | } }, |
| 3606 | 3611 | }); |
| ... | ... | @@ -3615,7 +3620,7 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 3615 | 3620 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 3616 | 3621 | const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node }; |
| 3617 | 3622 | const var_ty = try sema.resolveType(block, ty_src, inst_data.operand); |
| 3618 | | return sema.analyzeComptimeAlloc(block, var_ty, 0); |
| 3623 | return sema.analyzeComptimeAlloc(block, var_ty, .none); |
| 3619 | 3624 | } |
| 3620 | 3625 | |
| 3621 | 3626 | fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -3625,7 +3630,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3625 | 3630 | const alloc_ty = sema.typeOf(alloc); |
| 3626 | 3631 | |
| 3627 | 3632 | var ptr_info = alloc_ty.ptrInfo(mod); |
| 3628 | | const elem_ty = ptr_info.pointee_type; |
| 3633 | const elem_ty = ptr_info.child.toType(); |
| 3629 | 3634 | |
| 3630 | 3635 | // Detect if all stores to an `.alloc` were comptime-known. |
| 3631 | 3636 | ct: { |
| ... | ... | @@ -3669,11 +3674,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3669 | 3674 | |
| 3670 | 3675 | var anon_decl = try block.startAnonDecl(); |
| 3671 | 3676 | defer anon_decl.deinit(); |
| 3672 | | return sema.analyzeDeclRef(try anon_decl.finish( |
| 3673 | | elem_ty, |
| 3674 | | store_val, |
| 3675 | | ptr_info.@"align", |
| 3676 | | )); |
| 3677 | return sema.analyzeDeclRef(try anon_decl.finish(elem_ty, store_val, ptr_info.flags.alignment)); |
| 3677 | 3678 | } |
| 3678 | 3679 | |
| 3679 | 3680 | return sema.makePtrConst(block, alloc); |
| ... | ... | @@ -3684,8 +3685,8 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai |
| 3684 | 3685 | const alloc_ty = sema.typeOf(alloc); |
| 3685 | 3686 | |
| 3686 | 3687 | var ptr_info = alloc_ty.ptrInfo(mod); |
| 3687 | | ptr_info.mutable = false; |
| 3688 | | const const_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info); |
| 3688 | ptr_info.flags.is_const = true; |
| 3689 | const const_ptr_ty = try mod.ptrType(ptr_info); |
| 3689 | 3690 | |
| 3690 | 3691 | // Detect if a comptime value simply needs to have its type changed. |
| 3691 | 3692 | if (try sema.resolveMaybeUndefVal(alloc)) |val| { |
| ... | ... | @@ -3724,12 +3725,12 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 3724 | 3725 | const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node }; |
| 3725 | 3726 | const var_ty = try sema.resolveType(block, ty_src, inst_data.operand); |
| 3726 | 3727 | if (block.is_comptime) { |
| 3727 | | return sema.analyzeComptimeAlloc(block, var_ty, 0); |
| 3728 | return sema.analyzeComptimeAlloc(block, var_ty, .none); |
| 3728 | 3729 | } |
| 3729 | 3730 | const target = sema.mod.getTarget(); |
| 3730 | | const ptr_type = try Type.ptr(sema.arena, sema.mod, .{ |
| 3731 | | .pointee_type = var_ty, |
| 3732 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 3731 | const ptr_type = try sema.mod.ptrType(.{ |
| 3732 | .child = var_ty.toIntern(), |
| 3733 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 3733 | 3734 | }); |
| 3734 | 3735 | try sema.queueFullTypeResolution(var_ty); |
| 3735 | 3736 | return block.addTy(.alloc, ptr_type); |
| ... | ... | @@ -3743,13 +3744,13 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 3743 | 3744 | const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node }; |
| 3744 | 3745 | const var_ty = try sema.resolveType(block, ty_src, inst_data.operand); |
| 3745 | 3746 | if (block.is_comptime) { |
| 3746 | | return sema.analyzeComptimeAlloc(block, var_ty, 0); |
| 3747 | return sema.analyzeComptimeAlloc(block, var_ty, .none); |
| 3747 | 3748 | } |
| 3748 | 3749 | try sema.validateVarType(block, ty_src, var_ty, false); |
| 3749 | 3750 | const target = sema.mod.getTarget(); |
| 3750 | | const ptr_type = try Type.ptr(sema.arena, sema.mod, .{ |
| 3751 | | .pointee_type = var_ty, |
| 3752 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 3751 | const ptr_type = try sema.mod.ptrType(.{ |
| 3752 | .child = var_ty.toIntern(), |
| 3753 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 3753 | 3754 | }); |
| 3754 | 3755 | try sema.queueFullTypeResolution(var_ty); |
| 3755 | 3756 | return block.addTy(.alloc, ptr_type); |
| ... | ... | @@ -3915,11 +3916,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3915 | 3916 | const new_decl_index = d: { |
| 3916 | 3917 | var anon_decl = try block.startAnonDecl(); |
| 3917 | 3918 | defer anon_decl.deinit(); |
| 3918 | | const new_decl_index = try anon_decl.finish( |
| 3919 | | final_elem_ty, |
| 3920 | | store_val, |
| 3921 | | ia1.alignment.toByteUnits(0), |
| 3922 | | ); |
| 3919 | const new_decl_index = try anon_decl.finish(final_elem_ty, store_val, ia1.alignment); |
| 3923 | 3920 | break :d new_decl_index; |
| 3924 | 3921 | }; |
| 3925 | 3922 | try mod.declareDeclDependency(sema.owner_decl_index, new_decl_index); |
| ... | ... | @@ -5143,11 +5140,7 @@ fn storeToInferredAllocComptime( |
| 5143 | 5140 | if (operand_val.getVariable(sema.mod) != null) break :store; |
| 5144 | 5141 | var anon_decl = try block.startAnonDecl(); |
| 5145 | 5142 | defer anon_decl.deinit(); |
| 5146 | | iac.decl_index = try anon_decl.finish( |
| 5147 | | operand_ty, |
| 5148 | | operand_val, |
| 5149 | | iac.alignment.toByteUnits(0), |
| 5150 | | ); |
| 5143 | iac.decl_index = try anon_decl.finish(operand_ty, operand_val, iac.alignment); |
| 5151 | 5144 | try sema.comptime_mutable_decls.append(iac.decl_index); |
| 5152 | 5145 | return; |
| 5153 | 5146 | } |
| ... | ... | @@ -5228,8 +5221,8 @@ fn addStrLit(sema: *Sema, block: *Block, bytes: []const u8) CompileError!Air.Ins |
| 5228 | 5221 | const duped_bytes = try sema.arena.dupe(u8, bytes); |
| 5229 | 5222 | const ty = try mod.arrayType(.{ |
| 5230 | 5223 | .len = bytes.len, |
| 5231 | | .child = .u8_type, |
| 5232 | 5224 | .sentinel = .zero_u8, |
| 5225 | .child = .u8_type, |
| 5233 | 5226 | }); |
| 5234 | 5227 | const val = try mod.intern(.{ .aggregate = .{ |
| 5235 | 5228 | .ty = ty.toIntern(), |
| ... | ... | @@ -5840,11 +5833,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 5840 | 5833 | const decl_index = if (operand.val.getFunction(sema.mod)) |function| function.owner_decl else blk: { |
| 5841 | 5834 | var anon_decl = try block.startAnonDecl(); |
| 5842 | 5835 | defer anon_decl.deinit(); |
| 5843 | | break :blk try anon_decl.finish( |
| 5844 | | operand.ty, |
| 5845 | | operand.val, |
| 5846 | | 0, |
| 5847 | | ); |
| 5836 | break :blk try anon_decl.finish(operand.ty, operand.val, .none); |
| 5848 | 5837 | }; |
| 5849 | 5838 | try sema.analyzeExport(block, src, options, decl_index); |
| 5850 | 5839 | } |
| ... | ... | @@ -5929,9 +5918,9 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 5929 | 5918 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 5930 | 5919 | const src = LazySrcLoc.nodeOffset(extra.node); |
| 5931 | 5920 | const alignment = try sema.resolveAlign(block, operand_src, extra.operand); |
| 5932 | | if (alignment > 256) { |
| 5921 | if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) { |
| 5933 | 5922 | return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{ |
| 5934 | | alignment, |
| 5923 | alignment.toByteUnitsOptional().?, |
| 5935 | 5924 | }); |
| 5936 | 5925 | } |
| 5937 | 5926 | const func_index = sema.func_index.unwrap() orelse |
| ... | ... | @@ -6566,8 +6555,8 @@ fn checkCallArgumentCount( |
| 6566 | 6555 | .Fn => break :func_ty callee_ty, |
| 6567 | 6556 | .Pointer => { |
| 6568 | 6557 | const ptr_info = callee_ty.ptrInfo(mod); |
| 6569 | | if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) { |
| 6570 | | break :func_ty ptr_info.pointee_type; |
| 6558 | if (ptr_info.flags.size == .One and ptr_info.child.toType().zigTypeTag(mod) == .Fn) { |
| 6559 | break :func_ty ptr_info.child.toType(); |
| 6571 | 6560 | } |
| 6572 | 6561 | }, |
| 6573 | 6562 | .Optional => { |
| ... | ... | @@ -6638,8 +6627,8 @@ fn callBuiltin( |
| 6638 | 6627 | .Fn => break :func_ty callee_ty, |
| 6639 | 6628 | .Pointer => { |
| 6640 | 6629 | const ptr_info = callee_ty.ptrInfo(mod); |
| 6641 | | if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) { |
| 6642 | | break :func_ty ptr_info.pointee_type; |
| 6630 | if (ptr_info.flags.size == .One and ptr_info.child.toType().zigTypeTag(mod) == .Fn) { |
| 6631 | break :func_ty ptr_info.child.toType(); |
| 6643 | 6632 | } |
| 6644 | 6633 | }, |
| 6645 | 6634 | else => {}, |
| ... | ... | @@ -7877,7 +7866,7 @@ fn resolveGenericInstantiationType( |
| 7877 | 7866 | .ty = new_decl.ty.toIntern(), |
| 7878 | 7867 | .index = new_func, |
| 7879 | 7868 | } })).toValue(); |
| 7880 | | new_decl.@"align" = 0; |
| 7869 | new_decl.alignment = .none; |
| 7881 | 7870 | new_decl.has_tv = true; |
| 7882 | 7871 | new_decl.owns_tv = true; |
| 7883 | 7872 | new_decl.analysis = .complete; |
| ... | ... | @@ -7952,7 +7941,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 7952 | 7941 | } else if (child_type.zigTypeTag(mod) == .Null) { |
| 7953 | 7942 | return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(mod)}); |
| 7954 | 7943 | } |
| 7955 | | const opt_type = try Type.optional(sema.arena, child_type, mod); |
| 7944 | const opt_type = try mod.optionalType(child_type.toIntern()); |
| 7956 | 7945 | |
| 7957 | 7946 | return sema.addType(opt_type); |
| 7958 | 7947 | } |
| ... | ... | @@ -7998,7 +7987,10 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 7998 | 7987 | const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, "array length must be comptime-known"); |
| 7999 | 7988 | const elem_type = try sema.resolveType(block, elem_src, extra.rhs); |
| 8000 | 7989 | try sema.validateArrayElemType(block, elem_type, elem_src); |
| 8001 | | const array_ty = try Type.array(sema.arena, len, null, elem_type, sema.mod); |
| 7990 | const array_ty = try sema.mod.arrayType(.{ |
| 7991 | .len = len, |
| 7992 | .child = elem_type.toIntern(), |
| 7993 | }); |
| 8002 | 7994 | |
| 8003 | 7995 | return sema.addType(array_ty); |
| 8004 | 7996 | } |
| ... | ... | @@ -8018,7 +8010,11 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 8018 | 8010 | const uncasted_sentinel = try sema.resolveInst(extra.sentinel); |
| 8019 | 8011 | const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src); |
| 8020 | 8012 | const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel, "array sentinel value must be comptime-known"); |
| 8021 | | const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type, sema.mod); |
| 8013 | const array_ty = try sema.mod.arrayType(.{ |
| 8014 | .len = len, |
| 8015 | .sentinel = sentinel_val.toIntern(), |
| 8016 | .child = elem_type.toIntern(), |
| 8017 | }); |
| 8022 | 8018 | |
| 8023 | 8019 | return sema.addType(array_ty); |
| 8024 | 8020 | } |
| ... | ... | @@ -8393,10 +8389,12 @@ fn analyzeOptionalPayloadPtr( |
| 8393 | 8389 | } |
| 8394 | 8390 | |
| 8395 | 8391 | const child_type = opt_type.optionalChild(mod); |
| 8396 | | const child_pointer = try Type.ptr(sema.arena, mod, .{ |
| 8397 | | .pointee_type = child_type, |
| 8398 | | .mutable = !optional_ptr_ty.isConstPtr(mod), |
| 8399 | | .@"addrspace" = optional_ptr_ty.ptrAddressSpace(mod), |
| 8392 | const child_pointer = try mod.ptrType(.{ |
| 8393 | .child = child_type.toIntern(), |
| 8394 | .flags = .{ |
| 8395 | .is_const = optional_ptr_ty.isConstPtr(mod), |
| 8396 | .address_space = optional_ptr_ty.ptrAddressSpace(mod), |
| 8397 | }, |
| 8400 | 8398 | }); |
| 8401 | 8399 | |
| 8402 | 8400 | if (try sema.resolveDefinedValue(block, src, optional_ptr)) |ptr_val| { |
| ... | ... | @@ -8460,14 +8458,15 @@ fn zirOptionalPayload( |
| 8460 | 8458 | // TODO https://github.com/ziglang/zig/issues/6597 |
| 8461 | 8459 | if (true) break :t operand_ty; |
| 8462 | 8460 | const ptr_info = operand_ty.ptrInfo(mod); |
| 8463 | | break :t try Type.ptr(sema.arena, mod, .{ |
| 8464 | | .pointee_type = ptr_info.pointee_type, |
| 8465 | | .@"align" = ptr_info.@"align", |
| 8466 | | .@"addrspace" = ptr_info.@"addrspace", |
| 8467 | | .mutable = ptr_info.mutable, |
| 8468 | | .@"allowzero" = ptr_info.@"allowzero", |
| 8469 | | .@"volatile" = ptr_info.@"volatile", |
| 8470 | | .size = .One, |
| 8461 | break :t try mod.ptrType(.{ |
| 8462 | .child = ptr_info.child, |
| 8463 | .flags = .{ |
| 8464 | .alignment = ptr_info.flags.alignment, |
| 8465 | .is_const = ptr_info.flags.is_const, |
| 8466 | .is_volatile = ptr_info.flags.is_volatile, |
| 8467 | .is_allowzero = ptr_info.flags.is_allowzero, |
| 8468 | .address_space = ptr_info.flags.address_space, |
| 8469 | }, |
| 8471 | 8470 | }); |
| 8472 | 8471 | }, |
| 8473 | 8472 | else => return sema.failWithExpectedOptionalType(block, src, operand_ty), |
| ... | ... | @@ -8580,10 +8579,12 @@ fn analyzeErrUnionPayloadPtr( |
| 8580 | 8579 | |
| 8581 | 8580 | const err_union_ty = operand_ty.childType(mod); |
| 8582 | 8581 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 8583 | | const operand_pointer_ty = try Type.ptr(sema.arena, mod, .{ |
| 8584 | | .pointee_type = payload_ty, |
| 8585 | | .mutable = !operand_ty.isConstPtr(mod), |
| 8586 | | .@"addrspace" = operand_ty.ptrAddressSpace(mod), |
| 8582 | const operand_pointer_ty = try mod.ptrType(.{ |
| 8583 | .child = payload_ty.toIntern(), |
| 8584 | .flags = .{ |
| 8585 | .is_const = operand_ty.isConstPtr(mod), |
| 8586 | .address_space = operand_ty.ptrAddressSpace(mod), |
| 8587 | }, |
| 8587 | 8588 | }); |
| 8588 | 8589 | |
| 8589 | 8590 | if (try sema.resolveDefinedValue(block, src, operand)) |ptr_val| { |
| ... | ... | @@ -8750,7 +8751,7 @@ fn zirFunc( |
| 8750 | 8751 | block, |
| 8751 | 8752 | inst_data.src_node, |
| 8752 | 8753 | inst, |
| 8753 | | 0, |
| 8754 | .none, |
| 8754 | 8755 | target_util.defaultAddressSpace(target, .function), |
| 8755 | 8756 | FuncLinkSection.default, |
| 8756 | 8757 | cc, |
| ... | ... | @@ -8879,7 +8880,7 @@ fn funcCommon( |
| 8879 | 8880 | src_node_offset: i32, |
| 8880 | 8881 | func_inst: Zir.Inst.Index, |
| 8881 | 8882 | /// null means generic poison |
| 8882 | | alignment: ?u32, |
| 8883 | alignment: ?Alignment, |
| 8883 | 8884 | /// null means generic poison |
| 8884 | 8885 | address_space: ?std.builtin.AddressSpace, |
| 8885 | 8886 | /// outer null means generic poison; inner null means default link section |
| ... | ... | @@ -9128,7 +9129,7 @@ fn funcCommon( |
| 9128 | 9129 | .return_type = return_type.toIntern(), |
| 9129 | 9130 | .cc = cc_resolved, |
| 9130 | 9131 | .cc_is_generic = cc == null, |
| 9131 | | .alignment = if (alignment) |a| InternPool.Alignment.fromByteUnits(a) else .none, |
| 9132 | .alignment = alignment orelse .none, |
| 9132 | 9133 | .align_is_generic = alignment == null, |
| 9133 | 9134 | .section_is_generic = section == .generic, |
| 9134 | 9135 | .addrspace_is_generic = address_space == null, |
| ... | ... | @@ -9143,7 +9144,7 @@ fn funcCommon( |
| 9143 | 9144 | .default => .none, |
| 9144 | 9145 | .explicit => |section_name| section_name.toOptional(), |
| 9145 | 9146 | }; |
| 9146 | | sema.owner_decl.@"align" = alignment orelse 0; |
| 9147 | sema.owner_decl.alignment = alignment orelse .none; |
| 9147 | 9148 | sema.owner_decl.@"addrspace" = address_space orelse .generic; |
| 9148 | 9149 | |
| 9149 | 9150 | if (is_extern) { |
| ... | ... | @@ -10275,11 +10276,13 @@ const SwitchProngAnalysis = struct { |
| 10275 | 10276 | const union_obj = mod.typeToUnion(operand_ty).?; |
| 10276 | 10277 | const field_ty = union_obj.fields.values()[field_index].ty; |
| 10277 | 10278 | if (capture_byref) { |
| 10278 | | const ptr_field_ty = try Type.ptr(sema.arena, mod, .{ |
| 10279 | | .pointee_type = field_ty, |
| 10280 | | .mutable = operand_ptr_ty.ptrIsMutable(mod), |
| 10281 | | .@"volatile" = operand_ptr_ty.isVolatilePtr(mod), |
| 10282 | | .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod), |
| 10279 | const ptr_field_ty = try mod.ptrType(.{ |
| 10280 | .child = field_ty.toIntern(), |
| 10281 | .flags = .{ |
| 10282 | .is_const = !operand_ptr_ty.ptrIsMutable(mod), |
| 10283 | .is_volatile = operand_ptr_ty.isVolatilePtr(mod), |
| 10284 | .address_space = operand_ptr_ty.ptrAddressSpace(mod), |
| 10285 | }, |
| 10283 | 10286 | }); |
| 10284 | 10287 | if (try sema.resolveDefinedValue(block, sema.src, spa.operand_ptr)) |union_ptr| { |
| 10285 | 10288 | return sema.addConstant( |
| ... | ... | @@ -10382,24 +10385,28 @@ const SwitchProngAnalysis = struct { |
| 10382 | 10385 | // By-reference captures have some further restrictions which make them easier to emit |
| 10383 | 10386 | if (capture_byref) { |
| 10384 | 10387 | const operand_ptr_info = operand_ptr_ty.ptrInfo(mod); |
| 10385 | | const capture_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 10386 | | .pointee_type = capture_ty, |
| 10387 | | .@"addrspace" = operand_ptr_info.@"addrspace", |
| 10388 | | .mutable = operand_ptr_info.mutable, |
| 10389 | | .@"volatile" = operand_ptr_info.@"volatile", |
| 10390 | | // TODO: alignment! |
| 10388 | const capture_ptr_ty = try mod.ptrType(.{ |
| 10389 | .child = capture_ty.toIntern(), |
| 10390 | .flags = .{ |
| 10391 | // TODO: alignment! |
| 10392 | .is_const = operand_ptr_info.flags.is_const, |
| 10393 | .is_volatile = operand_ptr_info.flags.is_volatile, |
| 10394 | .address_space = operand_ptr_info.flags.address_space, |
| 10395 | }, |
| 10391 | 10396 | }); |
| 10392 | 10397 | |
| 10393 | 10398 | // By-ref captures of hetereogeneous types are only allowed if each field |
| 10394 | 10399 | // pointer type is in-memory coercible to the capture pointer type. |
| 10395 | 10400 | if (!same_types) { |
| 10396 | 10401 | for (field_tys, 0..) |field_ty, i| { |
| 10397 | | const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 10398 | | .pointee_type = field_ty, |
| 10399 | | .@"addrspace" = operand_ptr_info.@"addrspace", |
| 10400 | | .mutable = operand_ptr_info.mutable, |
| 10401 | | .@"volatile" = operand_ptr_info.@"volatile", |
| 10402 | | // TODO: alignment! |
| 10402 | const field_ptr_ty = try mod.ptrType(.{ |
| 10403 | .child = field_ty.toIntern(), |
| 10404 | .flags = .{ |
| 10405 | // TODO: alignment! |
| 10406 | .is_const = operand_ptr_info.flags.is_const, |
| 10407 | .is_volatile = operand_ptr_info.flags.is_volatile, |
| 10408 | .address_space = operand_ptr_info.flags.address_space, |
| 10409 | }, |
| 10403 | 10410 | }); |
| 10404 | 10411 | if (.ok != try sema.coerceInMemoryAllowed(block, capture_ptr_ty, field_ptr_ty, false, sema.mod.getTarget(), .unneeded, .unneeded)) { |
| 10405 | 10412 | const multi_idx = raw_capture_src.multi_capture; |
| ... | ... | @@ -12656,8 +12663,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 12656 | 12663 | // - When a Decl is destroyed, it can free the `*Module.EmbedFile`. |
| 12657 | 12664 | const ty = try mod.arrayType(.{ |
| 12658 | 12665 | .len = embed_file.bytes.len, |
| 12659 | | .child = .u8_type, |
| 12660 | 12666 | .sentinel = .zero_u8, |
| 12667 | .child = .u8_type, |
| 12661 | 12668 | }); |
| 12662 | 12669 | embed_file.owner_decl = try anon_decl.finish( |
| 12663 | 12670 | ty, |
| ... | ... | @@ -12665,7 +12672,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 12665 | 12672 | .ty = ty.toIntern(), |
| 12666 | 12673 | .storage = .{ .bytes = embed_file.bytes }, |
| 12667 | 12674 | } })).toValue(), |
| 12668 | | 0, // default alignment |
| 12675 | .none, // default alignment |
| 12669 | 12676 | ); |
| 12670 | 12677 | |
| 12671 | 12678 | return sema.analyzeDeclRef(embed_file.owner_decl); |
| ... | ... | @@ -13289,7 +13296,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13289 | 13296 | ), |
| 13290 | 13297 | }; |
| 13291 | 13298 | |
| 13292 | | const result_ty = try Type.array(sema.arena, result_len, res_sent_val, resolved_elem_ty, mod); |
| 13299 | const result_ty = try mod.arrayType(.{ |
| 13300 | .len = result_len, |
| 13301 | .sentinel = if (res_sent_val) |v| v.toIntern() else .none, |
| 13302 | .child = resolved_elem_ty.toIntern(), |
| 13303 | }); |
| 13293 | 13304 | const ptr_addrspace = p: { |
| 13294 | 13305 | if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(mod); |
| 13295 | 13306 | if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace(mod); |
| ... | ... | @@ -13348,14 +13359,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13348 | 13359 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 13349 | 13360 | |
| 13350 | 13361 | if (ptr_addrspace) |ptr_as| { |
| 13351 | | const alloc_ty = try Type.ptr(sema.arena, mod, .{ |
| 13352 | | .pointee_type = result_ty, |
| 13353 | | .@"addrspace" = ptr_as, |
| 13362 | const alloc_ty = try mod.ptrType(.{ |
| 13363 | .child = result_ty.toIntern(), |
| 13364 | .flags = .{ .address_space = ptr_as }, |
| 13354 | 13365 | }); |
| 13355 | 13366 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 13356 | | const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{ |
| 13357 | | .pointee_type = resolved_elem_ty, |
| 13358 | | .@"addrspace" = ptr_as, |
| 13367 | const elem_ptr_ty = try mod.ptrType(.{ |
| 13368 | .child = resolved_elem_ty.toIntern(), |
| 13369 | .flags = .{ .address_space = ptr_as }, |
| 13359 | 13370 | }); |
| 13360 | 13371 | |
| 13361 | 13372 | var elem_i: usize = 0; |
| ... | ... | @@ -13407,21 +13418,24 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins |
| 13407 | 13418 | .Array => return operand_ty.arrayInfo(mod), |
| 13408 | 13419 | .Pointer => { |
| 13409 | 13420 | const ptr_info = operand_ty.ptrInfo(mod); |
| 13410 | | switch (ptr_info.size) { |
| 13421 | switch (ptr_info.flags.size) { |
| 13411 | 13422 | // TODO: in the Many case here this should only work if the type |
| 13412 | 13423 | // has a sentinel, and this code should compute the length based |
| 13413 | 13424 | // on the sentinel value. |
| 13414 | 13425 | .Slice, .Many => { |
| 13415 | 13426 | const val = try sema.resolveConstValue(block, src, operand, "slice value being concatenated must be comptime-known"); |
| 13416 | 13427 | return Type.ArrayInfo{ |
| 13417 | | .elem_type = ptr_info.pointee_type, |
| 13418 | | .sentinel = ptr_info.sentinel, |
| 13428 | .elem_type = ptr_info.child.toType(), |
| 13429 | .sentinel = switch (ptr_info.sentinel) { |
| 13430 | .none => null, |
| 13431 | else => ptr_info.sentinel.toValue(), |
| 13432 | }, |
| 13419 | 13433 | .len = val.sliceLen(mod), |
| 13420 | 13434 | }; |
| 13421 | 13435 | }, |
| 13422 | 13436 | .One => { |
| 13423 | | if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) { |
| 13424 | | return ptr_info.pointee_type.arrayInfo(mod); |
| 13437 | if (ptr_info.child.toType().zigTypeTag(mod) == .Array) { |
| 13438 | return ptr_info.child.toType().arrayInfo(mod); |
| 13425 | 13439 | } |
| 13426 | 13440 | }, |
| 13427 | 13441 | .C => {}, |
| ... | ... | @@ -13557,7 +13571,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13557 | 13571 | return sema.fail(block, rhs_src, "operation results in overflow", .{}); |
| 13558 | 13572 | const result_len = try sema.usizeCast(block, src, result_len_u64); |
| 13559 | 13573 | |
| 13560 | | const result_ty = try Type.array(sema.arena, result_len, lhs_info.sentinel, lhs_info.elem_type, mod); |
| 13574 | const result_ty = try mod.arrayType(.{ |
| 13575 | .len = result_len, |
| 13576 | .sentinel = if (lhs_info.sentinel) |s| s.toIntern() else .none, |
| 13577 | .child = lhs_info.elem_type.toIntern(), |
| 13578 | }); |
| 13561 | 13579 | |
| 13562 | 13580 | const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null; |
| 13563 | 13581 | const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len); |
| ... | ... | @@ -13600,14 +13618,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13600 | 13618 | try sema.requireRuntimeBlock(block, src, lhs_src); |
| 13601 | 13619 | |
| 13602 | 13620 | if (ptr_addrspace) |ptr_as| { |
| 13603 | | const alloc_ty = try Type.ptr(sema.arena, mod, .{ |
| 13604 | | .pointee_type = result_ty, |
| 13605 | | .@"addrspace" = ptr_as, |
| 13621 | const alloc_ty = try mod.ptrType(.{ |
| 13622 | .child = result_ty.toIntern(), |
| 13623 | .flags = .{ .address_space = ptr_as }, |
| 13606 | 13624 | }); |
| 13607 | 13625 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 13608 | | const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{ |
| 13609 | | .pointee_type = lhs_info.elem_type, |
| 13610 | | .@"addrspace" = ptr_as, |
| 13626 | const elem_ptr_ty = try mod.ptrType(.{ |
| 13627 | .child = lhs_info.elem_type.toIntern(), |
| 13628 | .flags = .{ .address_space = ptr_as }, |
| 13611 | 13629 | }); |
| 13612 | 13630 | |
| 13613 | 13631 | var elem_i: usize = 0; |
| ... | ... | @@ -15563,18 +15581,18 @@ fn analyzePtrArithmetic( |
| 15563 | 15581 | const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset); |
| 15564 | 15582 | const ptr_ty = sema.typeOf(ptr); |
| 15565 | 15583 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 15566 | | assert(ptr_info.size == .Many or ptr_info.size == .C); |
| 15584 | assert(ptr_info.flags.size == .Many or ptr_info.flags.size == .C); |
| 15567 | 15585 | |
| 15568 | 15586 | const new_ptr_ty = t: { |
| 15569 | 15587 | // Calculate the new pointer alignment. |
| 15570 | 15588 | // This code is duplicated in `elemPtrType`. |
| 15571 | | if (ptr_info.@"align" == 0) { |
| 15589 | if (ptr_info.flags.alignment == .none) { |
| 15572 | 15590 | // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness. |
| 15573 | 15591 | break :t ptr_ty; |
| 15574 | 15592 | } |
| 15575 | 15593 | // If the addend is not a comptime-known value we can still count on |
| 15576 | 15594 | // it being a multiple of the type size. |
| 15577 | | const elem_size = ptr_info.pointee_type.abiSize(mod); |
| 15595 | const elem_size = ptr_info.child.toType().abiSize(mod); |
| 15578 | 15596 | const addend = if (opt_off_val) |off_val| a: { |
| 15579 | 15597 | const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(mod)); |
| 15580 | 15598 | break :a elem_size * off_int; |
| ... | ... | @@ -15583,17 +15601,23 @@ fn analyzePtrArithmetic( |
| 15583 | 15601 | // The resulting pointer is aligned to the lcd between the offset (an |
| 15584 | 15602 | // arbitrary number) and the alignment factor (always a power of two, |
| 15585 | 15603 | // non zero). |
| 15586 | | const new_align = @as(u32, 1) << @intCast(u5, @ctz(addend | ptr_info.@"align")); |
| 15604 | const new_align = @enumFromInt(Alignment, @min( |
| 15605 | @ctz(addend), |
| 15606 | @intFromEnum(ptr_info.flags.alignment), |
| 15607 | )); |
| 15608 | assert(new_align != .none); |
| 15587 | 15609 | |
| 15588 | | break :t try Type.ptr(sema.arena, mod, .{ |
| 15589 | | .pointee_type = ptr_info.pointee_type, |
| 15610 | break :t try mod.ptrType(.{ |
| 15611 | .child = ptr_info.child, |
| 15590 | 15612 | .sentinel = ptr_info.sentinel, |
| 15591 | | .@"align" = new_align, |
| 15592 | | .@"addrspace" = ptr_info.@"addrspace", |
| 15593 | | .mutable = ptr_info.mutable, |
| 15594 | | .@"allowzero" = ptr_info.@"allowzero", |
| 15595 | | .@"volatile" = ptr_info.@"volatile", |
| 15596 | | .size = ptr_info.size, |
| 15613 | .flags = .{ |
| 15614 | .size = ptr_info.flags.size, |
| 15615 | .alignment = new_align, |
| 15616 | .is_const = ptr_info.flags.is_const, |
| 15617 | .is_volatile = ptr_info.flags.is_volatile, |
| 15618 | .is_allowzero = ptr_info.flags.is_allowzero, |
| 15619 | .address_space = ptr_info.flags.address_space, |
| 15620 | }, |
| 15597 | 15621 | }); |
| 15598 | 15622 | }; |
| 15599 | 15623 | |
| ... | ... | @@ -15605,7 +15629,7 @@ fn analyzePtrArithmetic( |
| 15605 | 15629 | const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod)); |
| 15606 | 15630 | if (offset_int == 0) return ptr; |
| 15607 | 15631 | if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| { |
| 15608 | | const elem_size = ptr_info.pointee_type.abiSize(mod); |
| 15632 | const elem_size = ptr_info.child.toType().abiSize(mod); |
| 15609 | 15633 | const new_addr = switch (air_tag) { |
| 15610 | 15634 | .ptr_add => addr + elem_size * offset_int, |
| 15611 | 15635 | .ptr_sub => addr - elem_size * offset_int, |
| ... | ... | @@ -16344,8 +16368,8 @@ fn zirBuiltinSrc( |
| 16344 | 16368 | const name = try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(fn_owner_decl.name)); |
| 16345 | 16369 | const new_decl_ty = try mod.arrayType(.{ |
| 16346 | 16370 | .len = name.len, |
| 16347 | | .child = .u8_type, |
| 16348 | 16371 | .sentinel = .zero_u8, |
| 16372 | .child = .u8_type, |
| 16349 | 16373 | }); |
| 16350 | 16374 | const new_decl = try anon_decl.finish( |
| 16351 | 16375 | new_decl_ty, |
| ... | ... | @@ -16353,7 +16377,7 @@ fn zirBuiltinSrc( |
| 16353 | 16377 | .ty = new_decl_ty.toIntern(), |
| 16354 | 16378 | .storage = .{ .bytes = name }, |
| 16355 | 16379 | } })).toValue(), |
| 16356 | | 0, // default alignment |
| 16380 | .none, // default alignment |
| 16357 | 16381 | ); |
| 16358 | 16382 | break :blk try mod.intern(.{ .ptr = .{ |
| 16359 | 16383 | .ty = .slice_const_u8_sentinel_0_type, |
| ... | ... | @@ -16369,8 +16393,8 @@ fn zirBuiltinSrc( |
| 16369 | 16393 | const name = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena); |
| 16370 | 16394 | const new_decl_ty = try mod.arrayType(.{ |
| 16371 | 16395 | .len = name.len, |
| 16372 | | .child = .u8_type, |
| 16373 | 16396 | .sentinel = .zero_u8, |
| 16397 | .child = .u8_type, |
| 16374 | 16398 | }); |
| 16375 | 16399 | const new_decl = try anon_decl.finish( |
| 16376 | 16400 | new_decl_ty, |
| ... | ... | @@ -16378,7 +16402,7 @@ fn zirBuiltinSrc( |
| 16378 | 16402 | .ty = new_decl_ty.toIntern(), |
| 16379 | 16403 | .storage = .{ .bytes = name }, |
| 16380 | 16404 | } })).toValue(), |
| 16381 | | 0, // default alignment |
| 16405 | .none, // default alignment |
| 16382 | 16406 | ); |
| 16383 | 16407 | break :blk try mod.intern(.{ .ptr = .{ |
| 16384 | 16408 | .ty = .slice_const_u8_sentinel_0_type, |
| ... | ... | @@ -16499,7 +16523,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16499 | 16523 | .ty = new_decl_ty.toIntern(), |
| 16500 | 16524 | .storage = .{ .elems = param_vals }, |
| 16501 | 16525 | } })).toValue(), |
| 16502 | | 0, // default alignment |
| 16526 | .none, // default alignment |
| 16503 | 16527 | ); |
| 16504 | 16528 | break :v try mod.intern(.{ .ptr = .{ |
| 16505 | 16529 | .ty = (try mod.ptrType(.{ |
| ... | ... | @@ -16601,10 +16625,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16601 | 16625 | }, |
| 16602 | 16626 | .Pointer => { |
| 16603 | 16627 | const info = ty.ptrInfo(mod); |
| 16604 | | const alignment = if (info.@"align" != 0) |
| 16605 | | try mod.intValue(Type.comptime_int, info.@"align") |
| 16628 | const alignment = if (info.flags.alignment.toByteUnitsOptional()) |alignment| |
| 16629 | try mod.intValue(Type.comptime_int, alignment) |
| 16606 | 16630 | else |
| 16607 | | try info.pointee_type.lazyAbiAlignment(mod); |
| 16631 | try info.child.toType().lazyAbiAlignment(mod); |
| 16608 | 16632 | |
| 16609 | 16633 | const addrspace_ty = try sema.getBuiltinType("AddressSpace"); |
| 16610 | 16634 | const pointer_ty = t: { |
| ... | ... | @@ -16634,21 +16658,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16634 | 16658 | |
| 16635 | 16659 | const field_values = .{ |
| 16636 | 16660 | // size: Size, |
| 16637 | | try (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.size))).intern(ptr_size_ty, mod), |
| 16661 | try (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).intern(ptr_size_ty, mod), |
| 16638 | 16662 | // is_const: bool, |
| 16639 | | Value.makeBool(!info.mutable).toIntern(), |
| 16663 | Value.makeBool(info.flags.is_const).toIntern(), |
| 16640 | 16664 | // is_volatile: bool, |
| 16641 | | Value.makeBool(info.@"volatile").toIntern(), |
| 16665 | Value.makeBool(info.flags.is_volatile).toIntern(), |
| 16642 | 16666 | // alignment: comptime_int, |
| 16643 | 16667 | alignment.toIntern(), |
| 16644 | 16668 | // address_space: AddressSpace |
| 16645 | | try (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.@"addrspace"))).intern(addrspace_ty, mod), |
| 16669 | try (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).intern(addrspace_ty, mod), |
| 16646 | 16670 | // child: type, |
| 16647 | | info.pointee_type.toIntern(), |
| 16671 | info.child, |
| 16648 | 16672 | // is_allowzero: bool, |
| 16649 | | Value.makeBool(info.@"allowzero").toIntern(), |
| 16673 | Value.makeBool(info.flags.is_allowzero).toIntern(), |
| 16650 | 16674 | // sentinel: ?*const anyopaque, |
| 16651 | | (try sema.optRefValue(block, info.pointee_type, info.sentinel)).toIntern(), |
| 16675 | (try sema.optRefValue(block, info.child.toType(), switch (info.sentinel) { |
| 16676 | .none => null, |
| 16677 | else => info.sentinel.toValue(), |
| 16678 | })).toIntern(), |
| 16652 | 16679 | }; |
| 16653 | 16680 | return sema.addConstant(type_info_ty, (try mod.intern(.{ .un = .{ |
| 16654 | 16681 | .ty = type_info_ty.toIntern(), |
| ... | ... | @@ -16792,7 +16819,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16792 | 16819 | .ty = new_decl_ty.toIntern(), |
| 16793 | 16820 | .storage = .{ .bytes = name }, |
| 16794 | 16821 | } })).toValue(), |
| 16795 | | 0, // default alignment |
| 16822 | .none, // default alignment |
| 16796 | 16823 | ); |
| 16797 | 16824 | break :v try mod.intern(.{ .ptr = .{ |
| 16798 | 16825 | .ty = .slice_const_u8_type, |
| ... | ... | @@ -16827,7 +16854,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16827 | 16854 | const array_errors_ty = try mod.arrayType(.{ |
| 16828 | 16855 | .len = vals.len, |
| 16829 | 16856 | .child = error_field_ty.toIntern(), |
| 16830 | | .sentinel = .none, |
| 16831 | 16857 | }); |
| 16832 | 16858 | const new_decl = try fields_anon_decl.finish( |
| 16833 | 16859 | array_errors_ty, |
| ... | ... | @@ -16835,7 +16861,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16835 | 16861 | .ty = array_errors_ty.toIntern(), |
| 16836 | 16862 | .storage = .{ .elems = vals }, |
| 16837 | 16863 | } })).toValue(), |
| 16838 | | 0, // default alignment |
| 16864 | .none, // default alignment |
| 16839 | 16865 | ); |
| 16840 | 16866 | break :v try mod.intern(.{ .ptr = .{ |
| 16841 | 16867 | .ty = slice_errors_ty.toIntern(), |
| ... | ... | @@ -16929,7 +16955,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16929 | 16955 | .ty = new_decl_ty.toIntern(), |
| 16930 | 16956 | .storage = .{ .bytes = name }, |
| 16931 | 16957 | } })).toValue(), |
| 16932 | | 0, // default alignment |
| 16958 | .none, // default alignment |
| 16933 | 16959 | ); |
| 16934 | 16960 | break :v try mod.intern(.{ .ptr = .{ |
| 16935 | 16961 | .ty = .slice_const_u8_type, |
| ... | ... | @@ -16954,7 +16980,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16954 | 16980 | const fields_array_ty = try mod.arrayType(.{ |
| 16955 | 16981 | .len = enum_field_vals.len, |
| 16956 | 16982 | .child = enum_field_ty.toIntern(), |
| 16957 | | .sentinel = .none, |
| 16958 | 16983 | }); |
| 16959 | 16984 | const new_decl = try fields_anon_decl.finish( |
| 16960 | 16985 | fields_array_ty, |
| ... | ... | @@ -16962,7 +16987,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16962 | 16987 | .ty = fields_array_ty.toIntern(), |
| 16963 | 16988 | .storage = .{ .elems = enum_field_vals }, |
| 16964 | 16989 | } })).toValue(), |
| 16965 | | 0, // default alignment |
| 16990 | .none, // default alignment |
| 16966 | 16991 | ); |
| 16967 | 16992 | break :v try mod.intern(.{ .ptr = .{ |
| 16968 | 16993 | .ty = (try mod.ptrType(.{ |
| ... | ... | @@ -17068,7 +17093,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17068 | 17093 | .ty = new_decl_ty.toIntern(), |
| 17069 | 17094 | .storage = .{ .bytes = name }, |
| 17070 | 17095 | } })).toValue(), |
| 17071 | | 0, // default alignment |
| 17096 | .none, // default alignment |
| 17072 | 17097 | ); |
| 17073 | 17098 | break :v try mod.intern(.{ .ptr = .{ |
| 17074 | 17099 | .ty = .slice_const_u8_type, |
| ... | ... | @@ -17100,7 +17125,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17100 | 17125 | const array_fields_ty = try mod.arrayType(.{ |
| 17101 | 17126 | .len = union_field_vals.len, |
| 17102 | 17127 | .child = union_field_ty.toIntern(), |
| 17103 | | .sentinel = .none, |
| 17104 | 17128 | }); |
| 17105 | 17129 | const new_decl = try fields_anon_decl.finish( |
| 17106 | 17130 | array_fields_ty, |
| ... | ... | @@ -17108,7 +17132,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17108 | 17132 | .ty = array_fields_ty.toIntern(), |
| 17109 | 17133 | .storage = .{ .elems = union_field_vals }, |
| 17110 | 17134 | } })).toValue(), |
| 17111 | | 0, // default alignment |
| 17135 | .none, // default alignment |
| 17112 | 17136 | ); |
| 17113 | 17137 | break :v try mod.intern(.{ .ptr = .{ |
| 17114 | 17138 | .ty = (try mod.ptrType(.{ |
| ... | ... | @@ -17228,7 +17252,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17228 | 17252 | .ty = new_decl_ty.toIntern(), |
| 17229 | 17253 | .storage = .{ .bytes = bytes }, |
| 17230 | 17254 | } })).toValue(), |
| 17231 | | 0, // default alignment |
| 17255 | .none, // default alignment |
| 17232 | 17256 | ); |
| 17233 | 17257 | break :v try mod.intern(.{ .ptr = .{ |
| 17234 | 17258 | .ty = .slice_const_u8_type, |
| ... | ... | @@ -17285,7 +17309,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17285 | 17309 | .ty = new_decl_ty.toIntern(), |
| 17286 | 17310 | .storage = .{ .bytes = name }, |
| 17287 | 17311 | } })).toValue(), |
| 17288 | | 0, // default alignment |
| 17312 | .none, // default alignment |
| 17289 | 17313 | ); |
| 17290 | 17314 | break :v try mod.intern(.{ .ptr = .{ |
| 17291 | 17315 | .ty = .slice_const_u8_type, |
| ... | ... | @@ -17324,7 +17348,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17324 | 17348 | const array_fields_ty = try mod.arrayType(.{ |
| 17325 | 17349 | .len = struct_field_vals.len, |
| 17326 | 17350 | .child = struct_field_ty.toIntern(), |
| 17327 | | .sentinel = .none, |
| 17328 | 17351 | }); |
| 17329 | 17352 | const new_decl = try fields_anon_decl.finish( |
| 17330 | 17353 | array_fields_ty, |
| ... | ... | @@ -17332,7 +17355,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17332 | 17355 | .ty = array_fields_ty.toIntern(), |
| 17333 | 17356 | .storage = .{ .elems = struct_field_vals }, |
| 17334 | 17357 | } })).toValue(), |
| 17335 | | 0, // default alignment |
| 17358 | .none, // default alignment |
| 17336 | 17359 | ); |
| 17337 | 17360 | break :v try mod.intern(.{ .ptr = .{ |
| 17338 | 17361 | .ty = (try mod.ptrType(.{ |
| ... | ... | @@ -17471,7 +17494,6 @@ fn typeInfoDecls( |
| 17471 | 17494 | const array_decl_ty = try mod.arrayType(.{ |
| 17472 | 17495 | .len = decl_vals.items.len, |
| 17473 | 17496 | .child = declaration_ty.toIntern(), |
| 17474 | | .sentinel = .none, |
| 17475 | 17497 | }); |
| 17476 | 17498 | const new_decl = try decls_anon_decl.finish( |
| 17477 | 17499 | array_decl_ty, |
| ... | ... | @@ -17479,7 +17501,7 @@ fn typeInfoDecls( |
| 17479 | 17501 | .ty = array_decl_ty.toIntern(), |
| 17480 | 17502 | .storage = .{ .elems = decl_vals.items }, |
| 17481 | 17503 | } })).toValue(), |
| 17482 | | 0, // default alignment |
| 17504 | .none, // default alignment |
| 17483 | 17505 | ); |
| 17484 | 17506 | return try mod.intern(.{ .ptr = .{ |
| 17485 | 17507 | .ty = (try mod.ptrType(.{ |
| ... | ... | @@ -17532,7 +17554,7 @@ fn typeInfoNamespaceDecls( |
| 17532 | 17554 | .ty = new_decl_ty.toIntern(), |
| 17533 | 17555 | .storage = .{ .bytes = name }, |
| 17534 | 17556 | } })).toValue(), |
| 17535 | | 0, // default alignment |
| 17557 | .none, // default alignment |
| 17536 | 17558 | ); |
| 17537 | 17559 | break :v try mod.intern(.{ .ptr = .{ |
| 17538 | 17560 | .ty = .slice_const_u8_type, |
| ... | ... | @@ -18057,12 +18079,14 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 18057 | 18079 | |
| 18058 | 18080 | const operand_ty = sema.typeOf(operand); |
| 18059 | 18081 | const ptr_info = operand_ty.ptrInfo(mod); |
| 18060 | | const res_ty = try Type.ptr(sema.arena, mod, .{ |
| 18061 | | .pointee_type = err_union_ty.errorUnionPayload(mod), |
| 18062 | | .@"addrspace" = ptr_info.@"addrspace", |
| 18063 | | .mutable = ptr_info.mutable, |
| 18064 | | .@"allowzero" = ptr_info.@"allowzero", |
| 18065 | | .@"volatile" = ptr_info.@"volatile", |
| 18082 | const res_ty = try mod.ptrType(.{ |
| 18083 | .child = err_union_ty.errorUnionPayload(mod).toIntern(), |
| 18084 | .flags = .{ |
| 18085 | .is_const = ptr_info.flags.is_const, |
| 18086 | .is_volatile = ptr_info.flags.is_volatile, |
| 18087 | .is_allowzero = ptr_info.flags.is_allowzero, |
| 18088 | .address_space = ptr_info.flags.address_space, |
| 18089 | }, |
| 18066 | 18090 | }); |
| 18067 | 18091 | const res_ty_ref = try sema.addType(res_ty); |
| 18068 | 18092 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.TryPtr).Struct.fields.len + |
| ... | ... | @@ -18482,7 +18506,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18482 | 18506 | break :blk val.toIntern(); |
| 18483 | 18507 | } else .none; |
| 18484 | 18508 | |
| 18485 | | const abi_align: InternPool.Alignment = if (inst_data.flags.has_align) blk: { |
| 18509 | const abi_align: Alignment = if (inst_data.flags.has_align) blk: { |
| 18486 | 18510 | const ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 18487 | 18511 | extra_i += 1; |
| 18488 | 18512 | const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src); |
| ... | ... | @@ -18498,7 +18522,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18498 | 18522 | } |
| 18499 | 18523 | const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?); |
| 18500 | 18524 | try sema.validateAlign(block, align_src, abi_align); |
| 18501 | | break :blk InternPool.Alignment.fromByteUnits(abi_align); |
| 18525 | break :blk Alignment.fromByteUnits(abi_align); |
| 18502 | 18526 | } else .none; |
| 18503 | 18527 | |
| 18504 | 18528 | const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: { |
| ... | ... | @@ -18775,9 +18799,9 @@ fn zirStructInit( |
| 18775 | 18799 | |
| 18776 | 18800 | if (is_ref) { |
| 18777 | 18801 | const target = mod.getTarget(); |
| 18778 | | const alloc_ty = try Type.ptr(sema.arena, mod, .{ |
| 18779 | | .pointee_type = resolved_ty, |
| 18780 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 18802 | const alloc_ty = try mod.ptrType(.{ |
| 18803 | .child = resolved_ty.toIntern(), |
| 18804 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 18781 | 18805 | }); |
| 18782 | 18806 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 18783 | 18807 | const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty, true); |
| ... | ... | @@ -18898,9 +18922,9 @@ fn finishStructInit( |
| 18898 | 18922 | if (is_ref) { |
| 18899 | 18923 | try sema.resolveStructLayout(struct_ty); |
| 18900 | 18924 | const target = sema.mod.getTarget(); |
| 18901 | | const alloc_ty = try Type.ptr(sema.arena, mod, .{ |
| 18902 | | .pointee_type = struct_ty, |
| 18903 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 18925 | const alloc_ty = try mod.ptrType(.{ |
| 18926 | .child = struct_ty.toIntern(), |
| 18927 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 18904 | 18928 | }); |
| 18905 | 18929 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 18906 | 18930 | for (field_inits, 0..) |field_init, i_usize| { |
| ... | ... | @@ -19019,9 +19043,9 @@ fn zirStructInitAnon( |
| 19019 | 19043 | |
| 19020 | 19044 | if (is_ref) { |
| 19021 | 19045 | const target = mod.getTarget(); |
| 19022 | | const alloc_ty = try Type.ptr(sema.arena, mod, .{ |
| 19023 | | .pointee_type = tuple_ty.toType(), |
| 19024 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 19046 | const alloc_ty = try mod.ptrType(.{ |
| 19047 | .child = tuple_ty, |
| 19048 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 19025 | 19049 | }); |
| 19026 | 19050 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 19027 | 19051 | var extra_index = extra.end; |
| ... | ... | @@ -19030,10 +19054,9 @@ fn zirStructInitAnon( |
| 19030 | 19054 | const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index); |
| 19031 | 19055 | extra_index = item.end; |
| 19032 | 19056 | |
| 19033 | | const field_ptr_ty = try Type.ptr(sema.arena, mod, .{ |
| 19034 | | .mutable = true, |
| 19035 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 19036 | | .pointee_type = field_ty.toType(), |
| 19057 | const field_ptr_ty = try mod.ptrType(.{ |
| 19058 | .child = field_ty, |
| 19059 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 19037 | 19060 | }); |
| 19038 | 19061 | if (values[i] == .none) { |
| 19039 | 19062 | const init = try sema.resolveInst(item.data.init); |
| ... | ... | @@ -19131,18 +19154,17 @@ fn zirArrayInit( |
| 19131 | 19154 | |
| 19132 | 19155 | if (is_ref) { |
| 19133 | 19156 | const target = mod.getTarget(); |
| 19134 | | const alloc_ty = try Type.ptr(sema.arena, mod, .{ |
| 19135 | | .pointee_type = array_ty, |
| 19136 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 19157 | const alloc_ty = try mod.ptrType(.{ |
| 19158 | .child = array_ty.toIntern(), |
| 19159 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 19137 | 19160 | }); |
| 19138 | 19161 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 19139 | 19162 | |
| 19140 | 19163 | if (array_ty.isTuple(mod)) { |
| 19141 | 19164 | for (resolved_args, 0..) |arg, i| { |
| 19142 | | const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{ |
| 19143 | | .mutable = true, |
| 19144 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 19145 | | .pointee_type = array_ty.structFieldType(i, mod), |
| 19165 | const elem_ptr_ty = try mod.ptrType(.{ |
| 19166 | .child = array_ty.structFieldType(i, mod).toIntern(), |
| 19167 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 19146 | 19168 | }); |
| 19147 | 19169 | const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty); |
| 19148 | 19170 | |
| ... | ... | @@ -19153,10 +19175,9 @@ fn zirArrayInit( |
| 19153 | 19175 | return sema.makePtrConst(block, alloc); |
| 19154 | 19176 | } |
| 19155 | 19177 | |
| 19156 | | const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{ |
| 19157 | | .mutable = true, |
| 19158 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 19159 | | .pointee_type = array_ty.elemType2(mod), |
| 19178 | const elem_ptr_ty = try mod.ptrType(.{ |
| 19179 | .child = array_ty.elemType2(mod).toIntern(), |
| 19180 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 19160 | 19181 | }); |
| 19161 | 19182 | const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty); |
| 19162 | 19183 | |
| ... | ... | @@ -19230,17 +19251,16 @@ fn zirArrayInitAnon( |
| 19230 | 19251 | |
| 19231 | 19252 | if (is_ref) { |
| 19232 | 19253 | const target = sema.mod.getTarget(); |
| 19233 | | const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 19234 | | .pointee_type = tuple_ty.toType(), |
| 19235 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 19254 | const alloc_ty = try mod.ptrType(.{ |
| 19255 | .child = tuple_ty, |
| 19256 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 19236 | 19257 | }); |
| 19237 | 19258 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 19238 | 19259 | for (operands, 0..) |operand, i_usize| { |
| 19239 | 19260 | const i = @intCast(u32, i_usize); |
| 19240 | | const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 19241 | | .mutable = true, |
| 19242 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 19243 | | .pointee_type = types[i].toType(), |
| 19261 | const field_ptr_ty = try mod.ptrType(.{ |
| 19262 | .child = types[i], |
| 19263 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 19244 | 19264 | }); |
| 19245 | 19265 | if (values[i] == .none) { |
| 19246 | 19266 | const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty); |
| ... | ... | @@ -19273,7 +19293,7 @@ fn addConstantMaybeRef( |
| 19273 | 19293 | const decl = try anon_decl.finish( |
| 19274 | 19294 | ty, |
| 19275 | 19295 | val, |
| 19276 | | 0, // default alignment |
| 19296 | .none, // default alignment |
| 19277 | 19297 | ); |
| 19278 | 19298 | return sema.analyzeDeclRef(decl); |
| 19279 | 19299 | } |
| ... | ... | @@ -19368,7 +19388,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 19368 | 19388 | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 19369 | 19389 | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 19370 | 19390 | const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); |
| 19371 | | const opt_ptr_stack_trace_ty = try Type.optional(sema.arena, ptr_stack_trace_ty, mod); |
| 19391 | const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern()); |
| 19372 | 19392 | |
| 19373 | 19393 | if (sema.owner_func != null and |
| 19374 | 19394 | sema.owner_func.?.calls_or_awaits_errorable_fn and |
| ... | ... | @@ -19688,7 +19708,7 @@ fn zirReify( |
| 19688 | 19708 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); |
| 19689 | 19709 | } |
| 19690 | 19710 | |
| 19691 | | const abi_align = InternPool.Alignment.fromByteUnits( |
| 19711 | const abi_align = Alignment.fromByteUnits( |
| 19692 | 19712 | (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?, |
| 19693 | 19713 | ); |
| 19694 | 19714 | |
| ... | ... | @@ -19709,10 +19729,7 @@ fn zirReify( |
| 19709 | 19729 | return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{}); |
| 19710 | 19730 | } |
| 19711 | 19731 | const sentinel_ptr_val = sentinel_val.optionalValue(mod).?; |
| 19712 | | const ptr_ty = try Type.ptr(sema.arena, mod, .{ |
| 19713 | | .@"addrspace" = .generic, |
| 19714 | | .pointee_type = elem_ty, |
| 19715 | | }); |
| 19732 | const ptr_ty = try mod.singleMutPtrType(elem_ty); |
| 19716 | 19733 | const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?; |
| 19717 | 19734 | break :s sent_val.toIntern(); |
| 19718 | 19735 | } |
| ... | ... | @@ -19781,14 +19798,15 @@ fn zirReify( |
| 19781 | 19798 | const len = len_val.toUnsignedInt(mod); |
| 19782 | 19799 | const child_ty = child_val.toType(); |
| 19783 | 19800 | const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: { |
| 19784 | | const ptr_ty = try Type.ptr(sema.arena, mod, .{ |
| 19785 | | .@"addrspace" = .generic, |
| 19786 | | .pointee_type = child_ty, |
| 19787 | | }); |
| 19801 | const ptr_ty = try mod.singleMutPtrType(child_ty); |
| 19788 | 19802 | break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?; |
| 19789 | 19803 | } else null; |
| 19790 | 19804 | |
| 19791 | | const ty = try Type.array(sema.arena, len, sentinel, child_ty, mod); |
| 19805 | const ty = try mod.arrayType(.{ |
| 19806 | .len = len, |
| 19807 | .sentinel = if (sentinel) |s| s.toIntern() else .none, |
| 19808 | .child = child_ty.toIntern(), |
| 19809 | }); |
| 19792 | 19810 | return sema.addType(ty); |
| 19793 | 19811 | }, |
| 19794 | 19812 | .Optional => { |
| ... | ... | @@ -19799,7 +19817,7 @@ fn zirReify( |
| 19799 | 19817 | |
| 19800 | 19818 | const child_ty = child_val.toType(); |
| 19801 | 19819 | |
| 19802 | | const ty = try Type.optional(sema.arena, child_ty, mod); |
| 19820 | const ty = try mod.optionalType(child_ty.toIntern()); |
| 19803 | 19821 | return sema.addType(ty); |
| 19804 | 19822 | }, |
| 19805 | 19823 | .ErrorUnion => { |
| ... | ... | @@ -20180,7 +20198,7 @@ fn zirReify( |
| 20180 | 20198 | const field_ty = type_val.toType(); |
| 20181 | 20199 | gop.value_ptr.* = .{ |
| 20182 | 20200 | .ty = field_ty, |
| 20183 | | .abi_align = @intCast(u32, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?), |
| 20201 | .abi_align = Alignment.fromByteUnits((try alignment_val.getUnsignedIntAdvanced(mod, sema)).?), |
| 20184 | 20202 | }; |
| 20185 | 20203 | |
| 20186 | 20204 | if (field_ty.zigTypeTag(mod) == .Opaque) { |
| ... | ... | @@ -20287,7 +20305,7 @@ fn zirReify( |
| 20287 | 20305 | if (alignment == target_util.defaultFunctionAlignment(target)) { |
| 20288 | 20306 | break :alignment .none; |
| 20289 | 20307 | } else { |
| 20290 | | break :alignment InternPool.Alignment.fromByteUnits(alignment); |
| 20308 | break :alignment Alignment.fromByteUnits(alignment); |
| 20291 | 20309 | } |
| 20292 | 20310 | }; |
| 20293 | 20311 | const return_type = return_type_val.optionalValue(mod) orelse |
| ... | ... | @@ -20436,7 +20454,7 @@ fn reifyStruct( |
| 20436 | 20454 | if (!try sema.intFitsInType(alignment_val, Type.u32, null)) { |
| 20437 | 20455 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); |
| 20438 | 20456 | } |
| 20439 | | const abi_align = @intCast(u29, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?); |
| 20457 | const abi_align = (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?; |
| 20440 | 20458 | |
| 20441 | 20459 | if (layout == .Packed) { |
| 20442 | 20460 | if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{}); |
| ... | ... | @@ -20483,7 +20501,7 @@ fn reifyStruct( |
| 20483 | 20501 | |
| 20484 | 20502 | gop.value_ptr.* = .{ |
| 20485 | 20503 | .ty = field_ty, |
| 20486 | | .abi_align = abi_align, |
| 20504 | .abi_align = Alignment.fromByteUnits(abi_align), |
| 20487 | 20505 | .default_val = default_val, |
| 20488 | 20506 | .is_comptime = is_comptime_val.toBool(), |
| 20489 | 20507 | .offset = undefined, |
| ... | ... | @@ -20585,7 +20603,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 20585 | 20603 | try sema.checkPtrOperand(block, ptr_src, ptr_ty); |
| 20586 | 20604 | |
| 20587 | 20605 | var ptr_info = ptr_ty.ptrInfo(mod); |
| 20588 | | const src_addrspace = ptr_info.@"addrspace"; |
| 20606 | const src_addrspace = ptr_info.flags.address_space; |
| 20589 | 20607 | if (!target_util.addrSpaceCastIsValid(sema.mod.getTarget(), src_addrspace, dest_addrspace)) { |
| 20590 | 20608 | const msg = msg: { |
| 20591 | 20609 | const msg = try sema.errMsg(block, src, "invalid address space cast", .{}); |
| ... | ... | @@ -20596,10 +20614,10 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 20596 | 20614 | return sema.failWithOwnedErrorMsg(msg); |
| 20597 | 20615 | } |
| 20598 | 20616 | |
| 20599 | | ptr_info.@"addrspace" = dest_addrspace; |
| 20600 | | const dest_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info); |
| 20617 | ptr_info.flags.address_space = dest_addrspace; |
| 20618 | const dest_ptr_ty = try mod.ptrType(ptr_info); |
| 20601 | 20619 | const dest_ty = if (ptr_ty.zigTypeTag(mod) == .Optional) |
| 20602 | | try Type.optional(sema.arena, dest_ptr_ty, mod) |
| 20620 | try mod.optionalType(dest_ptr_ty.toIntern()) |
| 20603 | 20621 | else |
| 20604 | 20622 | dest_ptr_ty; |
| 20605 | 20623 | |
| ... | ... | @@ -20617,11 +20635,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 20617 | 20635 | |
| 20618 | 20636 | fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref { |
| 20619 | 20637 | const va_list_ty = try sema.getBuiltinType("VaList"); |
| 20620 | | const va_list_ptr = try Type.ptr(sema.arena, sema.mod, .{ |
| 20621 | | .pointee_type = va_list_ty, |
| 20622 | | .mutable = true, |
| 20623 | | .@"addrspace" = .generic, |
| 20624 | | }); |
| 20638 | const va_list_ptr = try sema.mod.singleMutPtrType(va_list_ty); |
| 20625 | 20639 | |
| 20626 | 20640 | const inst = try sema.resolveInst(zir_ref); |
| 20627 | 20641 | return sema.coerce(block, va_list_ptr, inst, src); |
| ... | ... | @@ -20698,20 +20712,22 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 20698 | 20712 | var anon_decl = try block.startAnonDecl(); |
| 20699 | 20713 | defer anon_decl.deinit(); |
| 20700 | 20714 | |
| 20701 | | const bytes = try ty.nameAllocArena(sema.arena, mod); |
| 20715 | var bytes = std.ArrayList(u8).init(sema.arena); |
| 20716 | defer bytes.deinit(); |
| 20717 | try ty.print(bytes.writer(), mod); |
| 20702 | 20718 | |
| 20703 | 20719 | const decl_ty = try mod.arrayType(.{ |
| 20704 | | .len = bytes.len, |
| 20705 | | .child = .u8_type, |
| 20720 | .len = bytes.items.len, |
| 20706 | 20721 | .sentinel = .zero_u8, |
| 20722 | .child = .u8_type, |
| 20707 | 20723 | }); |
| 20708 | 20724 | const new_decl = try anon_decl.finish( |
| 20709 | 20725 | decl_ty, |
| 20710 | 20726 | (try mod.intern(.{ .aggregate = .{ |
| 20711 | 20727 | .ty = decl_ty.toIntern(), |
| 20712 | | .storage = .{ .bytes = bytes }, |
| 20728 | .storage = .{ .bytes = bytes.items }, |
| 20713 | 20729 | } })).toValue(), |
| 20714 | | 0, // default alignment |
| 20730 | .none, // default alignment |
| 20715 | 20731 | ); |
| 20716 | 20732 | |
| 20717 | 20733 | return sema.analyzeDeclRef(new_decl); |
| ... | ... | @@ -20962,7 +20978,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20962 | 20978 | |
| 20963 | 20979 | const operand_info = operand_ty.ptrInfo(mod); |
| 20964 | 20980 | const dest_info = dest_ty.ptrInfo(mod); |
| 20965 | | if (!operand_info.mutable and dest_info.mutable) { |
| 20981 | if (operand_info.flags.is_const and !dest_info.flags.is_const) { |
| 20966 | 20982 | const msg = msg: { |
| 20967 | 20983 | const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{}); |
| 20968 | 20984 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -20972,7 +20988,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20972 | 20988 | }; |
| 20973 | 20989 | return sema.failWithOwnedErrorMsg(msg); |
| 20974 | 20990 | } |
| 20975 | | if (operand_info.@"volatile" and !dest_info.@"volatile") { |
| 20991 | if (operand_info.flags.is_volatile and !dest_info.flags.is_volatile) { |
| 20976 | 20992 | const msg = msg: { |
| 20977 | 20993 | const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{}); |
| 20978 | 20994 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -20982,7 +20998,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20982 | 20998 | }; |
| 20983 | 20999 | return sema.failWithOwnedErrorMsg(msg); |
| 20984 | 21000 | } |
| 20985 | | if (operand_info.@"addrspace" != dest_info.@"addrspace") { |
| 21001 | if (operand_info.flags.address_space != dest_info.flags.address_space) { |
| 20986 | 21002 | const msg = msg: { |
| 20987 | 21003 | const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{}); |
| 20988 | 21004 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -21014,14 +21030,12 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 21014 | 21030 | // If the destination is less aligned than the source, preserve the source alignment |
| 21015 | 21031 | const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: { |
| 21016 | 21032 | // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result |
| 21033 | var dest_ptr_info = dest_ty.ptrInfo(mod); |
| 21034 | dest_ptr_info.flags.alignment = Alignment.fromNonzeroByteUnits(operand_align); |
| 21017 | 21035 | if (dest_ty.zigTypeTag(mod) == .Optional) { |
| 21018 | | var dest_ptr_info = dest_ty.optionalChild(mod).ptrInfo(mod); |
| 21019 | | dest_ptr_info.@"align" = operand_align; |
| 21020 | | break :blk try Type.optional(sema.arena, try Type.ptr(sema.arena, mod, dest_ptr_info), mod); |
| 21036 | break :blk try mod.optionalType((try mod.ptrType(dest_ptr_info)).toIntern()); |
| 21021 | 21037 | } else { |
| 21022 | | var dest_ptr_info = dest_ty.ptrInfo(mod); |
| 21023 | | dest_ptr_info.@"align" = operand_align; |
| 21024 | | break :blk try Type.ptr(sema.arena, mod, dest_ptr_info); |
| 21038 | break :blk try mod.ptrType(dest_ptr_info); |
| 21025 | 21039 | } |
| 21026 | 21040 | }; |
| 21027 | 21041 | |
| ... | ... | @@ -21088,8 +21102,8 @@ fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 21088 | 21102 | try sema.checkPtrOperand(block, operand_src, operand_ty); |
| 21089 | 21103 | |
| 21090 | 21104 | var ptr_info = operand_ty.ptrInfo(mod); |
| 21091 | | ptr_info.mutable = true; |
| 21092 | | const dest_ty = try Type.ptr(sema.arena, mod, ptr_info); |
| 21105 | ptr_info.flags.is_const = false; |
| 21106 | const dest_ty = try mod.ptrType(ptr_info); |
| 21093 | 21107 | |
| 21094 | 21108 | if (try sema.resolveMaybeUndefVal(operand)) |operand_val| { |
| 21095 | 21109 | return sema.addConstant(dest_ty, try mod.getCoerced(operand_val, dest_ty)); |
| ... | ... | @@ -21109,8 +21123,8 @@ fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 21109 | 21123 | try sema.checkPtrOperand(block, operand_src, operand_ty); |
| 21110 | 21124 | |
| 21111 | 21125 | var ptr_info = operand_ty.ptrInfo(mod); |
| 21112 | | ptr_info.@"volatile" = false; |
| 21113 | | const dest_ty = try Type.ptr(sema.arena, mod, ptr_info); |
| 21126 | ptr_info.flags.is_volatile = false; |
| 21127 | const dest_ty = try mod.ptrType(ptr_info); |
| 21114 | 21128 | |
| 21115 | 21129 | if (try sema.resolveMaybeUndefVal(operand)) |operand_val| { |
| 21116 | 21130 | return sema.addConstant(dest_ty, operand_val); |
| ... | ... | @@ -21219,28 +21233,29 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 21219 | 21233 | try sema.checkPtrOperand(block, ptr_src, ptr_ty); |
| 21220 | 21234 | |
| 21221 | 21235 | var ptr_info = ptr_ty.ptrInfo(mod); |
| 21222 | | ptr_info.@"align" = dest_align; |
| 21223 | | var dest_ty = try Type.ptr(sema.arena, mod, ptr_info); |
| 21236 | ptr_info.flags.alignment = dest_align; |
| 21237 | var dest_ty = try mod.ptrType(ptr_info); |
| 21224 | 21238 | if (ptr_ty.zigTypeTag(mod) == .Optional) { |
| 21225 | 21239 | dest_ty = try mod.optionalType(dest_ty.toIntern()); |
| 21226 | 21240 | } |
| 21227 | 21241 | |
| 21228 | 21242 | if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| { |
| 21229 | 21243 | if (try val.getUnsignedIntAdvanced(mod, null)) |addr| { |
| 21230 | | if (addr % dest_align != 0) { |
| 21231 | | return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align }); |
| 21244 | const dest_align_bytes = dest_align.toByteUnitsOptional().?; |
| 21245 | if (addr % dest_align_bytes != 0) { |
| 21246 | return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align_bytes }); |
| 21232 | 21247 | } |
| 21233 | 21248 | } |
| 21234 | 21249 | return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty)); |
| 21235 | 21250 | } |
| 21236 | 21251 | |
| 21237 | 21252 | try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src); |
| 21238 | | if (block.wantSafety() and dest_align > 1 and |
| 21239 | | try sema.typeHasRuntimeBits(ptr_info.pointee_type)) |
| 21253 | if (block.wantSafety() and dest_align.order(Alignment.fromNonzeroByteUnits(1)).compare(.gt) and |
| 21254 | try sema.typeHasRuntimeBits(ptr_info.child.toType())) |
| 21240 | 21255 | { |
| 21241 | 21256 | const align_minus_1 = try sema.addConstant( |
| 21242 | 21257 | Type.usize, |
| 21243 | | try mod.intValue(Type.usize, dest_align - 1), |
| 21258 | try mod.intValue(Type.usize, dest_align.toByteUnitsOptional().? - 1), |
| 21244 | 21259 | ); |
| 21245 | 21260 | const actual_ptr = if (ptr_ty.isSlice(mod)) |
| 21246 | 21261 | try sema.analyzeSlicePtr(block, ptr_src, ptr, ptr_ty) |
| ... | ... | @@ -21685,28 +21700,29 @@ fn checkAtomicPtrOperand( |
| 21685 | 21700 | ), |
| 21686 | 21701 | }; |
| 21687 | 21702 | |
| 21688 | | var wanted_ptr_data: Type.Payload.Pointer.Data = .{ |
| 21689 | | .pointee_type = elem_ty, |
| 21690 | | .@"align" = alignment, |
| 21691 | | .@"addrspace" = .generic, |
| 21692 | | .mutable = !ptr_const, |
| 21703 | var wanted_ptr_data: InternPool.Key.PtrType = .{ |
| 21704 | .child = elem_ty.toIntern(), |
| 21705 | .flags = .{ |
| 21706 | .alignment = alignment, |
| 21707 | .is_const = ptr_const, |
| 21708 | }, |
| 21693 | 21709 | }; |
| 21694 | 21710 | |
| 21695 | 21711 | const ptr_ty = sema.typeOf(ptr); |
| 21696 | 21712 | const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) { |
| 21697 | 21713 | .Pointer => ptr_ty.ptrInfo(mod), |
| 21698 | 21714 | else => { |
| 21699 | | const wanted_ptr_ty = try Type.ptr(sema.arena, mod, wanted_ptr_data); |
| 21715 | const wanted_ptr_ty = try mod.ptrType(wanted_ptr_data); |
| 21700 | 21716 | _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src); |
| 21701 | 21717 | unreachable; |
| 21702 | 21718 | }, |
| 21703 | 21719 | }; |
| 21704 | 21720 | |
| 21705 | | wanted_ptr_data.@"addrspace" = ptr_data.@"addrspace"; |
| 21706 | | wanted_ptr_data.@"allowzero" = ptr_data.@"allowzero"; |
| 21707 | | wanted_ptr_data.@"volatile" = ptr_data.@"volatile"; |
| 21721 | wanted_ptr_data.flags.address_space = ptr_data.flags.address_space; |
| 21722 | wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero; |
| 21723 | wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile; |
| 21708 | 21724 | |
| 21709 | | const wanted_ptr_ty = try Type.ptr(sema.arena, mod, wanted_ptr_data); |
| 21725 | const wanted_ptr_ty = try mod.ptrType(wanted_ptr_data); |
| 21710 | 21726 | const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src); |
| 21711 | 21727 | |
| 21712 | 21728 | return casted_ptr; |
| ... | ... | @@ -22059,7 +22075,7 @@ fn zirCmpxchg( |
| 22059 | 22075 | return sema.fail(block, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{}); |
| 22060 | 22076 | } |
| 22061 | 22077 | |
| 22062 | | const result_ty = try Type.optional(sema.arena, elem_ty, mod); |
| 22078 | const result_ty = try mod.optionalType(elem_ty.toIntern()); |
| 22063 | 22079 | |
| 22064 | 22080 | // special case zero bit types |
| 22065 | 22081 | if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) { |
| ... | ... | @@ -22825,31 +22841,33 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 22825 | 22841 | try sema.checkPtrOperand(block, ptr_src, field_ptr_ty); |
| 22826 | 22842 | const field_ptr_ty_info = field_ptr_ty.ptrInfo(mod); |
| 22827 | 22843 | |
| 22828 | | var ptr_ty_data: Type.Payload.Pointer.Data = .{ |
| 22829 | | .pointee_type = parent_ty.structFieldType(field_index, mod), |
| 22830 | | .mutable = field_ptr_ty_info.mutable, |
| 22831 | | .@"addrspace" = field_ptr_ty_info.@"addrspace", |
| 22844 | var ptr_ty_data: InternPool.Key.PtrType = .{ |
| 22845 | .child = parent_ty.structFieldType(field_index, mod).toIntern(), |
| 22846 | .flags = .{ |
| 22847 | .address_space = field_ptr_ty_info.flags.address_space, |
| 22848 | .is_const = field_ptr_ty_info.flags.is_const, |
| 22849 | }, |
| 22832 | 22850 | }; |
| 22833 | 22851 | |
| 22834 | 22852 | if (parent_ty.containerLayout(mod) == .Packed) { |
| 22835 | 22853 | return sema.fail(block, src, "TODO handle packed structs/unions with @fieldParentPtr", .{}); |
| 22836 | 22854 | } else { |
| 22837 | | ptr_ty_data.@"align" = blk: { |
| 22855 | ptr_ty_data.flags.alignment = blk: { |
| 22838 | 22856 | if (mod.typeToStruct(parent_ty)) |struct_obj| { |
| 22839 | 22857 | break :blk struct_obj.fields.values()[field_index].abi_align; |
| 22840 | 22858 | } else if (mod.typeToUnion(parent_ty)) |union_obj| { |
| 22841 | 22859 | break :blk union_obj.fields.values()[field_index].abi_align; |
| 22842 | 22860 | } else { |
| 22843 | | break :blk 0; |
| 22861 | break :blk .none; |
| 22844 | 22862 | } |
| 22845 | 22863 | }; |
| 22846 | 22864 | } |
| 22847 | 22865 | |
| 22848 | | const actual_field_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data); |
| 22866 | const actual_field_ptr_ty = try mod.ptrType(ptr_ty_data); |
| 22849 | 22867 | const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src); |
| 22850 | 22868 | |
| 22851 | | ptr_ty_data.pointee_type = parent_ty; |
| 22852 | | const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data); |
| 22869 | ptr_ty_data.child = parent_ty.toIntern(); |
| 22870 | const result_ptr = try mod.ptrType(ptr_ty_data); |
| 22853 | 22871 | |
| 22854 | 22872 | if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| { |
| 22855 | 22873 | const field = switch (ip.indexToKey(field_ptr_val.toIntern())) { |
| ... | ... | @@ -23172,21 +23190,25 @@ fn analyzeMinMax( |
| 23172 | 23190 | fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref { |
| 23173 | 23191 | const mod = sema.mod; |
| 23174 | 23192 | const info = sema.typeOf(ptr).ptrInfo(mod); |
| 23175 | | if (info.size == .One) { |
| 23193 | if (info.flags.size == .One) { |
| 23176 | 23194 | // Already an array pointer. |
| 23177 | 23195 | return ptr; |
| 23178 | 23196 | } |
| 23179 | | const new_ty = try Type.ptr(sema.arena, mod, .{ |
| 23180 | | .pointee_type = try Type.array(sema.arena, len, info.sentinel, info.pointee_type, mod), |
| 23181 | | .sentinel = null, |
| 23182 | | .@"align" = info.@"align", |
| 23183 | | .@"addrspace" = info.@"addrspace", |
| 23184 | | .mutable = info.mutable, |
| 23185 | | .@"allowzero" = info.@"allowzero", |
| 23186 | | .@"volatile" = info.@"volatile", |
| 23187 | | .size = .One, |
| 23197 | const new_ty = try mod.ptrType(.{ |
| 23198 | .child = (try mod.arrayType(.{ |
| 23199 | .len = len, |
| 23200 | .sentinel = info.sentinel, |
| 23201 | .child = info.child, |
| 23202 | })).toIntern(), |
| 23203 | .flags = .{ |
| 23204 | .alignment = info.flags.alignment, |
| 23205 | .is_const = info.flags.is_const, |
| 23206 | .is_volatile = info.flags.is_volatile, |
| 23207 | .is_allowzero = info.flags.is_allowzero, |
| 23208 | .address_space = info.flags.address_space, |
| 23209 | }, |
| 23188 | 23210 | }); |
| 23189 | | if (info.size == .Slice) { |
| 23211 | if (info.flags.size == .Slice) { |
| 23190 | 23212 | return block.addTyOp(.slice_ptr, new_ty, ptr); |
| 23191 | 23213 | } |
| 23192 | 23214 | return block.addBitCast(new_ty, ptr); |
| ... | ... | @@ -23604,7 +23626,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 23604 | 23626 | return sema.fail(block, align_src, "target does not support function alignment", .{}); |
| 23605 | 23627 | } |
| 23606 | 23628 | |
| 23607 | | const @"align": ?u32 = if (extra.data.bits.has_align_body) blk: { |
| 23629 | const @"align": ?Alignment = if (extra.data.bits.has_align_body) blk: { |
| 23608 | 23630 | const body_len = sema.code.extra[extra_index]; |
| 23609 | 23631 | extra_index += 1; |
| 23610 | 23632 | const body = sema.code.extra[extra_index..][0..body_len]; |
| ... | ... | @@ -23617,9 +23639,9 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 23617 | 23639 | const alignment = @intCast(u32, val.toUnsignedInt(mod)); |
| 23618 | 23640 | try sema.validateAlign(block, align_src, alignment); |
| 23619 | 23641 | if (alignment == target_util.defaultFunctionAlignment(target)) { |
| 23620 | | break :blk 0; |
| 23642 | break :blk .none; |
| 23621 | 23643 | } else { |
| 23622 | | break :blk alignment; |
| 23644 | break :blk Alignment.fromNonzeroByteUnits(alignment); |
| 23623 | 23645 | } |
| 23624 | 23646 | } else if (extra.data.bits.has_align_ref) blk: { |
| 23625 | 23647 | const align_ref = @enumFromInt(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| ... | ... | @@ -23633,11 +23655,11 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 23633 | 23655 | const alignment = @intCast(u32, align_tv.val.toUnsignedInt(mod)); |
| 23634 | 23656 | try sema.validateAlign(block, align_src, alignment); |
| 23635 | 23657 | if (alignment == target_util.defaultFunctionAlignment(target)) { |
| 23636 | | break :blk 0; |
| 23658 | break :blk .none; |
| 23637 | 23659 | } else { |
| 23638 | | break :blk alignment; |
| 23660 | break :blk Alignment.fromNonzeroByteUnits(alignment); |
| 23639 | 23661 | } |
| 23640 | | } else 0; |
| 23662 | } else .none; |
| 23641 | 23663 | |
| 23642 | 23664 | const @"addrspace": ?std.builtin.AddressSpace = if (extra.data.bits.has_addrspace_body) blk: { |
| 23643 | 23665 | const body_len = sema.code.extra[extra_index]; |
| ... | ... | @@ -24032,7 +24054,7 @@ fn zirBuiltinExtern( |
| 24032 | 24054 | }; |
| 24033 | 24055 | |
| 24034 | 24056 | if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) { |
| 24035 | | ty = try Type.optional(sema.arena, ty, mod); |
| 24057 | ty = try mod.optionalType(ty.toIntern()); |
| 24036 | 24058 | } |
| 24037 | 24059 | |
| 24038 | 24060 | // TODO check duplicate extern |
| ... | ... | @@ -24058,7 +24080,7 @@ fn zirBuiltinExtern( |
| 24058 | 24080 | // below, so this type doesn't matter |
| 24059 | 24081 | new_decl.ty = ty; |
| 24060 | 24082 | new_decl.val = new_var.toValue(); |
| 24061 | | new_decl.@"align" = 0; |
| 24083 | new_decl.alignment = .none; |
| 24062 | 24084 | new_decl.@"linksection" = .none; |
| 24063 | 24085 | new_decl.has_tv = true; |
| 24064 | 24086 | new_decl.analysis = .complete; |
| ... | ... | @@ -24948,18 +24970,19 @@ fn fieldVal( |
| 24948 | 24970 | ); |
| 24949 | 24971 | } else if (ip.stringEqlSlice(field_name, "ptr") and is_pointer_to) { |
| 24950 | 24972 | const ptr_info = object_ty.ptrInfo(mod); |
| 24951 | | const result_ty = try Type.ptr(sema.arena, mod, .{ |
| 24952 | | .pointee_type = ptr_info.pointee_type.childType(mod), |
| 24973 | const result_ty = try mod.ptrType(.{ |
| 24974 | .child = ptr_info.child.toType().childType(mod).toIntern(), |
| 24953 | 24975 | .sentinel = ptr_info.sentinel, |
| 24954 | | .@"align" = ptr_info.@"align", |
| 24955 | | .@"addrspace" = ptr_info.@"addrspace", |
| 24956 | | .bit_offset = ptr_info.bit_offset, |
| 24957 | | .host_size = ptr_info.host_size, |
| 24958 | | .vector_index = ptr_info.vector_index, |
| 24959 | | .@"allowzero" = ptr_info.@"allowzero", |
| 24960 | | .mutable = ptr_info.mutable, |
| 24961 | | .@"volatile" = ptr_info.@"volatile", |
| 24962 | | .size = .Many, |
| 24976 | .flags = .{ |
| 24977 | .size = .Many, |
| 24978 | .alignment = ptr_info.flags.alignment, |
| 24979 | .is_const = ptr_info.flags.is_const, |
| 24980 | .is_volatile = ptr_info.flags.is_volatile, |
| 24981 | .is_allowzero = ptr_info.flags.is_allowzero, |
| 24982 | .address_space = ptr_info.flags.address_space, |
| 24983 | .vector_index = ptr_info.flags.vector_index, |
| 24984 | }, |
| 24985 | .packed_offset = ptr_info.packed_offset, |
| 24963 | 24986 | }); |
| 24964 | 24987 | return sema.coerce(block, result_ty, object, src); |
| 24965 | 24988 | } else { |
| ... | ... | @@ -24973,7 +24996,7 @@ fn fieldVal( |
| 24973 | 24996 | }, |
| 24974 | 24997 | .Pointer => { |
| 24975 | 24998 | const ptr_info = inner_ty.ptrInfo(mod); |
| 24976 | | if (ptr_info.size == .Slice) { |
| 24999 | if (ptr_info.flags.size == .Slice) { |
| 24977 | 25000 | if (ip.stringEqlSlice(field_name, "ptr")) { |
| 24978 | 25001 | const slice = if (is_pointer_to) |
| 24979 | 25002 | try sema.analyzeLoad(block, src, object, object_src) |
| ... | ... | @@ -25147,7 +25170,7 @@ fn fieldPtr( |
| 25147 | 25170 | return sema.analyzeDeclRef(try anon_decl.finish( |
| 25148 | 25171 | Type.usize, |
| 25149 | 25172 | try mod.intValue(Type.usize, inner_ty.arrayLen(mod)), |
| 25150 | | 0, // default alignment |
| 25173 | .none, // default alignment |
| 25151 | 25174 | )); |
| 25152 | 25175 | } else { |
| 25153 | 25176 | return sema.fail( |
| ... | ... | @@ -25169,11 +25192,13 @@ fn fieldPtr( |
| 25169 | 25192 | if (ip.stringEqlSlice(field_name, "ptr")) { |
| 25170 | 25193 | const slice_ptr_ty = inner_ty.slicePtrFieldType(mod); |
| 25171 | 25194 | |
| 25172 | | const result_ty = try Type.ptr(sema.arena, mod, .{ |
| 25173 | | .pointee_type = slice_ptr_ty, |
| 25174 | | .mutable = attr_ptr_ty.ptrIsMutable(mod), |
| 25175 | | .@"volatile" = attr_ptr_ty.isVolatilePtr(mod), |
| 25176 | | .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod), |
| 25195 | const result_ty = try mod.ptrType(.{ |
| 25196 | .child = slice_ptr_ty.toIntern(), |
| 25197 | .flags = .{ |
| 25198 | .is_const = !attr_ptr_ty.ptrIsMutable(mod), |
| 25199 | .is_volatile = attr_ptr_ty.isVolatilePtr(mod), |
| 25200 | .address_space = attr_ptr_ty.ptrAddressSpace(mod), |
| 25201 | }, |
| 25177 | 25202 | }); |
| 25178 | 25203 | |
| 25179 | 25204 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { |
| ... | ... | @@ -25189,11 +25214,13 @@ fn fieldPtr( |
| 25189 | 25214 | |
| 25190 | 25215 | return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr); |
| 25191 | 25216 | } else if (ip.stringEqlSlice(field_name, "len")) { |
| 25192 | | const result_ty = try Type.ptr(sema.arena, mod, .{ |
| 25193 | | .pointee_type = Type.usize, |
| 25194 | | .mutable = attr_ptr_ty.ptrIsMutable(mod), |
| 25195 | | .@"volatile" = attr_ptr_ty.isVolatilePtr(mod), |
| 25196 | | .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod), |
| 25217 | const result_ty = try mod.ptrType(.{ |
| 25218 | .child = .usize_type, |
| 25219 | .flags = .{ |
| 25220 | .is_const = !attr_ptr_ty.ptrIsMutable(mod), |
| 25221 | .is_volatile = attr_ptr_ty.isVolatilePtr(mod), |
| 25222 | .address_space = attr_ptr_ty.ptrAddressSpace(mod), |
| 25223 | }, |
| 25197 | 25224 | }); |
| 25198 | 25225 | |
| 25199 | 25226 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { |
| ... | ... | @@ -25261,7 +25288,7 @@ fn fieldPtr( |
| 25261 | 25288 | .ty = error_set_type.toIntern(), |
| 25262 | 25289 | .name = field_name, |
| 25263 | 25290 | } })).toValue(), |
| 25264 | | 0, // default alignment |
| 25291 | .none, // default alignment |
| 25265 | 25292 | )); |
| 25266 | 25293 | }, |
| 25267 | 25294 | .Union => { |
| ... | ... | @@ -25279,7 +25306,7 @@ fn fieldPtr( |
| 25279 | 25306 | return sema.analyzeDeclRef(try anon_decl.finish( |
| 25280 | 25307 | enum_ty, |
| 25281 | 25308 | try mod.enumValueFieldIndex(enum_ty, field_index_u32), |
| 25282 | | 0, // default alignment |
| 25309 | .none, // default alignment |
| 25283 | 25310 | )); |
| 25284 | 25311 | } |
| 25285 | 25312 | } |
| ... | ... | @@ -25300,7 +25327,7 @@ fn fieldPtr( |
| 25300 | 25327 | return sema.analyzeDeclRef(try anon_decl.finish( |
| 25301 | 25328 | child_type, |
| 25302 | 25329 | try mod.enumValueFieldIndex(child_type, field_index_u32), |
| 25303 | | 0, // default alignment |
| 25330 | .none, // default alignment |
| 25304 | 25331 | )); |
| 25305 | 25332 | }, |
| 25306 | 25333 | .Struct, .Opaque => { |
| ... | ... | @@ -25514,11 +25541,12 @@ fn finishFieldCallBind( |
| 25514 | 25541 | object_ptr: Air.Inst.Ref, |
| 25515 | 25542 | ) CompileError!ResolvedFieldCallee { |
| 25516 | 25543 | const mod = sema.mod; |
| 25517 | | const arena = sema.arena; |
| 25518 | | const ptr_field_ty = try Type.ptr(arena, mod, .{ |
| 25519 | | .pointee_type = field_ty, |
| 25520 | | .mutable = ptr_ty.ptrIsMutable(mod), |
| 25521 | | .@"addrspace" = ptr_ty.ptrAddressSpace(mod), |
| 25544 | const ptr_field_ty = try mod.ptrType(.{ |
| 25545 | .child = field_ty.toIntern(), |
| 25546 | .flags = .{ |
| 25547 | .is_const = !ptr_ty.ptrIsMutable(mod), |
| 25548 | .address_space = ptr_ty.ptrAddressSpace(mod), |
| 25549 | }, |
| 25522 | 25550 | }); |
| 25523 | 25551 | |
| 25524 | 25552 | const container_ty = ptr_ty.childType(mod); |
| ... | ... | @@ -25651,11 +25679,13 @@ fn structFieldPtrByIndex( |
| 25651 | 25679 | const struct_ptr_ty = sema.typeOf(struct_ptr); |
| 25652 | 25680 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod); |
| 25653 | 25681 | |
| 25654 | | var ptr_ty_data: Type.Payload.Pointer.Data = .{ |
| 25655 | | .pointee_type = field.ty, |
| 25656 | | .mutable = struct_ptr_ty_info.mutable, |
| 25657 | | .@"volatile" = struct_ptr_ty_info.@"volatile", |
| 25658 | | .@"addrspace" = struct_ptr_ty_info.@"addrspace", |
| 25682 | var ptr_ty_data: InternPool.Key.PtrType = .{ |
| 25683 | .child = field.ty.toIntern(), |
| 25684 | .flags = .{ |
| 25685 | .is_const = struct_ptr_ty_info.flags.is_const, |
| 25686 | .is_volatile = struct_ptr_ty_info.flags.is_volatile, |
| 25687 | .address_space = struct_ptr_ty_info.flags.address_space, |
| 25688 | }, |
| 25659 | 25689 | }; |
| 25660 | 25690 | |
| 25661 | 25691 | const target = mod.getTarget(); |
| ... | ... | @@ -25668,24 +25698,22 @@ fn structFieldPtrByIndex( |
| 25668 | 25698 | if (!(try sema.typeHasRuntimeBits(f.ty))) continue; |
| 25669 | 25699 | |
| 25670 | 25700 | if (i == field_index) { |
| 25671 | | ptr_ty_data.bit_offset = running_bits; |
| 25701 | ptr_ty_data.packed_offset.bit_offset = running_bits; |
| 25672 | 25702 | } |
| 25673 | 25703 | running_bits += @intCast(u16, f.ty.bitSize(mod)); |
| 25674 | 25704 | } |
| 25675 | | ptr_ty_data.host_size = (running_bits + 7) / 8; |
| 25705 | ptr_ty_data.packed_offset.host_size = (running_bits + 7) / 8; |
| 25676 | 25706 | |
| 25677 | 25707 | // If this is a packed struct embedded in another one, we need to offset |
| 25678 | 25708 | // the bits against each other. |
| 25679 | | if (struct_ptr_ty_info.host_size != 0) { |
| 25680 | | ptr_ty_data.host_size = struct_ptr_ty_info.host_size; |
| 25681 | | ptr_ty_data.bit_offset += struct_ptr_ty_info.bit_offset; |
| 25709 | if (struct_ptr_ty_info.packed_offset.host_size != 0) { |
| 25710 | ptr_ty_data.packed_offset.host_size = struct_ptr_ty_info.packed_offset.host_size; |
| 25711 | ptr_ty_data.packed_offset.bit_offset += struct_ptr_ty_info.packed_offset.bit_offset; |
| 25682 | 25712 | } |
| 25683 | 25713 | |
| 25684 | | const parent_align = if (struct_ptr_ty_info.@"align" != 0) |
| 25685 | | struct_ptr_ty_info.@"align" |
| 25686 | | else |
| 25687 | | struct_ptr_ty_info.pointee_type.abiAlignment(mod); |
| 25688 | | ptr_ty_data.@"align" = parent_align; |
| 25714 | const parent_align = struct_ptr_ty_info.flags.alignment.toByteUnitsOptional() orelse |
| 25715 | struct_ptr_ty_info.child.toType().abiAlignment(mod); |
| 25716 | ptr_ty_data.flags.alignment = Alignment.fromByteUnits(parent_align); |
| 25689 | 25717 | |
| 25690 | 25718 | // If the field happens to be byte-aligned, simplify the pointer type. |
| 25691 | 25719 | // The pointee type bit size must match its ABI byte size so that loads and stores |
| ... | ... | @@ -25695,24 +25723,24 @@ fn structFieldPtrByIndex( |
| 25695 | 25723 | // targets before adding the necessary complications to this code. This will not |
| 25696 | 25724 | // cause miscompilations; it only means the field pointer uses bit masking when it |
| 25697 | 25725 | // might not be strictly necessary. |
| 25698 | | if (parent_align != 0 and ptr_ty_data.bit_offset % 8 == 0 and |
| 25726 | if (parent_align != 0 and ptr_ty_data.packed_offset.bit_offset % 8 == 0 and |
| 25699 | 25727 | target.cpu.arch.endian() == .Little) |
| 25700 | 25728 | { |
| 25701 | | const elem_size_bytes = ptr_ty_data.pointee_type.abiSize(mod); |
| 25702 | | const elem_size_bits = ptr_ty_data.pointee_type.bitSize(mod); |
| 25729 | const elem_size_bytes = ptr_ty_data.child.toType().abiSize(mod); |
| 25730 | const elem_size_bits = ptr_ty_data.child.toType().bitSize(mod); |
| 25703 | 25731 | if (elem_size_bytes * 8 == elem_size_bits) { |
| 25704 | | const byte_offset = ptr_ty_data.bit_offset / 8; |
| 25705 | | const new_align = @as(u32, 1) << @intCast(u5, @ctz(byte_offset | parent_align)); |
| 25706 | | ptr_ty_data.bit_offset = 0; |
| 25707 | | ptr_ty_data.host_size = 0; |
| 25708 | | ptr_ty_data.@"align" = new_align; |
| 25732 | const byte_offset = ptr_ty_data.packed_offset.bit_offset / 8; |
| 25733 | const new_align = @enumFromInt(Alignment, @ctz(byte_offset | parent_align)); |
| 25734 | assert(new_align != .none); |
| 25735 | ptr_ty_data.flags.alignment = new_align; |
| 25736 | ptr_ty_data.packed_offset = .{ .host_size = 0, .bit_offset = 0 }; |
| 25709 | 25737 | } |
| 25710 | 25738 | } |
| 25711 | 25739 | } else { |
| 25712 | | ptr_ty_data.@"align" = field.abi_align; |
| 25740 | ptr_ty_data.flags.alignment = field.abi_align; |
| 25713 | 25741 | } |
| 25714 | 25742 | |
| 25715 | | const ptr_field_ty = try Type.ptr(sema.arena, mod, ptr_ty_data); |
| 25743 | const ptr_field_ty = try mod.ptrType(ptr_ty_data); |
| 25716 | 25744 | |
| 25717 | 25745 | if (field.is_comptime) { |
| 25718 | 25746 | const val = try mod.intern(.{ .ptr = .{ |
| ... | ... | @@ -25874,7 +25902,6 @@ fn unionFieldPtr( |
| 25874 | 25902 | unresolved_union_ty: Type, |
| 25875 | 25903 | initializing: bool, |
| 25876 | 25904 | ) CompileError!Air.Inst.Ref { |
| 25877 | | const arena = sema.arena; |
| 25878 | 25905 | const mod = sema.mod; |
| 25879 | 25906 | const ip = &mod.intern_pool; |
| 25880 | 25907 | |
| ... | ... | @@ -25885,11 +25912,13 @@ fn unionFieldPtr( |
| 25885 | 25912 | const union_obj = mod.typeToUnion(union_ty).?; |
| 25886 | 25913 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); |
| 25887 | 25914 | const field = union_obj.fields.values()[field_index]; |
| 25888 | | const ptr_field_ty = try Type.ptr(arena, mod, .{ |
| 25889 | | .pointee_type = field.ty, |
| 25890 | | .mutable = union_ptr_ty.ptrIsMutable(mod), |
| 25891 | | .@"volatile" = union_ptr_ty.isVolatilePtr(mod), |
| 25892 | | .@"addrspace" = union_ptr_ty.ptrAddressSpace(mod), |
| 25915 | const ptr_field_ty = try mod.ptrType(.{ |
| 25916 | .child = field.ty.toIntern(), |
| 25917 | .flags = .{ |
| 25918 | .is_const = !union_ptr_ty.ptrIsMutable(mod), |
| 25919 | .is_volatile = union_ptr_ty.isVolatilePtr(mod), |
| 25920 | .address_space = union_ptr_ty.ptrAddressSpace(mod), |
| 25921 | }, |
| 25893 | 25922 | }); |
| 25894 | 25923 | const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name, mod).?); |
| 25895 | 25924 | |
| ... | ... | @@ -26250,11 +26279,13 @@ fn tupleFieldPtr( |
| 26250 | 26279 | } |
| 26251 | 26280 | |
| 26252 | 26281 | const field_ty = tuple_ty.structFieldType(field_index, mod); |
| 26253 | | const ptr_field_ty = try Type.ptr(sema.arena, mod, .{ |
| 26254 | | .pointee_type = field_ty, |
| 26255 | | .mutable = tuple_ptr_ty.ptrIsMutable(mod), |
| 26256 | | .@"volatile" = tuple_ptr_ty.isVolatilePtr(mod), |
| 26257 | | .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod), |
| 26282 | const ptr_field_ty = try mod.ptrType(.{ |
| 26283 | .child = field_ty.toIntern(), |
| 26284 | .flags = .{ |
| 26285 | .is_const = !tuple_ptr_ty.ptrIsMutable(mod), |
| 26286 | .is_volatile = tuple_ptr_ty.isVolatilePtr(mod), |
| 26287 | .address_space = tuple_ptr_ty.ptrAddressSpace(mod), |
| 26288 | }, |
| 26258 | 26289 | }); |
| 26259 | 26290 | |
| 26260 | 26291 | if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| { |
| ... | ... | @@ -26705,15 +26736,15 @@ fn coerceExtra( |
| 26705 | 26736 | |
| 26706 | 26737 | // *T to *[1]T |
| 26707 | 26738 | single_item: { |
| 26708 | | if (dest_info.size != .One) break :single_item; |
| 26739 | if (dest_info.flags.size != .One) break :single_item; |
| 26709 | 26740 | if (!inst_ty.isSinglePointer(mod)) break :single_item; |
| 26710 | 26741 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer; |
| 26711 | 26742 | const ptr_elem_ty = inst_ty.childType(mod); |
| 26712 | | const array_ty = dest_info.pointee_type; |
| 26743 | const array_ty = dest_info.child.toType(); |
| 26713 | 26744 | if (array_ty.zigTypeTag(mod) != .Array) break :single_item; |
| 26714 | 26745 | const array_elem_ty = array_ty.childType(mod); |
| 26715 | 26746 | if (array_ty.arrayLen(mod) != 1) break :single_item; |
| 26716 | | const dest_is_mut = dest_info.mutable; |
| 26747 | const dest_is_mut = !dest_info.flags.is_const; |
| 26717 | 26748 | switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) { |
| 26718 | 26749 | .ok => {}, |
| 26719 | 26750 | else => break :single_item, |
| ... | ... | @@ -26728,9 +26759,9 @@ fn coerceExtra( |
| 26728 | 26759 | const array_ty = inst_ty.childType(mod); |
| 26729 | 26760 | if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr; |
| 26730 | 26761 | const array_elem_type = array_ty.childType(mod); |
| 26731 | | const dest_is_mut = dest_info.mutable; |
| 26762 | const dest_is_mut = !dest_info.flags.is_const; |
| 26732 | 26763 | |
| 26733 | | const dst_elem_type = dest_info.pointee_type; |
| 26764 | const dst_elem_type = dest_info.child.toType(); |
| 26734 | 26765 | const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src); |
| 26735 | 26766 | switch (elem_res) { |
| 26736 | 26767 | .ok => {}, |
| ... | ... | @@ -26744,12 +26775,12 @@ fn coerceExtra( |
| 26744 | 26775 | }, |
| 26745 | 26776 | } |
| 26746 | 26777 | |
| 26747 | | if (dest_info.sentinel) |dest_sent| { |
| 26778 | if (dest_info.sentinel != .none) { |
| 26748 | 26779 | if (array_ty.sentinel(mod)) |inst_sent| { |
| 26749 | | if (!dest_sent.eql(inst_sent, dst_elem_type, mod)) { |
| 26780 | if (dest_info.sentinel != (try mod.getCoerced(inst_sent, dst_elem_type)).toIntern()) { |
| 26750 | 26781 | in_memory_result = .{ .ptr_sentinel = .{ |
| 26751 | 26782 | .actual = inst_sent, |
| 26752 | | .wanted = dest_sent, |
| 26783 | .wanted = dest_info.sentinel.toValue(), |
| 26753 | 26784 | .ty = dst_elem_type, |
| 26754 | 26785 | } }; |
| 26755 | 26786 | break :src_array_ptr; |
| ... | ... | @@ -26757,14 +26788,14 @@ fn coerceExtra( |
| 26757 | 26788 | } else { |
| 26758 | 26789 | in_memory_result = .{ .ptr_sentinel = .{ |
| 26759 | 26790 | .actual = Value.@"unreachable", |
| 26760 | | .wanted = dest_sent, |
| 26791 | .wanted = dest_info.sentinel.toValue(), |
| 26761 | 26792 | .ty = dst_elem_type, |
| 26762 | 26793 | } }; |
| 26763 | 26794 | break :src_array_ptr; |
| 26764 | 26795 | } |
| 26765 | 26796 | } |
| 26766 | 26797 | |
| 26767 | | switch (dest_info.size) { |
| 26798 | switch (dest_info.flags.size) { |
| 26768 | 26799 | .Slice => { |
| 26769 | 26800 | // *[N]T to []T |
| 26770 | 26801 | return sema.coerceArrayPtrToSlice(block, dest_ty, inst, inst_src); |
| ... | ... | @@ -26787,8 +26818,8 @@ fn coerceExtra( |
| 26787 | 26818 | // In this case we must add a safety check because the C pointer |
| 26788 | 26819 | // could be null. |
| 26789 | 26820 | const src_elem_ty = inst_ty.childType(mod); |
| 26790 | | const dest_is_mut = dest_info.mutable; |
| 26791 | | const dst_elem_type = dest_info.pointee_type; |
| 26821 | const dest_is_mut = !dest_info.flags.is_const; |
| 26822 | const dst_elem_type = dest_info.child.toType(); |
| 26792 | 26823 | switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) { |
| 26793 | 26824 | .ok => {}, |
| 26794 | 26825 | else => break :src_c_ptr, |
| ... | ... | @@ -26798,7 +26829,7 @@ fn coerceExtra( |
| 26798 | 26829 | |
| 26799 | 26830 | // cast from *T and [*]T to *anyopaque |
| 26800 | 26831 | // but don't do it if the source type is a double pointer |
| 26801 | | if (dest_info.pointee_type.toIntern() == .anyopaque_type and inst_ty.zigTypeTag(mod) == .Pointer) to_anyopaque: { |
| 26832 | if (dest_info.child == .anyopaque_type and inst_ty.zigTypeTag(mod) == .Pointer) to_anyopaque: { |
| 26802 | 26833 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer; |
| 26803 | 26834 | const elem_ty = inst_ty.elemType2(mod); |
| 26804 | 26835 | if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) { |
| ... | ... | @@ -26819,7 +26850,7 @@ fn coerceExtra( |
| 26819 | 26850 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); |
| 26820 | 26851 | } |
| 26821 | 26852 | |
| 26822 | | switch (dest_info.size) { |
| 26853 | switch (dest_info.flags.size) { |
| 26823 | 26854 | // coercion to C pointer |
| 26824 | 26855 | .C => switch (inst_ty.zigTypeTag(mod)) { |
| 26825 | 26856 | .Null => { |
| ... | ... | @@ -26852,9 +26883,9 @@ fn coerceExtra( |
| 26852 | 26883 | const inst_info = inst_ty.ptrInfo(mod); |
| 26853 | 26884 | switch (try sema.coerceInMemoryAllowed( |
| 26854 | 26885 | block, |
| 26855 | | dest_info.pointee_type, |
| 26856 | | inst_info.pointee_type, |
| 26857 | | dest_info.mutable, |
| 26886 | dest_info.child.toType(), |
| 26887 | inst_info.child.toType(), |
| 26888 | !dest_info.flags.is_const, |
| 26858 | 26889 | target, |
| 26859 | 26890 | dest_ty_src, |
| 26860 | 26891 | inst_src, |
| ... | ... | @@ -26862,10 +26893,10 @@ fn coerceExtra( |
| 26862 | 26893 | .ok => {}, |
| 26863 | 26894 | else => break :p, |
| 26864 | 26895 | } |
| 26865 | | if (inst_info.size == .Slice) { |
| 26866 | | assert(dest_info.sentinel == null); |
| 26867 | | if (inst_info.sentinel == null or |
| 26868 | | !inst_info.sentinel.?.eql(try mod.intValue(dest_info.pointee_type, 0), dest_info.pointee_type, mod)) |
| 26896 | if (inst_info.flags.size == .Slice) { |
| 26897 | assert(dest_info.sentinel == .none); |
| 26898 | if (inst_info.sentinel == .none or |
| 26899 | inst_info.sentinel != (try mod.intValue(inst_info.child.toType(), 0)).toIntern()) |
| 26869 | 26900 | break :p; |
| 26870 | 26901 | |
| 26871 | 26902 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); |
| ... | ... | @@ -26875,7 +26906,7 @@ fn coerceExtra( |
| 26875 | 26906 | }, |
| 26876 | 26907 | else => {}, |
| 26877 | 26908 | }, |
| 26878 | | .One => switch (dest_info.pointee_type.zigTypeTag(mod)) { |
| 26909 | .One => switch (dest_info.child.toType().zigTypeTag(mod)) { |
| 26879 | 26910 | .Union => { |
| 26880 | 26911 | // pointer to anonymous struct to pointer to union |
| 26881 | 26912 | if (inst_ty.isSinglePointer(mod) and |
| ... | ... | @@ -26929,16 +26960,16 @@ fn coerceExtra( |
| 26929 | 26960 | // we use a dummy pointer value with the required alignment. |
| 26930 | 26961 | return sema.addConstant(dest_ty, (try mod.intern(.{ .ptr = .{ |
| 26931 | 26962 | .ty = dest_ty.toIntern(), |
| 26932 | | .addr = .{ .int = (if (dest_info.@"align" != 0) |
| 26933 | | try mod.intValue(Type.usize, dest_info.@"align") |
| 26963 | .addr = .{ .int = (if (dest_info.flags.alignment != .none) |
| 26964 | try mod.intValue(Type.usize, dest_info.flags.alignment.toByteUnitsOptional().?) |
| 26934 | 26965 | else |
| 26935 | | try mod.getCoerced(try dest_info.pointee_type.lazyAbiAlignment(mod), Type.usize)).toIntern() }, |
| 26966 | try mod.getCoerced(try dest_info.child.toType().lazyAbiAlignment(mod), Type.usize)).toIntern() }, |
| 26936 | 26967 | .len = (try mod.intValue(Type.usize, 0)).toIntern(), |
| 26937 | 26968 | } })).toValue()); |
| 26938 | 26969 | } |
| 26939 | 26970 | |
| 26940 | 26971 | // pointer to tuple to slice |
| 26941 | | if (dest_info.mutable) { |
| 26972 | if (!dest_info.flags.is_const) { |
| 26942 | 26973 | const err_msg = err_msg: { |
| 26943 | 26974 | const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(mod)}); |
| 26944 | 26975 | errdefer err_msg.deinit(sema.gpa); |
| ... | ... | @@ -26956,9 +26987,9 @@ fn coerceExtra( |
| 26956 | 26987 | |
| 26957 | 26988 | switch (try sema.coerceInMemoryAllowed( |
| 26958 | 26989 | block, |
| 26959 | | dest_info.pointee_type, |
| 26960 | | inst_info.pointee_type, |
| 26961 | | dest_info.mutable, |
| 26990 | dest_info.child.toType(), |
| 26991 | inst_info.child.toType(), |
| 26992 | !dest_info.flags.is_const, |
| 26962 | 26993 | target, |
| 26963 | 26994 | dest_ty_src, |
| 26964 | 26995 | inst_src, |
| ... | ... | @@ -26967,12 +26998,9 @@ fn coerceExtra( |
| 26967 | 26998 | else => break :p, |
| 26968 | 26999 | } |
| 26969 | 27000 | |
| 26970 | | if (dest_info.sentinel == null or inst_info.sentinel == null or |
| 26971 | | !dest_info.sentinel.?.eql( |
| 26972 | | try mod.getCoerced(inst_info.sentinel.?, dest_info.pointee_type), |
| 26973 | | dest_info.pointee_type, |
| 26974 | | mod, |
| 26975 | | )) |
| 27001 | if (dest_info.sentinel == .none or inst_info.sentinel == .none or |
| 27002 | dest_info.sentinel != |
| 27003 | try mod.intern_pool.getCoerced(sema.gpa, inst_info.sentinel, dest_info.child)) |
| 26976 | 27004 | break :p; |
| 26977 | 27005 | |
| 26978 | 27006 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); |
| ... | ... | @@ -28098,41 +28126,41 @@ fn coerceInMemoryAllowedPtrs( |
| 28098 | 28126 | const dest_info = dest_ptr_ty.ptrInfo(mod); |
| 28099 | 28127 | const src_info = src_ptr_ty.ptrInfo(mod); |
| 28100 | 28128 | |
| 28101 | | const ok_ptr_size = src_info.size == dest_info.size or |
| 28102 | | src_info.size == .C or dest_info.size == .C; |
| 28129 | const ok_ptr_size = src_info.flags.size == dest_info.flags.size or |
| 28130 | src_info.flags.size == .C or dest_info.flags.size == .C; |
| 28103 | 28131 | if (!ok_ptr_size) { |
| 28104 | 28132 | return InMemoryCoercionResult{ .ptr_size = .{ |
| 28105 | | .actual = src_info.size, |
| 28106 | | .wanted = dest_info.size, |
| 28133 | .actual = src_info.flags.size, |
| 28134 | .wanted = dest_info.flags.size, |
| 28107 | 28135 | } }; |
| 28108 | 28136 | } |
| 28109 | 28137 | |
| 28110 | 28138 | const ok_cv_qualifiers = |
| 28111 | | (src_info.mutable or !dest_info.mutable) and |
| 28112 | | (!src_info.@"volatile" or dest_info.@"volatile"); |
| 28139 | (!src_info.flags.is_const or dest_info.flags.is_const) and |
| 28140 | (!src_info.flags.is_volatile or dest_info.flags.is_volatile); |
| 28113 | 28141 | |
| 28114 | 28142 | if (!ok_cv_qualifiers) { |
| 28115 | 28143 | return InMemoryCoercionResult{ .ptr_qualifiers = .{ |
| 28116 | | .actual_const = !src_info.mutable, |
| 28117 | | .wanted_const = !dest_info.mutable, |
| 28118 | | .actual_volatile = src_info.@"volatile", |
| 28119 | | .wanted_volatile = dest_info.@"volatile", |
| 28144 | .actual_const = src_info.flags.is_const, |
| 28145 | .wanted_const = dest_info.flags.is_const, |
| 28146 | .actual_volatile = src_info.flags.is_volatile, |
| 28147 | .wanted_volatile = dest_info.flags.is_volatile, |
| 28120 | 28148 | } }; |
| 28121 | 28149 | } |
| 28122 | 28150 | |
| 28123 | | if (dest_info.@"addrspace" != src_info.@"addrspace") { |
| 28151 | if (dest_info.flags.address_space != src_info.flags.address_space) { |
| 28124 | 28152 | return InMemoryCoercionResult{ .ptr_addrspace = .{ |
| 28125 | | .actual = src_info.@"addrspace", |
| 28126 | | .wanted = dest_info.@"addrspace", |
| 28153 | .actual = src_info.flags.address_space, |
| 28154 | .wanted = dest_info.flags.address_space, |
| 28127 | 28155 | } }; |
| 28128 | 28156 | } |
| 28129 | 28157 | |
| 28130 | | const child = try sema.coerceInMemoryAllowed(block, dest_info.pointee_type, src_info.pointee_type, dest_info.mutable, target, dest_src, src_src); |
| 28158 | const child = try sema.coerceInMemoryAllowed(block, dest_info.child.toType(), src_info.child.toType(), !dest_info.flags.is_const, target, dest_src, src_src); |
| 28131 | 28159 | if (child != .ok) { |
| 28132 | 28160 | return InMemoryCoercionResult{ .ptr_child = .{ |
| 28133 | 28161 | .child = try child.dupe(sema.arena), |
| 28134 | | .actual = src_info.pointee_type, |
| 28135 | | .wanted = dest_info.pointee_type, |
| 28162 | .actual = src_info.child.toType(), |
| 28163 | .wanted = dest_info.child.toType(), |
| 28136 | 28164 | } }; |
| 28137 | 28165 | } |
| 28138 | 28166 | |
| ... | ... | @@ -28149,28 +28177,31 @@ fn coerceInMemoryAllowedPtrs( |
| 28149 | 28177 | } }; |
| 28150 | 28178 | } |
| 28151 | 28179 | |
| 28152 | | if (src_info.host_size != dest_info.host_size or |
| 28153 | | src_info.bit_offset != dest_info.bit_offset) |
| 28180 | if (src_info.packed_offset.host_size != dest_info.packed_offset.host_size or |
| 28181 | src_info.packed_offset.bit_offset != dest_info.packed_offset.bit_offset) |
| 28154 | 28182 | { |
| 28155 | 28183 | return InMemoryCoercionResult{ .ptr_bit_range = .{ |
| 28156 | | .actual_host = src_info.host_size, |
| 28157 | | .wanted_host = dest_info.host_size, |
| 28158 | | .actual_offset = src_info.bit_offset, |
| 28159 | | .wanted_offset = dest_info.bit_offset, |
| 28184 | .actual_host = src_info.packed_offset.host_size, |
| 28185 | .wanted_host = dest_info.packed_offset.host_size, |
| 28186 | .actual_offset = src_info.packed_offset.bit_offset, |
| 28187 | .wanted_offset = dest_info.packed_offset.bit_offset, |
| 28160 | 28188 | } }; |
| 28161 | 28189 | } |
| 28162 | 28190 | |
| 28163 | | const ok_sent = dest_info.sentinel == null or src_info.size == .C or |
| 28164 | | (src_info.sentinel != null and dest_info.sentinel.?.eql( |
| 28165 | | try mod.getCoerced(src_info.sentinel.?, dest_info.pointee_type), |
| 28166 | | dest_info.pointee_type, |
| 28167 | | sema.mod, |
| 28168 | | )); |
| 28191 | const ok_sent = dest_info.sentinel == .none or src_info.flags.size == .C or |
| 28192 | (src_info.sentinel != .none and |
| 28193 | dest_info.sentinel == try mod.intern_pool.getCoerced(sema.gpa, src_info.sentinel, dest_info.child)); |
| 28169 | 28194 | if (!ok_sent) { |
| 28170 | 28195 | return InMemoryCoercionResult{ .ptr_sentinel = .{ |
| 28171 | | .actual = src_info.sentinel orelse Value.@"unreachable", |
| 28172 | | .wanted = dest_info.sentinel orelse Value.@"unreachable", |
| 28173 | | .ty = dest_info.pointee_type, |
| 28196 | .actual = switch (src_info.sentinel) { |
| 28197 | .none => Value.@"unreachable", |
| 28198 | else => src_info.sentinel.toValue(), |
| 28199 | }, |
| 28200 | .wanted = switch (dest_info.sentinel) { |
| 28201 | .none => Value.@"unreachable", |
| 28202 | else => dest_info.sentinel.toValue(), |
| 28203 | }, |
| 28204 | .ty = dest_info.child.toType(), |
| 28174 | 28205 | } }; |
| 28175 | 28206 | } |
| 28176 | 28207 | |
| ... | ... | @@ -28178,22 +28209,14 @@ fn coerceInMemoryAllowedPtrs( |
| 28178 | 28209 | // In this case, if they share the same child type, no need to resolve |
| 28179 | 28210 | // pointee type alignment. Otherwise both pointee types must have their alignment |
| 28180 | 28211 | // resolved and we compare the alignment numerically. |
| 28181 | | alignment: { |
| 28182 | | if (src_info.@"align" == 0 and dest_info.@"align" == 0 and |
| 28183 | | dest_info.pointee_type.eql(src_info.pointee_type, sema.mod)) |
| 28184 | | { |
| 28185 | | break :alignment; |
| 28186 | | } |
| 28187 | | |
| 28188 | | const src_align = if (src_info.@"align" != 0) |
| 28189 | | src_info.@"align" |
| 28190 | | else |
| 28191 | | src_info.pointee_type.abiAlignment(mod); |
| 28212 | if (src_info.flags.alignment != .none or dest_info.flags.alignment != .none or |
| 28213 | dest_info.child != src_info.child) |
| 28214 | { |
| 28215 | const src_align = src_info.flags.alignment.toByteUnitsOptional() orelse |
| 28216 | src_info.child.toType().abiAlignment(mod); |
| 28192 | 28217 | |
| 28193 | | const dest_align = if (dest_info.@"align" != 0) |
| 28194 | | dest_info.@"align" |
| 28195 | | else |
| 28196 | | dest_info.pointee_type.abiAlignment(mod); |
| 28218 | const dest_align = dest_info.flags.alignment.toByteUnitsOptional() orelse |
| 28219 | dest_info.child.toType().abiAlignment(mod); |
| 28197 | 28220 | |
| 28198 | 28221 | if (dest_align > src_align) { |
| 28199 | 28222 | return InMemoryCoercionResult{ .ptr_alignment = .{ |
| ... | ... | @@ -28201,8 +28224,6 @@ fn coerceInMemoryAllowedPtrs( |
| 28201 | 28224 | .wanted = dest_align, |
| 28202 | 28225 | } }; |
| 28203 | 28226 | } |
| 28204 | | |
| 28205 | | break :alignment; |
| 28206 | 28227 | } |
| 28207 | 28228 | |
| 28208 | 28229 | return .ok; |
| ... | ... | @@ -28367,7 +28388,7 @@ fn storePtr2( |
| 28367 | 28388 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 28368 | 28389 | try sema.queueFullTypeResolution(elem_ty); |
| 28369 | 28390 | |
| 28370 | | if (ptr_ty.ptrInfo(mod).vector_index == .runtime) { |
| 28391 | if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) { |
| 28371 | 28392 | const ptr_inst = Air.refToIndex(ptr).?; |
| 28372 | 28393 | const air_tags = sema.air_instructions.items(.tag); |
| 28373 | 28394 | if (air_tags[ptr_inst] == .ptr_elem_ptr) { |
| ... | ... | @@ -29219,11 +29240,14 @@ fn beginComptimePtrLoad( |
| 29219 | 29240 | // It's possible that we're loading a [N]T, in which case we'd like to slice |
| 29220 | 29241 | // the pointee array directly from our parent array. |
| 29221 | 29242 | if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, mod)) { |
| 29222 | | const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod)); |
| 29243 | const len = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod)); |
| 29223 | 29244 | const elem_idx = try sema.usizeCast(block, src, elem_ptr.index); |
| 29224 | | deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{ |
| 29225 | | .ty = try Type.array(sema.arena, N, null, elem_ty, mod), |
| 29226 | | .val = try array_tv.val.sliceArray(mod, sema.arena, elem_idx, elem_idx + N), |
| 29245 | deref.pointee = if (elem_ptr.index + len <= check_len) TypedValue{ |
| 29246 | .ty = try mod.arrayType(.{ |
| 29247 | .len = len, |
| 29248 | .child = elem_ty.toIntern(), |
| 29249 | }), |
| 29250 | .val = try array_tv.val.sliceArray(mod, sema.arena, elem_idx, elem_idx + len), |
| 29227 | 29251 | } else null; |
| 29228 | 29252 | break :blk deref; |
| 29229 | 29253 | } |
| ... | ... | @@ -29410,42 +29434,38 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul |
| 29410 | 29434 | const mod = sema.mod; |
| 29411 | 29435 | const dest_info = dest_ty.ptrInfo(mod); |
| 29412 | 29436 | const inst_info = inst_ty.ptrInfo(mod); |
| 29413 | | const len0 = (inst_info.pointee_type.zigTypeTag(mod) == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel(mod) == 0 or |
| 29414 | | (inst_info.pointee_type.arrayLen(mod) == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or |
| 29415 | | (inst_info.pointee_type.isTuple(mod) and inst_info.pointee_type.structFieldCount(mod) == 0); |
| 29437 | const len0 = (inst_info.child.toType().zigTypeTag(mod) == .Array and (inst_info.child.toType().arrayLenIncludingSentinel(mod) == 0 or |
| 29438 | (inst_info.child.toType().arrayLen(mod) == 0 and dest_info.sentinel == .none and dest_info.flags.size != .C and dest_info.flags.size != .Many))) or |
| 29439 | (inst_info.child.toType().isTuple(mod) and inst_info.child.toType().structFieldCount(mod) == 0); |
| 29416 | 29440 | |
| 29417 | 29441 | const ok_cv_qualifiers = |
| 29418 | | ((inst_info.mutable or !dest_info.mutable) or len0) and |
| 29419 | | (!inst_info.@"volatile" or dest_info.@"volatile"); |
| 29442 | ((!inst_info.flags.is_const or dest_info.flags.is_const) or len0) and |
| 29443 | (!inst_info.flags.is_volatile or dest_info.flags.is_volatile); |
| 29420 | 29444 | |
| 29421 | 29445 | if (!ok_cv_qualifiers) { |
| 29422 | 29446 | in_memory_result.* = .{ .ptr_qualifiers = .{ |
| 29423 | | .actual_const = !inst_info.mutable, |
| 29424 | | .wanted_const = !dest_info.mutable, |
| 29425 | | .actual_volatile = inst_info.@"volatile", |
| 29426 | | .wanted_volatile = dest_info.@"volatile", |
| 29447 | .actual_const = inst_info.flags.is_const, |
| 29448 | .wanted_const = dest_info.flags.is_const, |
| 29449 | .actual_volatile = inst_info.flags.is_volatile, |
| 29450 | .wanted_volatile = dest_info.flags.is_volatile, |
| 29427 | 29451 | } }; |
| 29428 | 29452 | return false; |
| 29429 | 29453 | } |
| 29430 | | if (dest_info.@"addrspace" != inst_info.@"addrspace") { |
| 29454 | if (dest_info.flags.address_space != inst_info.flags.address_space) { |
| 29431 | 29455 | in_memory_result.* = .{ .ptr_addrspace = .{ |
| 29432 | | .actual = inst_info.@"addrspace", |
| 29433 | | .wanted = dest_info.@"addrspace", |
| 29456 | .actual = inst_info.flags.address_space, |
| 29457 | .wanted = dest_info.flags.address_space, |
| 29434 | 29458 | } }; |
| 29435 | 29459 | return false; |
| 29436 | 29460 | } |
| 29437 | | if (inst_info.@"align" == 0 and dest_info.@"align" == 0) return true; |
| 29461 | if (inst_info.flags.alignment == .none and dest_info.flags.alignment == .none) return true; |
| 29438 | 29462 | if (len0) return true; |
| 29439 | 29463 | |
| 29440 | | const inst_align = if (inst_info.@"align" != 0) |
| 29441 | | inst_info.@"align" |
| 29442 | | else |
| 29443 | | inst_info.pointee_type.abiAlignment(mod); |
| 29464 | const inst_align = inst_info.flags.alignment.toByteUnitsOptional() orelse |
| 29465 | inst_info.child.toType().abiAlignment(mod); |
| 29444 | 29466 | |
| 29445 | | const dest_align = if (dest_info.@"align" != 0) |
| 29446 | | dest_info.@"align" |
| 29447 | | else |
| 29448 | | dest_info.pointee_type.abiAlignment(mod); |
| 29467 | const dest_align = dest_info.flags.alignment.toByteUnitsOptional() orelse |
| 29468 | dest_info.child.toType().abiAlignment(mod); |
| 29449 | 29469 | |
| 29450 | 29470 | if (dest_align > inst_align) { |
| 29451 | 29471 | in_memory_result.* = .{ .ptr_alignment = .{ |
| ... | ... | @@ -29882,9 +29902,13 @@ fn coerceTupleToSlicePtrs( |
| 29882 | 29902 | const tuple_ty = sema.typeOf(ptr_tuple).childType(mod); |
| 29883 | 29903 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); |
| 29884 | 29904 | const slice_info = slice_ty.ptrInfo(mod); |
| 29885 | | const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(mod), slice_info.sentinel, slice_info.pointee_type, sema.mod); |
| 29905 | const array_ty = try mod.arrayType(.{ |
| 29906 | .len = tuple_ty.structFieldCount(mod), |
| 29907 | .sentinel = slice_info.sentinel, |
| 29908 | .child = slice_info.child, |
| 29909 | }); |
| 29886 | 29910 | const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src); |
| 29887 | | if (slice_info.@"align" != 0) { |
| 29911 | if (slice_info.flags.alignment != .none) { |
| 29888 | 29912 | return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{}); |
| 29889 | 29913 | } |
| 29890 | 29914 | const ptr_array = try sema.analyzeRef(block, slice_ty_src, array_inst); |
| ... | ... | @@ -29903,9 +29927,9 @@ fn coerceTupleToArrayPtrs( |
| 29903 | 29927 | const mod = sema.mod; |
| 29904 | 29928 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); |
| 29905 | 29929 | const ptr_info = ptr_array_ty.ptrInfo(mod); |
| 29906 | | const array_ty = ptr_info.pointee_type; |
| 29930 | const array_ty = ptr_info.child.toType(); |
| 29907 | 29931 | const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src); |
| 29908 | | if (ptr_info.@"align" != 0) { |
| 29932 | if (ptr_info.flags.alignment != .none) { |
| 29909 | 29933 | return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{}); |
| 29910 | 29934 | } |
| 29911 | 29935 | const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst); |
| ... | ... | @@ -30244,7 +30268,7 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value { |
| 30244 | 30268 | const decl = try anon_decl.finish( |
| 30245 | 30269 | ty, |
| 30246 | 30270 | val, |
| 30247 | | 0, // default alignment |
| 30271 | .none, // default alignment |
| 30248 | 30272 | ); |
| 30249 | 30273 | try sema.maybeQueueFuncBodyAnalysis(decl); |
| 30250 | 30274 | try mod.declareDeclDependency(sema.owner_decl_index, decl); |
| ... | ... | @@ -30285,7 +30309,7 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo |
| 30285 | 30309 | const ptr_ty = try mod.ptrType(.{ |
| 30286 | 30310 | .child = decl_tv.ty.toIntern(), |
| 30287 | 30311 | .flags = .{ |
| 30288 | | .alignment = InternPool.Alignment.fromByteUnits(decl.@"align"), |
| 30312 | .alignment = decl.alignment, |
| 30289 | 30313 | .is_const = if (decl.val.getVariable(mod)) |variable| variable.is_const else true, |
| 30290 | 30314 | .address_space = decl.@"addrspace", |
| 30291 | 30315 | }, |
| ... | ... | @@ -30315,12 +30339,13 @@ fn analyzeRef( |
| 30315 | 30339 | src: LazySrcLoc, |
| 30316 | 30340 | operand: Air.Inst.Ref, |
| 30317 | 30341 | ) CompileError!Air.Inst.Ref { |
| 30342 | const mod = sema.mod; |
| 30318 | 30343 | const operand_ty = sema.typeOf(operand); |
| 30319 | 30344 | |
| 30320 | 30345 | if (try sema.resolveMaybeUndefVal(operand)) |val| { |
| 30321 | | switch (sema.mod.intern_pool.indexToKey(val.toIntern())) { |
| 30346 | switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 30322 | 30347 | .extern_func => |extern_func| return sema.analyzeDeclRef(extern_func.decl), |
| 30323 | | .func => |func| return sema.analyzeDeclRef(sema.mod.funcPtr(func.index).owner_decl), |
| 30348 | .func => |func| return sema.analyzeDeclRef(mod.funcPtr(func.index).owner_decl), |
| 30324 | 30349 | else => {}, |
| 30325 | 30350 | } |
| 30326 | 30351 | var anon_decl = try block.startAnonDecl(); |
| ... | ... | @@ -30328,20 +30353,22 @@ fn analyzeRef( |
| 30328 | 30353 | return sema.analyzeDeclRef(try anon_decl.finish( |
| 30329 | 30354 | operand_ty, |
| 30330 | 30355 | val, |
| 30331 | | 0, // default alignment |
| 30356 | .none, // default alignment |
| 30332 | 30357 | )); |
| 30333 | 30358 | } |
| 30334 | 30359 | |
| 30335 | 30360 | try sema.requireRuntimeBlock(block, src, null); |
| 30336 | | const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local); |
| 30337 | | const ptr_type = try Type.ptr(sema.arena, sema.mod, .{ |
| 30338 | | .pointee_type = operand_ty, |
| 30339 | | .mutable = false, |
| 30340 | | .@"addrspace" = address_space, |
| 30361 | const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local); |
| 30362 | const ptr_type = try mod.ptrType(.{ |
| 30363 | .child = operand_ty.toIntern(), |
| 30364 | .flags = .{ |
| 30365 | .is_const = true, |
| 30366 | .address_space = address_space, |
| 30367 | }, |
| 30341 | 30368 | }); |
| 30342 | | const mut_ptr_type = try Type.ptr(sema.arena, sema.mod, .{ |
| 30343 | | .pointee_type = operand_ty, |
| 30344 | | .@"addrspace" = address_space, |
| 30369 | const mut_ptr_type = try mod.ptrType(.{ |
| 30370 | .child = operand_ty.toIntern(), |
| 30371 | .flags = .{ .address_space = address_space }, |
| 30345 | 30372 | }); |
| 30346 | 30373 | const alloc = try block.addTy(.alloc, mut_ptr_type); |
| 30347 | 30374 | try sema.storePtr(block, src, alloc, operand); |
| ... | ... | @@ -30374,7 +30401,7 @@ fn analyzeLoad( |
| 30374 | 30401 | } |
| 30375 | 30402 | } |
| 30376 | 30403 | |
| 30377 | | if (ptr_ty.ptrInfo(mod).vector_index == .runtime) { |
| 30404 | if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) { |
| 30378 | 30405 | const ptr_inst = Air.refToIndex(ptr).?; |
| 30379 | 30406 | const air_tags = sema.air_instructions.items(.tag); |
| 30380 | 30407 | if (air_tags[ptr_inst] == .ptr_elem_ptr) { |
| ... | ... | @@ -30900,20 +30927,24 @@ fn analyzeSlice( |
| 30900 | 30927 | const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len); |
| 30901 | 30928 | |
| 30902 | 30929 | const new_ptr_ty_info = new_ptr_ty.ptrInfo(mod); |
| 30903 | | const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize(mod) != .C; |
| 30930 | const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C; |
| 30904 | 30931 | |
| 30905 | 30932 | if (opt_new_len_val) |new_len_val| { |
| 30906 | 30933 | const new_len_int = new_len_val.toUnsignedInt(mod); |
| 30907 | 30934 | |
| 30908 | | const return_ty = try Type.ptr(sema.arena, mod, .{ |
| 30909 | | .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, mod), |
| 30910 | | .sentinel = null, |
| 30911 | | .@"align" = new_ptr_ty_info.@"align", |
| 30912 | | .@"addrspace" = new_ptr_ty_info.@"addrspace", |
| 30913 | | .mutable = new_ptr_ty_info.mutable, |
| 30914 | | .@"allowzero" = new_allowzero, |
| 30915 | | .@"volatile" = new_ptr_ty_info.@"volatile", |
| 30916 | | .size = .One, |
| 30935 | const return_ty = try mod.ptrType(.{ |
| 30936 | .child = (try mod.arrayType(.{ |
| 30937 | .len = new_len_int, |
| 30938 | .sentinel = if (sentinel) |s| s.toIntern() else .none, |
| 30939 | .child = elem_ty.toIntern(), |
| 30940 | })).toIntern(), |
| 30941 | .flags = .{ |
| 30942 | .alignment = new_ptr_ty_info.flags.alignment, |
| 30943 | .is_const = new_ptr_ty_info.flags.is_const, |
| 30944 | .is_allowzero = new_allowzero, |
| 30945 | .is_volatile = new_ptr_ty_info.flags.is_volatile, |
| 30946 | .address_space = new_ptr_ty_info.flags.address_space, |
| 30947 | }, |
| 30917 | 30948 | }); |
| 30918 | 30949 | |
| 30919 | 30950 | const opt_new_ptr_val = try sema.resolveMaybeUndefVal(new_ptr); |
| ... | ... | @@ -30962,15 +30993,17 @@ fn analyzeSlice( |
| 30962 | 30993 | return sema.fail(block, src, "non-zero length slice of undefined pointer", .{}); |
| 30963 | 30994 | } |
| 30964 | 30995 | |
| 30965 | | const return_ty = try Type.ptr(sema.arena, mod, .{ |
| 30966 | | .pointee_type = elem_ty, |
| 30967 | | .sentinel = sentinel, |
| 30968 | | .@"align" = new_ptr_ty_info.@"align", |
| 30969 | | .@"addrspace" = new_ptr_ty_info.@"addrspace", |
| 30970 | | .mutable = new_ptr_ty_info.mutable, |
| 30971 | | .@"allowzero" = new_allowzero, |
| 30972 | | .@"volatile" = new_ptr_ty_info.@"volatile", |
| 30973 | | .size = .Slice, |
| 30996 | const return_ty = try mod.ptrType(.{ |
| 30997 | .child = elem_ty.toIntern(), |
| 30998 | .sentinel = if (sentinel) |s| s.toIntern() else .none, |
| 30999 | .flags = .{ |
| 31000 | .size = .Slice, |
| 31001 | .alignment = new_ptr_ty_info.flags.alignment, |
| 31002 | .is_const = new_ptr_ty_info.flags.is_const, |
| 31003 | .is_volatile = new_ptr_ty_info.flags.is_volatile, |
| 31004 | .is_allowzero = new_allowzero, |
| 31005 | .address_space = new_ptr_ty_info.flags.address_space, |
| 31006 | }, |
| 30974 | 31007 | }); |
| 30975 | 31008 | |
| 30976 | 31009 | try sema.requireRuntimeBlock(block, src, runtime_src.?); |
| ... | ... | @@ -31716,7 +31749,7 @@ const PeerResolveStrategy = enum { |
| 31716 | 31749 | .Int => .fixed_int, |
| 31717 | 31750 | .ComptimeFloat => .comptime_float, |
| 31718 | 31751 | .Float => .fixed_float, |
| 31719 | | .Pointer => if (ty.ptrInfo(mod).size == .C) .c_ptr else .ptr, |
| 31752 | .Pointer => if (ty.ptrInfo(mod).flags.size == .C) .c_ptr else .ptr, |
| 31720 | 31753 | .Array => .array, |
| 31721 | 31754 | .Vector => .vector, |
| 31722 | 31755 | .Optional => .optional, |
| ... | ... | @@ -32141,7 +32174,7 @@ fn resolvePeerTypesInner( |
| 32141 | 32174 | }, |
| 32142 | 32175 | |
| 32143 | 32176 | .c_ptr => { |
| 32144 | | var opt_ptr_info: ?Type.Payload.Pointer.Data = null; |
| 32177 | var opt_ptr_info: ?InternPool.Key.PtrType = null; |
| 32145 | 32178 | var first_idx: usize = undefined; |
| 32146 | 32179 | for (peer_tys, peer_vals, 0..) |opt_ty, opt_val, i| { |
| 32147 | 32180 | const ty = opt_ty orelse continue; |
| ... | ... | @@ -32172,42 +32205,47 @@ fn resolvePeerTypesInner( |
| 32172 | 32205 | |
| 32173 | 32206 | var ptr_info = opt_ptr_info orelse { |
| 32174 | 32207 | opt_ptr_info = peer_info; |
| 32175 | | opt_ptr_info.?.size = .C; |
| 32208 | opt_ptr_info.?.flags.size = .C; |
| 32176 | 32209 | first_idx = i; |
| 32177 | 32210 | continue; |
| 32178 | 32211 | }; |
| 32179 | 32212 | |
| 32180 | 32213 | // Try peer -> cur, then cur -> peer |
| 32181 | | ptr_info.pointee_type = (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) orelse { |
| 32214 | ptr_info.child = ((try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) orelse { |
| 32182 | 32215 | return .{ .conflict = .{ |
| 32183 | 32216 | .peer_idx_a = first_idx, |
| 32184 | 32217 | .peer_idx_b = i, |
| 32185 | 32218 | } }; |
| 32186 | | }; |
| 32219 | }).toIntern(); |
| 32187 | 32220 | |
| 32188 | | if (ptr_info.sentinel != null and peer_info.sentinel != null) { |
| 32189 | | const peer_sent = try mod.getCoerced(ptr_info.sentinel.?, ptr_info.pointee_type); |
| 32190 | | const ptr_sent = try mod.getCoerced(peer_info.sentinel.?, ptr_info.pointee_type); |
| 32191 | | if (ptr_sent.eql(peer_sent, ptr_info.pointee_type, mod)) { |
| 32221 | if (ptr_info.sentinel != .none and peer_info.sentinel != .none) { |
| 32222 | const peer_sent = try mod.intern_pool.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child); |
| 32223 | const ptr_sent = try mod.intern_pool.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child); |
| 32224 | if (ptr_sent == peer_sent) { |
| 32192 | 32225 | ptr_info.sentinel = ptr_sent; |
| 32193 | 32226 | } else { |
| 32194 | | ptr_info.sentinel = null; |
| 32227 | ptr_info.sentinel = .none; |
| 32195 | 32228 | } |
| 32196 | 32229 | } else { |
| 32197 | | ptr_info.sentinel = null; |
| 32230 | ptr_info.sentinel = .none; |
| 32198 | 32231 | } |
| 32199 | 32232 | |
| 32200 | | // Note that the align can be always non-zero; Type.ptr will canonicalize it |
| 32201 | | ptr_info.@"align" = @min(ptr_info.alignment(mod), peer_info.alignment(mod)); |
| 32202 | | if (ptr_info.@"addrspace" != peer_info.@"addrspace") { |
| 32233 | // Note that the align can be always non-zero; Module.ptrType will canonicalize it |
| 32234 | ptr_info.flags.alignment = Alignment.fromByteUnits(@min( |
| 32235 | ptr_info.flags.alignment.toByteUnitsOptional() orelse |
| 32236 | ptr_info.child.toType().abiAlignment(mod), |
| 32237 | peer_info.flags.alignment.toByteUnitsOptional() orelse |
| 32238 | peer_info.child.toType().abiAlignment(mod), |
| 32239 | )); |
| 32240 | if (ptr_info.flags.address_space != peer_info.flags.address_space) { |
| 32203 | 32241 | return .{ .conflict = .{ |
| 32204 | 32242 | .peer_idx_a = first_idx, |
| 32205 | 32243 | .peer_idx_b = i, |
| 32206 | 32244 | } }; |
| 32207 | 32245 | } |
| 32208 | 32246 | |
| 32209 | | if (ptr_info.bit_offset != peer_info.bit_offset or |
| 32210 | | ptr_info.host_size != peer_info.host_size) |
| 32247 | if (ptr_info.packed_offset.bit_offset != peer_info.packed_offset.bit_offset or |
| 32248 | ptr_info.packed_offset.host_size != peer_info.packed_offset.host_size) |
| 32211 | 32249 | { |
| 32212 | 32250 | return .{ .conflict = .{ |
| 32213 | 32251 | .peer_idx_a = first_idx, |
| ... | ... | @@ -32215,12 +32253,12 @@ fn resolvePeerTypesInner( |
| 32215 | 32253 | } }; |
| 32216 | 32254 | } |
| 32217 | 32255 | |
| 32218 | | ptr_info.mutable = ptr_info.mutable and peer_info.mutable; |
| 32219 | | ptr_info.@"volatile" = ptr_info.@"volatile" or peer_info.@"volatile"; |
| 32256 | ptr_info.flags.is_const = ptr_info.flags.is_const or peer_info.flags.is_const; |
| 32257 | ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile; |
| 32220 | 32258 | |
| 32221 | 32259 | opt_ptr_info = ptr_info; |
| 32222 | 32260 | } |
| 32223 | | return .{ .success = try Type.ptr(sema.arena, mod, opt_ptr_info.?) }; |
| 32261 | return .{ .success = try mod.ptrType(opt_ptr_info.?) }; |
| 32224 | 32262 | }, |
| 32225 | 32263 | |
| 32226 | 32264 | .ptr => { |
| ... | ... | @@ -32228,17 +32266,19 @@ fn resolvePeerTypesInner( |
| 32228 | 32266 | // if there were no actual slices. Else, we want the slice index to report a conflict. |
| 32229 | 32267 | var opt_slice_idx: ?usize = null; |
| 32230 | 32268 | |
| 32231 | | var opt_ptr_info: ?Type.Payload.Pointer.Data = null; |
| 32269 | var opt_ptr_info: ?InternPool.Key.PtrType = null; |
| 32232 | 32270 | var first_idx: usize = undefined; |
| 32233 | 32271 | var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error |
| 32234 | 32272 | |
| 32235 | 32273 | for (peer_tys, 0..) |opt_ty, i| { |
| 32236 | 32274 | const ty = opt_ty orelse continue; |
| 32237 | | const peer_info: Type.Payload.Pointer.Data = switch (ty.zigTypeTag(mod)) { |
| 32275 | const peer_info: InternPool.Key.PtrType = switch (ty.zigTypeTag(mod)) { |
| 32238 | 32276 | .Pointer => ty.ptrInfo(mod), |
| 32239 | 32277 | .Fn => .{ |
| 32240 | | .pointee_type = ty, |
| 32241 | | .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), |
| 32278 | .child = ty.toIntern(), |
| 32279 | .flags = .{ |
| 32280 | .address_space = target_util.defaultAddressSpace(target, .global_constant), |
| 32281 | }, |
| 32242 | 32282 | }, |
| 32243 | 32283 | else => return .{ .conflict = .{ |
| 32244 | 32284 | .peer_idx_a = strat_reason, |
| ... | ... | @@ -32246,7 +32286,7 @@ fn resolvePeerTypesInner( |
| 32246 | 32286 | } }, |
| 32247 | 32287 | }; |
| 32248 | 32288 | |
| 32249 | | switch (peer_info.size) { |
| 32289 | switch (peer_info.flags.size) { |
| 32250 | 32290 | .One, .Many => {}, |
| 32251 | 32291 | .Slice => opt_slice_idx = i, |
| 32252 | 32292 | .C => return .{ .conflict = .{ |
| ... | ... | @@ -32270,51 +32310,56 @@ fn resolvePeerTypesInner( |
| 32270 | 32310 | } }; |
| 32271 | 32311 | |
| 32272 | 32312 | // Note that the align can be always non-zero; Type.ptr will canonicalize it |
| 32273 | | ptr_info.@"align" = @min(ptr_info.alignment(mod), peer_info.alignment(mod)); |
| 32313 | ptr_info.flags.alignment = Alignment.fromByteUnits(@min( |
| 32314 | ptr_info.flags.alignment.toByteUnitsOptional() orelse |
| 32315 | ptr_info.child.toType().abiAlignment(mod), |
| 32316 | peer_info.flags.alignment.toByteUnitsOptional() orelse |
| 32317 | peer_info.child.toType().abiAlignment(mod), |
| 32318 | )); |
| 32274 | 32319 | |
| 32275 | | if (ptr_info.@"addrspace" != peer_info.@"addrspace") { |
| 32320 | if (ptr_info.flags.address_space != peer_info.flags.address_space) { |
| 32276 | 32321 | return generic_err; |
| 32277 | 32322 | } |
| 32278 | 32323 | |
| 32279 | | if (ptr_info.bit_offset != peer_info.bit_offset or |
| 32280 | | ptr_info.host_size != peer_info.host_size) |
| 32324 | if (ptr_info.packed_offset.bit_offset != peer_info.packed_offset.bit_offset or |
| 32325 | ptr_info.packed_offset.host_size != peer_info.packed_offset.host_size) |
| 32281 | 32326 | { |
| 32282 | 32327 | return generic_err; |
| 32283 | 32328 | } |
| 32284 | 32329 | |
| 32285 | | ptr_info.mutable = ptr_info.mutable and peer_info.mutable; |
| 32286 | | ptr_info.@"volatile" = ptr_info.@"volatile" or peer_info.@"volatile"; |
| 32330 | ptr_info.flags.is_const = ptr_info.flags.is_const or peer_info.flags.is_const; |
| 32331 | ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile; |
| 32287 | 32332 | |
| 32288 | | const peer_sentinel: ?Value = switch (peer_info.size) { |
| 32289 | | .One => switch (peer_info.pointee_type.zigTypeTag(mod)) { |
| 32290 | | .Array => peer_info.pointee_type.sentinel(mod), |
| 32291 | | else => null, |
| 32333 | const peer_sentinel: InternPool.Index = switch (peer_info.flags.size) { |
| 32334 | .One => switch (mod.intern_pool.indexToKey(peer_info.child)) { |
| 32335 | .array_type => |array_type| array_type.sentinel, |
| 32336 | else => .none, |
| 32292 | 32337 | }, |
| 32293 | 32338 | .Many, .Slice => peer_info.sentinel, |
| 32294 | 32339 | .C => unreachable, |
| 32295 | 32340 | }; |
| 32296 | 32341 | |
| 32297 | | const cur_sentinel: ?Value = switch (ptr_info.size) { |
| 32298 | | .One => switch (ptr_info.pointee_type.zigTypeTag(mod)) { |
| 32299 | | .Array => ptr_info.pointee_type.sentinel(mod), |
| 32300 | | else => null, |
| 32342 | const cur_sentinel: InternPool.Index = switch (ptr_info.flags.size) { |
| 32343 | .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) { |
| 32344 | .array_type => |array_type| array_type.sentinel, |
| 32345 | else => .none, |
| 32301 | 32346 | }, |
| 32302 | 32347 | .Many, .Slice => ptr_info.sentinel, |
| 32303 | 32348 | .C => unreachable, |
| 32304 | 32349 | }; |
| 32305 | 32350 | |
| 32306 | 32351 | // We abstract array handling slightly so that tuple pointers can work like array pointers |
| 32307 | | const peer_pointee_array = sema.typeIsArrayLike(peer_info.pointee_type); |
| 32308 | | const cur_pointee_array = sema.typeIsArrayLike(ptr_info.pointee_type); |
| 32352 | const peer_pointee_array = sema.typeIsArrayLike(peer_info.child.toType()); |
| 32353 | const cur_pointee_array = sema.typeIsArrayLike(ptr_info.child.toType()); |
| 32309 | 32354 | |
| 32310 | 32355 | // This switch is just responsible for deciding the size and pointee (not including |
| 32311 | 32356 | // single-pointer array sentinel). |
| 32312 | 32357 | good: { |
| 32313 | | switch (peer_info.size) { |
| 32314 | | .One => switch (ptr_info.size) { |
| 32358 | switch (peer_info.flags.size) { |
| 32359 | .One => switch (ptr_info.flags.size) { |
| 32315 | 32360 | .One => { |
| 32316 | | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| { |
| 32317 | | ptr_info.pointee_type = pointee; |
| 32361 | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| { |
| 32362 | ptr_info.child = pointee.toIntern(); |
| 32318 | 32363 | break :good; |
| 32319 | 32364 | } |
| 32320 | 32365 | |
| ... | ... | @@ -32324,29 +32369,29 @@ fn resolvePeerTypesInner( |
| 32324 | 32369 | if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| { |
| 32325 | 32370 | // *[n:x]T + *[n:y]T = *[n]T |
| 32326 | 32371 | if (cur_arr.len == peer_arr.len) { |
| 32327 | | ptr_info.pointee_type = try mod.arrayType(.{ |
| 32372 | ptr_info.child = (try mod.arrayType(.{ |
| 32328 | 32373 | .len = cur_arr.len, |
| 32329 | 32374 | .child = elem_ty.toIntern(), |
| 32330 | | }); |
| 32375 | })).toIntern(); |
| 32331 | 32376 | break :good; |
| 32332 | 32377 | } |
| 32333 | 32378 | // *[a]T + *[b]T = []T |
| 32334 | | ptr_info.size = .Slice; |
| 32335 | | ptr_info.pointee_type = elem_ty; |
| 32379 | ptr_info.flags.size = .Slice; |
| 32380 | ptr_info.child = elem_ty.toIntern(); |
| 32336 | 32381 | break :good; |
| 32337 | 32382 | } |
| 32338 | 32383 | |
| 32339 | 32384 | if (peer_arr.elem_ty.toIntern() == .noreturn_type) { |
| 32340 | 32385 | // *struct{} + *[a]T = []T |
| 32341 | | ptr_info.size = .Slice; |
| 32342 | | ptr_info.pointee_type = cur_arr.elem_ty; |
| 32386 | ptr_info.flags.size = .Slice; |
| 32387 | ptr_info.child = cur_arr.elem_ty.toIntern(); |
| 32343 | 32388 | break :good; |
| 32344 | 32389 | } |
| 32345 | 32390 | |
| 32346 | 32391 | if (cur_arr.elem_ty.toIntern() == .noreturn_type) { |
| 32347 | 32392 | // *[a]T + *struct{} = []T |
| 32348 | | ptr_info.size = .Slice; |
| 32349 | | ptr_info.pointee_type = peer_arr.elem_ty; |
| 32393 | ptr_info.flags.size = .Slice; |
| 32394 | ptr_info.child = peer_arr.elem_ty.toIntern(); |
| 32350 | 32395 | break :good; |
| 32351 | 32396 | } |
| 32352 | 32397 | |
| ... | ... | @@ -32355,8 +32400,8 @@ fn resolvePeerTypesInner( |
| 32355 | 32400 | .Many => { |
| 32356 | 32401 | // Only works for *[n]T + [*]T -> [*]T |
| 32357 | 32402 | const arr = peer_pointee_array orelse return generic_err; |
| 32358 | | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, arr.elem_ty)) |pointee| { |
| 32359 | | ptr_info.pointee_type = pointee; |
| 32403 | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), arr.elem_ty)) |pointee| { |
| 32404 | ptr_info.child = pointee.toIntern(); |
| 32360 | 32405 | break :good; |
| 32361 | 32406 | } |
| 32362 | 32407 | if (arr.elem_ty.toIntern() == .noreturn_type) { |
| ... | ... | @@ -32368,8 +32413,8 @@ fn resolvePeerTypesInner( |
| 32368 | 32413 | .Slice => { |
| 32369 | 32414 | // Only works for *[n]T + []T -> []T |
| 32370 | 32415 | const arr = peer_pointee_array orelse return generic_err; |
| 32371 | | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, arr.elem_ty)) |pointee| { |
| 32372 | | ptr_info.pointee_type = pointee; |
| 32416 | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), arr.elem_ty)) |pointee| { |
| 32417 | ptr_info.child = pointee.toIntern(); |
| 32373 | 32418 | break :good; |
| 32374 | 32419 | } |
| 32375 | 32420 | if (arr.elem_ty.toIntern() == .noreturn_type) { |
| ... | ... | @@ -32380,26 +32425,26 @@ fn resolvePeerTypesInner( |
| 32380 | 32425 | }, |
| 32381 | 32426 | .C => unreachable, |
| 32382 | 32427 | }, |
| 32383 | | .Many => switch (ptr_info.size) { |
| 32428 | .Many => switch (ptr_info.flags.size) { |
| 32384 | 32429 | .One => { |
| 32385 | 32430 | // Only works for [*]T + *[n]T -> [*]T |
| 32386 | 32431 | const arr = cur_pointee_array orelse return generic_err; |
| 32387 | | if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.pointee_type)) |pointee| { |
| 32388 | | ptr_info.size = .Many; |
| 32389 | | ptr_info.pointee_type = pointee; |
| 32432 | if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.child.toType())) |pointee| { |
| 32433 | ptr_info.flags.size = .Many; |
| 32434 | ptr_info.child = pointee.toIntern(); |
| 32390 | 32435 | break :good; |
| 32391 | 32436 | } |
| 32392 | 32437 | if (arr.elem_ty.toIntern() == .noreturn_type) { |
| 32393 | 32438 | // [*]T + *struct{} -> [*]T |
| 32394 | | ptr_info.size = .Many; |
| 32395 | | ptr_info.pointee_type = peer_info.pointee_type; |
| 32439 | ptr_info.flags.size = .Many; |
| 32440 | ptr_info.child = peer_info.child; |
| 32396 | 32441 | break :good; |
| 32397 | 32442 | } |
| 32398 | 32443 | return generic_err; |
| 32399 | 32444 | }, |
| 32400 | 32445 | .Many => { |
| 32401 | | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| { |
| 32402 | | ptr_info.pointee_type = pointee; |
| 32446 | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| { |
| 32447 | ptr_info.child = pointee.toIntern(); |
| 32403 | 32448 | break :good; |
| 32404 | 32449 | } |
| 32405 | 32450 | return generic_err; |
| ... | ... | @@ -32413,28 +32458,28 @@ fn resolvePeerTypesInner( |
| 32413 | 32458 | } }; |
| 32414 | 32459 | } |
| 32415 | 32460 | // Okay, then works for [*]T + "[]T" -> [*]T |
| 32416 | | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| { |
| 32417 | | ptr_info.size = .Many; |
| 32418 | | ptr_info.pointee_type = pointee; |
| 32461 | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| { |
| 32462 | ptr_info.flags.size = .Many; |
| 32463 | ptr_info.child = pointee.toIntern(); |
| 32419 | 32464 | break :good; |
| 32420 | 32465 | } |
| 32421 | 32466 | return generic_err; |
| 32422 | 32467 | }, |
| 32423 | 32468 | .C => unreachable, |
| 32424 | 32469 | }, |
| 32425 | | .Slice => switch (ptr_info.size) { |
| 32470 | .Slice => switch (ptr_info.flags.size) { |
| 32426 | 32471 | .One => { |
| 32427 | 32472 | // Only works for []T + *[n]T -> []T |
| 32428 | 32473 | const arr = cur_pointee_array orelse return generic_err; |
| 32429 | | if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.pointee_type)) |pointee| { |
| 32430 | | ptr_info.size = .Slice; |
| 32431 | | ptr_info.pointee_type = pointee; |
| 32474 | if (try sema.resolvePairInMemoryCoercible(block, src, arr.elem_ty, peer_info.child.toType())) |pointee| { |
| 32475 | ptr_info.flags.size = .Slice; |
| 32476 | ptr_info.child = pointee.toIntern(); |
| 32432 | 32477 | break :good; |
| 32433 | 32478 | } |
| 32434 | 32479 | if (arr.elem_ty.toIntern() == .noreturn_type) { |
| 32435 | 32480 | // []T + *struct{} -> []T |
| 32436 | | ptr_info.size = .Slice; |
| 32437 | | ptr_info.pointee_type = peer_info.pointee_type; |
| 32481 | ptr_info.flags.size = .Slice; |
| 32482 | ptr_info.child = peer_info.child; |
| 32438 | 32483 | break :good; |
| 32439 | 32484 | } |
| 32440 | 32485 | return generic_err; |
| ... | ... | @@ -32444,8 +32489,8 @@ fn resolvePeerTypesInner( |
| 32444 | 32489 | return generic_err; |
| 32445 | 32490 | }, |
| 32446 | 32491 | .Slice => { |
| 32447 | | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.pointee_type, peer_info.pointee_type)) |pointee| { |
| 32448 | | ptr_info.pointee_type = pointee; |
| 32492 | if (try sema.resolvePairInMemoryCoercible(block, src, ptr_info.child.toType(), peer_info.child.toType())) |pointee| { |
| 32493 | ptr_info.child = pointee.toIntern(); |
| 32449 | 32494 | break :good; |
| 32450 | 32495 | } |
| 32451 | 32496 | return generic_err; |
| ... | ... | @@ -32456,40 +32501,43 @@ fn resolvePeerTypesInner( |
| 32456 | 32501 | } |
| 32457 | 32502 | } |
| 32458 | 32503 | |
| 32459 | | const sentinel_ty = if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Array) blk: { |
| 32460 | | break :blk ptr_info.pointee_type.childType(mod); |
| 32461 | | } else ptr_info.pointee_type; |
| 32462 | | |
| 32463 | | // TODO: once InternPool is in, we need to cast the sentinels to sentinel_ty |
| 32504 | const sentinel_ty = switch (ptr_info.flags.size) { |
| 32505 | .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) { |
| 32506 | .array_type => |array_type| array_type.child, |
| 32507 | else => ptr_info.child, |
| 32508 | }, |
| 32509 | .Many, .Slice, .C => ptr_info.child, |
| 32510 | }; |
| 32464 | 32511 | |
| 32465 | 32512 | sentinel: { |
| 32466 | 32513 | no_sentinel: { |
| 32467 | | if (peer_sentinel == null) break :no_sentinel; |
| 32468 | | if (cur_sentinel == null) break :no_sentinel; |
| 32469 | | const peer_sent_coerced = try mod.getCoerced(peer_sentinel.?, sentinel_ty); |
| 32470 | | const cur_sent_coerced = try mod.getCoerced(cur_sentinel.?, sentinel_ty); |
| 32471 | | if (!peer_sent_coerced.eql(cur_sent_coerced, sentinel_ty, mod)) break :no_sentinel; |
| 32514 | if (peer_sentinel == .none) break :no_sentinel; |
| 32515 | if (cur_sentinel == .none) break :no_sentinel; |
| 32516 | const peer_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, peer_sentinel, sentinel_ty); |
| 32517 | const cur_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, cur_sentinel, sentinel_ty); |
| 32518 | if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel; |
| 32472 | 32519 | // Sentinels match |
| 32473 | | if (ptr_info.size == .One) { |
| 32474 | | assert(ptr_info.pointee_type.zigTypeTag(mod) == .Array); |
| 32475 | | ptr_info.pointee_type = try mod.arrayType(.{ |
| 32476 | | .len = ptr_info.pointee_type.arrayLen(mod), |
| 32477 | | .child = ptr_info.pointee_type.childType(mod).toIntern(), |
| 32478 | | .sentinel = cur_sent_coerced.toIntern(), |
| 32479 | | }); |
| 32520 | if (ptr_info.flags.size == .One) switch (mod.intern_pool.indexToKey(ptr_info.child)) { |
| 32521 | .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{ |
| 32522 | .len = array_type.len, |
| 32523 | .child = array_type.child, |
| 32524 | .sentinel = cur_sent_coerced, |
| 32525 | })).toIntern(), |
| 32526 | else => unreachable, |
| 32480 | 32527 | } else { |
| 32481 | 32528 | ptr_info.sentinel = cur_sent_coerced; |
| 32482 | 32529 | } |
| 32483 | 32530 | break :sentinel; |
| 32484 | 32531 | } |
| 32485 | 32532 | // Clear existing sentinel |
| 32486 | | ptr_info.sentinel = null; |
| 32487 | | if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) { |
| 32488 | | ptr_info.pointee_type = try mod.arrayType(.{ |
| 32489 | | .len = ptr_info.pointee_type.arrayLen(mod), |
| 32490 | | .child = ptr_info.pointee_type.childType(mod).toIntern(), |
| 32533 | ptr_info.sentinel = .none; |
| 32534 | switch (mod.intern_pool.indexToKey(ptr_info.child)) { |
| 32535 | .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{ |
| 32536 | .len = array_type.len, |
| 32537 | .child = array_type.child, |
| 32491 | 32538 | .sentinel = .none, |
| 32492 | | }); |
| 32539 | })).toIntern(), |
| 32540 | else => {}, |
| 32493 | 32541 | } |
| 32494 | 32542 | } |
| 32495 | 32543 | |
| ... | ... | @@ -32500,17 +32548,22 @@ fn resolvePeerTypesInner( |
| 32500 | 32548 | // &.{} and &.{}, we'll currently have a pointer type of `*[0]noreturn` - we wanted to |
| 32501 | 32549 | // coerce the empty struct to a specific type, but no peer provided one. We need to |
| 32502 | 32550 | // detect this case and emit an error. |
| 32503 | | const pointee = opt_ptr_info.?.pointee_type; |
| 32504 | | if (pointee.toIntern() == .noreturn_type or |
| 32505 | | (pointee.zigTypeTag(mod) == .Array and pointee.childType(mod).toIntern() == .noreturn_type)) |
| 32506 | | { |
| 32507 | | return .{ .conflict = .{ |
| 32551 | const pointee = opt_ptr_info.?.child; |
| 32552 | switch (pointee) { |
| 32553 | .noreturn_type => return .{ .conflict = .{ |
| 32508 | 32554 | .peer_idx_a = first_idx, |
| 32509 | 32555 | .peer_idx_b = other_idx, |
| 32510 | | } }; |
| 32556 | } }, |
| 32557 | else => switch (mod.intern_pool.indexToKey(pointee)) { |
| 32558 | .array_type => |array_type| if (array_type.child == .noreturn_type) return .{ .conflict = .{ |
| 32559 | .peer_idx_a = first_idx, |
| 32560 | .peer_idx_b = other_idx, |
| 32561 | } }, |
| 32562 | else => {}, |
| 32563 | }, |
| 32511 | 32564 | } |
| 32512 | 32565 | |
| 32513 | | return .{ .success = try Type.ptr(sema.arena, mod, opt_ptr_info.?) }; |
| 32566 | return .{ .success = try mod.ptrType(opt_ptr_info.?) }; |
| 32514 | 32567 | }, |
| 32515 | 32568 | |
| 32516 | 32569 | .func => { |
| ... | ... | @@ -34158,7 +34211,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 34158 | 34211 | } |
| 34159 | 34212 | gop.value_ptr.* = .{ |
| 34160 | 34213 | .ty = Type.noreturn, |
| 34161 | | .abi_align = 0, |
| 34214 | .abi_align = .none, |
| 34162 | 34215 | .default_val = .none, |
| 34163 | 34216 | .is_comptime = is_comptime, |
| 34164 | 34217 | .offset = undefined, |
| ... | ... | @@ -34695,7 +34748,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 34695 | 34748 | |
| 34696 | 34749 | gop.value_ptr.* = .{ |
| 34697 | 34750 | .ty = field_ty, |
| 34698 | | .abi_align = 0, |
| 34751 | .abi_align = .none, |
| 34699 | 34752 | }; |
| 34700 | 34753 | |
| 34701 | 34754 | if (align_ref != .none) { |
| ... | ... | @@ -34711,7 +34764,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 34711 | 34764 | else => |e| return e, |
| 34712 | 34765 | }; |
| 34713 | 34766 | } else { |
| 34714 | | gop.value_ptr.abi_align = 0; |
| 34767 | gop.value_ptr.abi_align = .none; |
| 34715 | 34768 | } |
| 34716 | 34769 | } |
| 34717 | 34770 | |
| ... | ... | @@ -35335,15 +35388,19 @@ fn analyzeComptimeAlloc( |
| 35335 | 35388 | sema: *Sema, |
| 35336 | 35389 | block: *Block, |
| 35337 | 35390 | var_type: Type, |
| 35338 | | alignment: u32, |
| 35391 | alignment: Alignment, |
| 35339 | 35392 | ) CompileError!Air.Inst.Ref { |
| 35393 | const mod = sema.mod; |
| 35394 | |
| 35340 | 35395 | // Needed to make an anon decl with type `var_type` (the `finish()` call below). |
| 35341 | 35396 | _ = try sema.typeHasOnePossibleValue(var_type); |
| 35342 | 35397 | |
| 35343 | | const ptr_type = try Type.ptr(sema.arena, sema.mod, .{ |
| 35344 | | .pointee_type = var_type, |
| 35345 | | .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant), |
| 35346 | | .@"align" = alignment, |
| 35398 | const ptr_type = try mod.ptrType(.{ |
| 35399 | .child = var_type.toIntern(), |
| 35400 | .flags = .{ |
| 35401 | .alignment = alignment, |
| 35402 | .address_space = target_util.defaultAddressSpace(mod.getTarget(), .global_constant), |
| 35403 | }, |
| 35347 | 35404 | }); |
| 35348 | 35405 | |
| 35349 | 35406 | var anon_decl = try block.startAnonDecl(); |
| ... | ... | @@ -35354,15 +35411,15 @@ fn analyzeComptimeAlloc( |
| 35354 | 35411 | // There will be stores before the first load, but they may be to sub-elements or |
| 35355 | 35412 | // sub-fields. So we need to initialize with undef to allow the mechanism to expand |
| 35356 | 35413 | // into fields/elements and have those overridden with stored values. |
| 35357 | | (try sema.mod.intern(.{ .undef = var_type.toIntern() })).toValue(), |
| 35414 | (try mod.intern(.{ .undef = var_type.toIntern() })).toValue(), |
| 35358 | 35415 | alignment, |
| 35359 | 35416 | ); |
| 35360 | | const decl = sema.mod.declPtr(decl_index); |
| 35361 | | decl.@"align" = alignment; |
| 35417 | const decl = mod.declPtr(decl_index); |
| 35418 | decl.alignment = alignment; |
| 35362 | 35419 | |
| 35363 | 35420 | try sema.comptime_mutable_decls.append(decl_index); |
| 35364 | | try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index); |
| 35365 | | return sema.addConstant(ptr_type, (try sema.mod.intern(.{ .ptr = .{ |
| 35421 | try mod.declareDeclDependency(sema.owner_decl_index, decl_index); |
| 35422 | return sema.addConstant(ptr_type, (try mod.intern(.{ .ptr = .{ |
| 35366 | 35423 | .ty = ptr_type.toIntern(), |
| 35367 | 35424 | .addr = .{ .mut_decl = .{ |
| 35368 | 35425 | .decl = decl_index, |
| ... | ... | @@ -35747,14 +35804,10 @@ fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!u32 { |
| 35747 | 35804 | /// Not valid to call for packed unions. |
| 35748 | 35805 | /// Keep implementation in sync with `Module.Union.Field.normalAlignment`. |
| 35749 | 35806 | fn unionFieldAlignment(sema: *Sema, field: Module.Union.Field) !u32 { |
| 35750 | | const mod = sema.mod; |
| 35751 | | if (field.ty.zigTypeTag(mod) == .NoReturn) { |
| 35752 | | return @as(u32, 0); |
| 35753 | | } else if (field.abi_align == 0) { |
| 35754 | | return sema.typeAbiAlignment(field.ty); |
| 35755 | | } else { |
| 35756 | | return field.abi_align; |
| 35757 | | } |
| 35807 | return @intCast(u32, if (field.ty.isNoReturn(sema.mod)) |
| 35808 | 0 |
| 35809 | else |
| 35810 | field.abi_align.toByteUnitsOptional() orelse try sema.typeAbiAlignment(field.ty)); |
| 35758 | 35811 | } |
| 35759 | 35812 | |
| 35760 | 35813 | /// Synchronize logic with `Type.isFnOrHasRuntimeBits`. |
| ... | ... | @@ -36405,16 +36458,16 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type { |
| 36405 | 36458 | const mod = sema.mod; |
| 36406 | 36459 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 36407 | 36460 | const elem_ty = ptr_ty.elemType2(mod); |
| 36408 | | const allow_zero = ptr_info.@"allowzero" and (offset orelse 0) == 0; |
| 36461 | const is_allowzero = ptr_info.flags.is_allowzero and (offset orelse 0) == 0; |
| 36409 | 36462 | const parent_ty = ptr_ty.childType(mod); |
| 36410 | 36463 | |
| 36411 | | const VI = Type.Payload.Pointer.Data.VectorIndex; |
| 36464 | const VI = InternPool.Key.PtrType.VectorIndex; |
| 36412 | 36465 | |
| 36413 | 36466 | const vector_info: struct { |
| 36414 | 36467 | host_size: u16 = 0, |
| 36415 | 36468 | alignment: u32 = 0, |
| 36416 | 36469 | vector_index: VI = .none, |
| 36417 | | } = if (parent_ty.isVector(mod) and ptr_info.size == .One) blk: { |
| 36470 | } = if (parent_ty.isVector(mod) and ptr_info.flags.size == .One) blk: { |
| 36418 | 36471 | const elem_bits = elem_ty.bitSize(mod); |
| 36419 | 36472 | if (elem_bits == 0) break :blk .{}; |
| 36420 | 36473 | const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits); |
| ... | ... | @@ -36422,17 +36475,17 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type { |
| 36422 | 36475 | |
| 36423 | 36476 | break :blk .{ |
| 36424 | 36477 | .host_size = @intCast(u16, parent_ty.arrayLen(mod)), |
| 36425 | | .alignment = @intCast(u16, parent_ty.abiAlignment(mod)), |
| 36478 | .alignment = @intCast(u32, parent_ty.abiAlignment(mod)), |
| 36426 | 36479 | .vector_index = if (offset) |some| @enumFromInt(VI, some) else .runtime, |
| 36427 | 36480 | }; |
| 36428 | 36481 | } else .{}; |
| 36429 | 36482 | |
| 36430 | | const alignment: u32 = a: { |
| 36483 | const alignment: Alignment = a: { |
| 36431 | 36484 | // Calculate the new pointer alignment. |
| 36432 | | if (ptr_info.@"align" == 0) { |
| 36433 | | if (vector_info.alignment != 0) break :a vector_info.alignment; |
| 36485 | if (ptr_info.flags.alignment == .none) { |
| 36486 | if (vector_info.alignment != 0) break :a Alignment.fromNonzeroByteUnits(vector_info.alignment); |
| 36434 | 36487 | // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness. |
| 36435 | | break :a 0; |
| 36488 | break :a .none; |
| 36436 | 36489 | } |
| 36437 | 36490 | // If the addend is not a comptime-known value we can still count on |
| 36438 | 36491 | // it being a multiple of the type size. |
| ... | ... | @@ -36442,18 +36495,27 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type { |
| 36442 | 36495 | // The resulting pointer is aligned to the lcd between the offset (an |
| 36443 | 36496 | // arbitrary number) and the alignment factor (always a power of two, |
| 36444 | 36497 | // non zero). |
| 36445 | | const new_align = @as(u32, 1) << @intCast(u5, @ctz(addend | ptr_info.@"align")); |
| 36498 | const new_align = @enumFromInt(Alignment, @min( |
| 36499 | @ctz(addend), |
| 36500 | @intFromEnum(ptr_info.flags.alignment), |
| 36501 | )); |
| 36502 | assert(new_align != .none); |
| 36446 | 36503 | break :a new_align; |
| 36447 | 36504 | }; |
| 36448 | | return try Type.ptr(sema.arena, sema.mod, .{ |
| 36449 | | .pointee_type = elem_ty, |
| 36450 | | .mutable = ptr_info.mutable, |
| 36451 | | .@"addrspace" = ptr_info.@"addrspace", |
| 36452 | | .@"allowzero" = allow_zero, |
| 36453 | | .@"volatile" = ptr_info.@"volatile", |
| 36454 | | .@"align" = alignment, |
| 36455 | | .host_size = vector_info.host_size, |
| 36456 | | .vector_index = vector_info.vector_index, |
| 36505 | return mod.ptrType(.{ |
| 36506 | .child = elem_ty.toIntern(), |
| 36507 | .flags = .{ |
| 36508 | .alignment = alignment, |
| 36509 | .is_const = ptr_info.flags.is_const, |
| 36510 | .is_volatile = ptr_info.flags.is_volatile, |
| 36511 | .is_allowzero = is_allowzero, |
| 36512 | .address_space = ptr_info.flags.address_space, |
| 36513 | .vector_index = vector_info.vector_index, |
| 36514 | }, |
| 36515 | .packed_offset = .{ |
| 36516 | .host_size = vector_info.host_size, |
| 36517 | .bit_offset = 0, |
| 36518 | }, |
| 36457 | 36519 | }); |
| 36458 | 36520 | } |
| 36459 | 36521 | |