authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-27 16:03:51+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-30 15:20:16+02:00
loga9785fe8eef564011b4266e8a1b9aa15b7e37189
tree6f350d82c03043356608001c9a3bed2ae68fe59b
parentb129350cb5de2251d50b142a50d8d74ccd92ae73

Sema: add helpful notes to invalid `@ptrCast` operations

Closes #14474

3 files changed, 20 insertions(+), 1 deletions(-)

doc/langref.html.in+9
...@@ -8799,6 +8799,15 @@ pub const PrefetchOptions = struct {...@@ -8799,6 +8799,15 @@ pub const PrefetchOptions = struct {
8799 {#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#}8799 {#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#}
8800 to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}.8800 to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}.
8801 </p>8801 </p>
8802 <p>
8803 {#syntax#}@ptrCast{#endsyntax#} cannot be used for:
8804 </p>
8805 <ul>
8806 <li>Removing {#syntax#}const{#endsyntax#} or {#syntax#}volatile{#endsyntax#} qualifier. TODO add a {#syntax#}@qualCast{#endsyntax#} builtin.</li>
8807 <li>Changing pointer address space, use {#link|@addrSpaceCast#}</li>
8808 <li>Increasing pointer alignment, use {#link|@alignCast#}</li>
8809 <li>Casting a non-slice pointer to a slice, use slicing syntax {#syntax#}ptr[start..end]{#endsyntax#}</li>
8810 </ul>
8802 {#header_close#}8811 {#header_close#}
88038812
8804 {#header_open|@ptrToInt#}8813 {#header_open|@ptrToInt#}
src/Sema.zig+10-1
...@@ -19535,7 +19535,14 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19535,7 +19535,14 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19535 return sema.fail(block, src, "cast discards volatile qualifier", .{});19535 return sema.fail(block, src, "cast discards volatile qualifier", .{});
19536 }19536 }
19537 if (operand_info.@"addrspace" != dest_info.@"addrspace") {19537 if (operand_info.@"addrspace" != dest_info.@"addrspace") {
19538 return sema.fail(block, src, "cast changes pointer address space", .{});19538 const msg = msg: {
19539 const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{});
19540 errdefer msg.destroy(sema.gpa);
19541
19542 try sema.errNote(block, src, msg, "consider using '@addrSpaceCast'", .{});
19543 break :msg msg;
19544 };
19545 return sema.failWithOwnedErrorMsg(msg);
19539 }19546 }
1954019547
19541 const dest_is_slice = dest_ty.isSlice();19548 const dest_is_slice = dest_ty.isSlice();
...@@ -19590,6 +19597,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19590,6 +19597,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19590 try sema.errNote(block, dest_ty_src, msg, "'{}' has alignment '{d}'", .{19597 try sema.errNote(block, dest_ty_src, msg, "'{}' has alignment '{d}'", .{
19591 dest_ty.fmt(sema.mod), dest_align,19598 dest_ty.fmt(sema.mod), dest_align,
19592 });19599 });
19600
19601 try sema.errNote(block, src, msg, "consider using '@alignCast'", .{});
19593 break :msg msg;19602 break :msg msg;
19594 };19603 };
19595 return sema.failWithOwnedErrorMsg(msg);19604 return sema.failWithOwnedErrorMsg(msg);
test/cases/compile_errors/increase_pointer_alignment_in_ptrCast.zig+1
...@@ -11,3 +11,4 @@ export fn entry() u32 {...@@ -11,3 +11,4 @@ export fn entry() u32 {
11// :3:17: error: cast increases pointer alignment11// :3:17: error: cast increases pointer alignment
12// :3:32: note: '*u8' has alignment '1'12// :3:32: note: '*u8' has alignment '1'
13// :3:26: note: '*u32' has alignment '4'13// :3:26: note: '*u32' has alignment '4'
14// :3:17: note: consider using '@alignCast'