stage2: Preserve larger alignment in @ptrCast

This commit is contained in:
Cody Tapscott 2022-03-02 21:49:10 -07:00 committed by Andrew Kelley
parent 7deadf4301
commit b6f1a8612b
2 changed files with 24 additions and 3 deletions

View File

@ -12538,6 +12538,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
const operand = sema.resolveInst(extra.rhs);
const operand_ty = sema.typeOf(operand);
const target = sema.mod.getTarget();
try sema.checkPtrType(block, dest_ty_src, dest_ty);
try sema.checkPtrOperand(block, operand_src, operand_ty);
if (dest_ty.isSlice()) {
@ -12547,7 +12549,28 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
try sema.analyzeSlicePtr(block, operand_src, operand, operand_ty)
else
operand;
return sema.coerceCompatiblePtrs(block, dest_ty, ptr, operand_src);
try sema.resolveTypeLayout(block, dest_ty_src, dest_ty.elemType2());
const dest_align = dest_ty.ptrAlignment(target);
try sema.resolveTypeLayout(block, operand_src, operand_ty.elemType2());
const operand_align = operand_ty.ptrAlignment(target);
// If the destination is less aligned than the source, preserve the source alignment
var aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {
// Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result
if (dest_ty.zigTypeTag() == .Optional) {
var buf: Type.Payload.ElemType = undefined;
var dest_ptr_info = dest_ty.optionalChild(&buf).ptrInfo().data;
dest_ptr_info.@"align" = operand_align;
break :blk try Type.optional(sema.arena, try Type.ptr(sema.arena, target, dest_ptr_info));
} else {
var dest_ptr_info = dest_ty.ptrInfo().data;
dest_ptr_info.@"align" = operand_align;
break :blk try Type.ptr(sema.arena, target, dest_ptr_info);
}
};
return sema.coerceCompatiblePtrs(block, aligned_dest_ty, ptr, operand_src);
}
fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {

View File

@ -67,8 +67,6 @@ const Bytes = struct {
};
test "comptime ptrcast keeps larger alignment" {
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
comptime {
const a: u32 = 1234;
const p = @ptrCast([*]const u8, &a);