-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
ptrCast between pointer types of different sizes no longer allowed #7022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29850,23 +29850,28 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn | |
return ira->codegen->invalid_inst_gen; | ||
} | ||
|
||
if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) | ||
if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown))) | ||
return ira->codegen->invalid_inst_gen; | ||
|
||
if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) | ||
if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown))) | ||
return ira->codegen->invalid_inst_gen; | ||
|
||
if (safety_check_on && | ||
type_has_bits(ira->codegen, dest_type) && | ||
!type_has_bits(ira->codegen, if_slice_ptr_type)) | ||
{ | ||
size_t src_size = type_size_bits(ira->codegen, if_slice_ptr_type); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIR pointers are either There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The major case this intends to fix is an optional zero-sized pointer, which are 1 bit large. Do those not count as pointers? I know There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Certainly in the past, pointers in C are not always a single machine word. Think far and near pointers in the DOS era. Also, the x32 mode for x86 CPUs does weird things where pointers are 32-bit. Java had/has a mode in the JVM where 32-bit pointers were used in 64-bit mode so registers could be 64-bit but pointers were smaller. The C specification goes to some lengths to make sure that the size of a pointer is not specified. As long as Whether that is something that Zig wants to support, different pointer sizes, is a different story! (edit: English is hard without caffeine!) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Those should probably decay to an optional type with no payload that in turn decay into a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @LemonBoy Yeah, but should they be allowed as the output/input type of @ptrCast? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Casting "down" from a regular pointer to a zero-sized pointer should be probably allowed as that's safe while the other way around should be prohibited as that's a great way to shoot yourself in the foot. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @LemonBoy #1469, an accepted proposal this is meant to close, disallows casting from a sized to zero-sized pointer. But should What makes me think that it shouldn't is that you can't cast |
||
size_t dest_size = type_size_bits(ira->codegen, dest_type); | ||
if (safety_check_on && src_size != dest_size) { | ||
ErrorMsg *msg = ir_add_error(ira, source_instr, | ||
buf_sprintf("'%s' and '%s' do not have the same in-memory representation", | ||
buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); | ||
add_error_note(ira->codegen, msg, ptr_src->source_node, | ||
buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name))); | ||
buf_sprintf("'%s' has a pointer size of %zu %s", | ||
buf_ptr(&src_type->name), | ||
src_size, | ||
src_size == 1? "bit" : "bits")); | ||
add_error_note(ira->codegen, msg, dest_type_src->source_node, | ||
buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name))); | ||
buf_sprintf("'%s' has a pointer size of %zu %s", | ||
buf_ptr(&dest_type->name), | ||
dest_size, | ||
dest_size == 1? "bit" : "bits")); | ||
return ira->codegen->invalid_inst_gen; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit, you can save one level of indentation by handling the exceptional case before the general one:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you could do that, but it would have to look more like
Because in your fix, it doesn't work since
&[_]usize{}
is a const pointer.Maybe this would be better too, since we won't need 2 return statements:
However, the downside to that is that the compiler will generate
empty_arr
even in the case wherestack_n
is not zero. But due to lazy evaluation this is maybe ok?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Welp, I didn't expect the constness to matter there.
You're basically forced to return a local pointer to a zero sized variable, it's not that nice :\
It's an empty array, its size won't matter much/at all.