-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Do not use undefined
for the ptr field of Allocator
/Random
instances
#21760
base: master
Are you sure you want to change the base?
Conversation
Since this is common to all pointer types, a utility method might make sense - something like |
Confirmed that the pointer values returned for 0-length allocations are unchanged. Tested the following: ```zig allocator.alloc(u8, 0); allocator.alignedAlloc(u8, 256, 0) allocator.alignedAlloc(u8, 2048, 0) allocator.create(u0) ``` and tested `realloc` with: ```zig const slice = try allocator.alloc(u8, 1); const realloced = try allocator.realloc(slice, 0); ``` and ```zig const slice = try allocator.alignedAlloc(u8, 256, 1); const realloced = try allocator.realloc(slice, 0); ```
The use of undefined here meant that it was always unsafe/illegal to compare the ptr fields of Allocator/Random. However, this restriction is not mentioned anywhere and the ptr field *is* being compared in real code, e.g. `std.process.Child.collectOutput`, which can lead to undefined behavior in release modes (see ziglang#21756). There are two ways to address this: 1. Codify that comparing `ptr` is always illegal/unsafe, and remove all existing comparisons. 2. Set `ptr` to a legal dummy value, similar to the value returned by Allocator.alloc when a zero-length slice is requested. The first option seems like footgun central (at least until usage of `undefined` is fully safety-checked in safe modes), so I went with the second option. Closes ziglang#21756
e9993ac
to
70fc415
Compare
Good idea, added that as Confirmed that the pointer values returned for 0-length allocations are unchanged. Tested the following: allocator.alloc(u8, 0);
allocator.alignedAlloc(u8, 256, 0)
allocator.alignedAlloc(u8, 2048, 0)
allocator.create(u0) and tested const slice = try allocator.alloc(u8, 1);
const realloced = try allocator.realloc(slice, 0); and const slice = try allocator.alignedAlloc(u8, 256, 1);
const realloced = try allocator.realloc(slice, 0); |
As a general rule, (It might be a good idea to downright disallow |
@jibal I do think it makes sense to have a global I think the main surprise is that assigning an |
Why have a pub field that should never be used? These are footguns and totally unnecessary UB. Anyway, I suppose having the compiler ban it is not the Zig way, but IMO library code should not be planting these mines. |
The use of
undefined
here meant that it was always unsafe/illegal to compare the ptr fields of Allocator/Random. However, this restriction is not mentioned anywhere and the ptr field is being compared in real code, e.g.std.process.Child.collectOutput
, which can lead to undefined behavior in release modes (see #21756).There are two ways to address this:
ptr
is always illegal/unsafe, and remove all existing comparisons.ptr
to a legal dummy value, similar to the value returned by Allocator.alloc when a zero-length slice is requested.The first option seems like footgun central (at least until usage of
undefined
is fully safety-checked in safe modes [#211]), so I went with the second option.Closes #21756
Closes #17704