| ... | @@ -15036,10 +15036,7 @@ fn analyzePtrArithmetic( | ... | @@ -15036,10 +15036,7 @@ fn analyzePtrArithmetic( |
| 15036 | const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset); | 15036 | const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset); |
| 15037 | const ptr_ty = sema.typeOf(ptr); | 15037 | const ptr_ty = sema.typeOf(ptr); |
| 15038 | const ptr_info = ptr_ty.ptrInfo(mod); | 15038 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 15039 | const elem_ty = if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Array) | 15039 | assert(ptr_info.size == .Many or ptr_info.size == .C); |
| 15040 | ptr_info.pointee_type.childType(mod) | | |
| 15041 | else | | |
| 15042 | ptr_info.pointee_type; | | |
| 15043 | | 15040 | |
| 15044 | const new_ptr_ty = t: { | 15041 | const new_ptr_ty = t: { |
| 15045 | // Calculate the new pointer alignment. | 15042 | // Calculate the new pointer alignment. |
| ... | @@ -15050,7 +15047,7 @@ fn analyzePtrArithmetic( | ... | @@ -15050,7 +15047,7 @@ fn analyzePtrArithmetic( |
| 15050 | } | 15047 | } |
| 15051 | // If the addend is not a comptime-known value we can still count on | 15048 | // If the addend is not a comptime-known value we can still count on |
| 15052 | // it being a multiple of the type size. | 15049 | // it being a multiple of the type size. |
| 15053 | const elem_size = elem_ty.abiSize(mod); | 15050 | const elem_size = ptr_info.pointee_type.abiSize(mod); |
| 15054 | const addend = if (opt_off_val) |off_val| a: { | 15051 | const addend = if (opt_off_val) |off_val| a: { |
| 15055 | const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(mod)); | 15052 | const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(mod)); |
| 15056 | break :a elem_size * off_int; | 15053 | break :a elem_size * off_int; |
| ... | @@ -15081,7 +15078,7 @@ fn analyzePtrArithmetic( | ... | @@ -15081,7 +15078,7 @@ fn analyzePtrArithmetic( |
| 15081 | const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod)); | 15078 | const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod)); |
| 15082 | if (offset_int == 0) return ptr; | 15079 | if (offset_int == 0) return ptr; |
| 15083 | if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| { | 15080 | if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| { |
| 15084 | const elem_size = elem_ty.abiSize(mod); | 15081 | const elem_size = ptr_info.pointee_type.abiSize(mod); |
| 15085 | const new_addr = switch (air_tag) { | 15082 | const new_addr = switch (air_tag) { |
| 15086 | .ptr_add => addr + elem_size * offset_int, | 15083 | .ptr_add => addr + elem_size * offset_int, |
| 15087 | .ptr_sub => addr - elem_size * offset_int, | 15084 | .ptr_sub => addr - elem_size * offset_int, |
| ... | @@ -22673,12 +22670,28 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -22673,12 +22670,28 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 22673 | const new_dest_ptr_ty = sema.typeOf(new_dest_ptr); | 22670 | const new_dest_ptr_ty = sema.typeOf(new_dest_ptr); |
| 22674 | const raw_dest_ptr = if (new_dest_ptr_ty.isSlice(mod)) | 22671 | const raw_dest_ptr = if (new_dest_ptr_ty.isSlice(mod)) |
| 22675 | try sema.analyzeSlicePtr(block, dest_src, new_dest_ptr, new_dest_ptr_ty) | 22672 | try sema.analyzeSlicePtr(block, dest_src, new_dest_ptr, new_dest_ptr_ty) |
| 22676 | else | 22673 | else if (new_dest_ptr_ty.ptrSize(mod) == .One) ptr: { |
| 22677 | new_dest_ptr; | 22674 | var dest_manyptr_ty_key = mod.intern_pool.indexToKey(new_dest_ptr_ty.toIntern()).ptr_type; |
| | 22675 | assert(dest_manyptr_ty_key.size == .One); |
| | 22676 | dest_manyptr_ty_key.elem_type = dest_elem_ty.toIntern(); |
| | 22677 | dest_manyptr_ty_key.size = .Many; |
| | 22678 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrType(dest_manyptr_ty_key), new_dest_ptr, dest_src); |
| | 22679 | } else new_dest_ptr; |
| | 22680 | |
| | 22681 | const new_src_ptr_ty = sema.typeOf(new_src_ptr); |
| | 22682 | const raw_src_ptr = if (new_src_ptr_ty.isSlice(mod)) |
| | 22683 | try sema.analyzeSlicePtr(block, src_src, new_src_ptr, new_src_ptr_ty) |
| | 22684 | else if (new_src_ptr_ty.ptrSize(mod) == .One) ptr: { |
| | 22685 | var src_manyptr_ty_key = mod.intern_pool.indexToKey(new_src_ptr_ty.toIntern()).ptr_type; |
| | 22686 | assert(src_manyptr_ty_key.size == .One); |
| | 22687 | src_manyptr_ty_key.elem_type = src_elem_ty.toIntern(); |
| | 22688 | src_manyptr_ty_key.size = .Many; |
| | 22689 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrType(src_manyptr_ty_key), new_src_ptr, src_src); |
| | 22690 | } else new_src_ptr; |
| 22678 | | 22691 | |
| 22679 | // ok1: dest >= src + len | 22692 | // ok1: dest >= src + len |
| 22680 | // ok2: src >= dest + len | 22693 | // ok2: src >= dest + len |
| 22681 | const src_plus_len = try sema.analyzePtrArithmetic(block, src, new_src_ptr, len, .ptr_add, src_src, src); | 22694 | const src_plus_len = try sema.analyzePtrArithmetic(block, src, raw_src_ptr, len, .ptr_add, src_src, src); |
| 22682 | const dest_plus_len = try sema.analyzePtrArithmetic(block, src, raw_dest_ptr, len, .ptr_add, dest_src, src); | 22695 | const dest_plus_len = try sema.analyzePtrArithmetic(block, src, raw_dest_ptr, len, .ptr_add, dest_src, src); |
| 22683 | const ok1 = try block.addBinOp(.cmp_gte, raw_dest_ptr, src_plus_len); | 22696 | const ok1 = try block.addBinOp(.cmp_gte, raw_dest_ptr, src_plus_len); |
| 22684 | const ok2 = try block.addBinOp(.cmp_gte, new_src_ptr, dest_plus_len); | 22697 | const ok2 = try block.addBinOp(.cmp_gte, new_src_ptr, dest_plus_len); |
| ... | @@ -29968,8 +29981,14 @@ fn analyzeSlice( | ... | @@ -29968,8 +29981,14 @@ fn analyzeSlice( |
| 29968 | | 29981 | |
| 29969 | const ptr = if (slice_ty.isSlice(mod)) | 29982 | const ptr = if (slice_ty.isSlice(mod)) |
| 29970 | try sema.analyzeSlicePtr(block, ptr_src, ptr_or_slice, slice_ty) | 29983 | try sema.analyzeSlicePtr(block, ptr_src, ptr_or_slice, slice_ty) |
| 29971 | else | 29984 | else if (array_ty.zigTypeTag(mod) == .Array) ptr: { |
| 29972 | ptr_or_slice; | 29985 | var manyptr_ty_key = mod.intern_pool.indexToKey(slice_ty.toIntern()).ptr_type; |
| | 29986 | assert(manyptr_ty_key.elem_type == array_ty.toIntern()); |
| | 29987 | assert(manyptr_ty_key.size == .One); |
| | 29988 | manyptr_ty_key.elem_type = elem_ty.toIntern(); |
| | 29989 | manyptr_ty_key.size = .Many; |
| | 29990 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrType(manyptr_ty_key), ptr_or_slice, ptr_src); |
| | 29991 | } else ptr_or_slice; |
| 29973 | | 29992 | |
| 29974 | const start = try sema.coerce(block, Type.usize, uncasted_start, start_src); | 29993 | const start = try sema.coerce(block, Type.usize, uncasted_start, start_src); |
| 29975 | const new_ptr = try sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src); | 29994 | const new_ptr = try sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src); |