authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-03-02 21:49:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-03 13:08:14-07:00
logb6f1a8612bc5120b729f94031119315334e54e35
tree7883e146fce4ad77a845392e783ebee62b1d08fc
parent7deadf4301d5f5f5e2b8a1a8b2dc7109e2c82181

stage2: Preserve larger alignment in @ptrCast


2 files changed, 24 insertions(+), 3 deletions(-)

src/Sema.zig+24-1
...@@ -12538,6 +12538,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -12538,6 +12538,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
12538 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);12538 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
12539 const operand = sema.resolveInst(extra.rhs);12539 const operand = sema.resolveInst(extra.rhs);
12540 const operand_ty = sema.typeOf(operand);12540 const operand_ty = sema.typeOf(operand);
12541 const target = sema.mod.getTarget();
12542
12541 try sema.checkPtrType(block, dest_ty_src, dest_ty);12543 try sema.checkPtrType(block, dest_ty_src, dest_ty);
12542 try sema.checkPtrOperand(block, operand_src, operand_ty);12544 try sema.checkPtrOperand(block, operand_src, operand_ty);
12543 if (dest_ty.isSlice()) {12545 if (dest_ty.isSlice()) {
...@@ -12547,7 +12549,28 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -12547,7 +12549,28 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
12547 try sema.analyzeSlicePtr(block, operand_src, operand, operand_ty)12549 try sema.analyzeSlicePtr(block, operand_src, operand, operand_ty)
12548 else12550 else
12549 operand;12551 operand;
12550 return sema.coerceCompatiblePtrs(block, dest_ty, ptr, operand_src);12552
12553 try sema.resolveTypeLayout(block, dest_ty_src, dest_ty.elemType2());
12554 const dest_align = dest_ty.ptrAlignment(target);
12555 try sema.resolveTypeLayout(block, operand_src, operand_ty.elemType2());
12556 const operand_align = operand_ty.ptrAlignment(target);
12557
12558 // If the destination is less aligned than the source, preserve the source alignment
12559 var aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {
12560 // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result
12561 if (dest_ty.zigTypeTag() == .Optional) {
12562 var buf: Type.Payload.ElemType = undefined;
12563 var dest_ptr_info = dest_ty.optionalChild(&buf).ptrInfo().data;
12564 dest_ptr_info.@"align" = operand_align;
12565 break :blk try Type.optional(sema.arena, try Type.ptr(sema.arena, target, dest_ptr_info));
12566 } else {
12567 var dest_ptr_info = dest_ty.ptrInfo().data;
12568 dest_ptr_info.@"align" = operand_align;
12569 break :blk try Type.ptr(sema.arena, target, dest_ptr_info);
12570 }
12571 };
12572
12573 return sema.coerceCompatiblePtrs(block, aligned_dest_ty, ptr, operand_src);
12551}12574}
1255212575
12553fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {12576fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
test/behavior/ptrcast.zig-2
...@@ -67,8 +67,6 @@ const Bytes = struct {...@@ -67,8 +67,6 @@ const Bytes = struct {
67};67};
6868
69test "comptime ptrcast keeps larger alignment" {69test "comptime ptrcast keeps larger alignment" {
70 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
71
72 comptime {70 comptime {
73 const a: u32 = 1234;71 const a: u32 = 1234;
74 const p = @ptrCast([*]const u8, &a);72 const p = @ptrCast([*]const u8, &a);