mirror of
https://github.com/ziglang/zig.git
synced 2026-01-27 17:55:24 +00:00
Sema: do not use coerceCompatiblePtr for ptrCast
This commit is contained in:
parent
e584558bd8
commit
fb91483e48
61
src/Sema.zig
61
src/Sema.zig
@ -17772,6 +17772,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
|
||||
|
||||
fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
|
||||
const src = inst_data.src();
|
||||
const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
|
||||
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
|
||||
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
|
||||
@ -17783,6 +17784,15 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
try sema.checkPtrType(block, dest_ty_src, dest_ty);
|
||||
try sema.checkPtrOperand(block, operand_src, operand_ty);
|
||||
|
||||
const operand_info = operand_ty.ptrInfo().data;
|
||||
const dest_info = dest_ty.ptrInfo().data;
|
||||
if (!operand_info.mutable and dest_info.mutable) {
|
||||
return sema.fail(block, src, "cast discards const qualifier", .{});
|
||||
}
|
||||
if (operand_info.@"volatile" and !dest_info.@"volatile") {
|
||||
return sema.fail(block, src, "cast discards volatile qualifier", .{});
|
||||
}
|
||||
|
||||
const dest_is_slice = dest_ty.isSlice();
|
||||
const operand_is_slice = operand_ty.isSlice();
|
||||
if (dest_is_slice and !operand_is_slice) {
|
||||
@ -17793,15 +17803,6 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
else
|
||||
operand;
|
||||
|
||||
if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {
|
||||
if (!dest_ty.ptrAllowsZero() and operand_val.isUndef()) {
|
||||
return sema.failWithUseOfUndef(block, operand_src);
|
||||
}
|
||||
if (!dest_ty.ptrAllowsZero() and operand_val.isNull()) {
|
||||
return sema.fail(block, operand_src, "null pointer casted to type {}", .{dest_ty.fmt(sema.mod)});
|
||||
}
|
||||
}
|
||||
|
||||
const dest_elem_ty = dest_ty.elemType2();
|
||||
try sema.resolveTypeLayout(block, dest_ty_src, dest_elem_ty);
|
||||
const dest_align = dest_ty.ptrAlignment(target);
|
||||
@ -17835,7 +17836,47 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
}
|
||||
}
|
||||
|
||||
return sema.coerceCompatiblePtrs(block, aligned_dest_ty, ptr, operand_src);
|
||||
if (dest_align > operand_align) {
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(block, src, "cast increases pointer alignment", .{});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
|
||||
try sema.errNote(block, operand_src, msg, "'{}' has alignment '{d}'", .{
|
||||
operand_ty.fmt(sema.mod), operand_align,
|
||||
});
|
||||
try sema.errNote(block, dest_ty_src, msg, "'{}' has alignment '{d}'", .{
|
||||
dest_ty.fmt(sema.mod), dest_align,
|
||||
});
|
||||
break :msg msg;
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(msg);
|
||||
}
|
||||
|
||||
if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {
|
||||
if (!dest_ty.ptrAllowsZero() and operand_val.isUndef()) {
|
||||
return sema.failWithUseOfUndef(block, operand_src);
|
||||
}
|
||||
if (!dest_ty.ptrAllowsZero() and operand_val.isNull()) {
|
||||
return sema.fail(block, operand_src, "null pointer casted to type {}", .{dest_ty.fmt(sema.mod)});
|
||||
}
|
||||
return sema.addConstant(aligned_dest_ty, operand_val);
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src, null);
|
||||
if (block.wantSafety() and operand_ty.ptrAllowsZero() and !dest_ty.ptrAllowsZero() and
|
||||
try sema.typeHasRuntimeBits(block, sema.src, dest_ty.elemType2()))
|
||||
{
|
||||
const ptr_int = try block.addUnOp(.ptrtoint, ptr);
|
||||
const is_non_zero = try block.addBinOp(.cmp_neq, ptr_int, .zero_usize);
|
||||
const ok = if (operand_is_slice) ok: {
|
||||
const len = try sema.analyzeSliceLen(block, operand_src, operand);
|
||||
const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize);
|
||||
break :ok try block.addBinOp(.bit_or, len_zero, is_non_zero);
|
||||
} else is_non_zero;
|
||||
try sema.addSafetyCheck(block, ok, .cast_to_null);
|
||||
}
|
||||
|
||||
return block.addBitCast(aligned_dest_ty, ptr);
|
||||
}
|
||||
|
||||
fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
|
||||
@ -5,9 +5,9 @@ export fn entry() u32 {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:17: error: cast increases pointer alignment
|
||||
// tmp.zig:3:38: note: '*u8' has alignment 1
|
||||
// tmp.zig:3:26: note: '*u32' has alignment 4
|
||||
// :3:17: error: cast increases pointer alignment
|
||||
// :3:32: note: '*u8' has alignment '1'
|
||||
// :3:26: note: '*u32' has alignment '4'
|
||||
@ -5,7 +5,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:15: error: cast discards const qualifier
|
||||
// :3:15: error: cast discards const qualifier
|
||||
Loading…
x
Reference in New Issue
Block a user