| ... | ... | @@ -16278,8 +16278,6 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 16278 | 16278 | // TODO compile error if the result pointer is comptime known and would have an |
| 16279 | 16279 | // alignment that disagrees with the Decl's alignment. |
| 16280 | 16280 | |
| 16281 | | // TODO insert safety check that the alignment is correct |
| 16282 | | |
| 16283 | 16281 | const ptr_info = ptr_ty.ptrInfo().data; |
| 16284 | 16282 | const dest_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 16285 | 16283 | .pointee_type = ptr_info.pointee_type, |
| ... | ... | @@ -16290,6 +16288,36 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 16290 | 16288 | .@"volatile" = ptr_info.@"volatile", |
| 16291 | 16289 | .size = ptr_info.size, |
| 16292 | 16290 | }); |
| 16291 | |
| 16292 | if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| { |
| 16293 | if (try val.getUnsignedIntAdvanced(sema.mod.getTarget(), null)) |addr| { |
| 16294 | if (addr % dest_align != 0) { |
| 16295 | return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align }); |
| 16296 | } |
| 16297 | } |
| 16298 | return sema.addConstant(dest_ty, val); |
| 16299 | } |
| 16300 | |
| 16301 | try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src); |
| 16302 | if (block.wantSafety() and dest_align > 1) { |
| 16303 | const val_payload = try sema.arena.create(Value.Payload.U64); |
| 16304 | val_payload.* = .{ |
| 16305 | .base = .{ .tag = .int_u64 }, |
| 16306 | .data = dest_align - 1, |
| 16307 | }; |
| 16308 | const align_minus_1 = try sema.addConstant( |
| 16309 | Type.usize, |
| 16310 | Value.initPayload(&val_payload.base), |
| 16311 | ); |
| 16312 | const actual_ptr = if (ptr_ty.isSlice()) |
| 16313 | try sema.analyzeSlicePtr(block, ptr_src, ptr, ptr_ty) |
| 16314 | else |
| 16315 | ptr; |
| 16316 | const ptr_int = try block.addUnOp(.ptrtoint, actual_ptr); |
| 16317 | const remainder = try block.addBinOp(.bit_and, ptr_int, align_minus_1); |
| 16318 | const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize); |
| 16319 | try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment); |
| 16320 | } |
| 16293 | 16321 | return sema.coerceCompatiblePtrs(block, dest_ty, ptr, ptr_src); |
| 16294 | 16322 | } |
| 16295 | 16323 | |