Skip to content

@fieldParentPtr violates type based aliasing guarantees #1644

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

Closed
rohlem opened this issue Oct 7, 2018 · 3 comments
Closed

@fieldParentPtr violates type based aliasing guarantees #1644

rohlem opened this issue Oct 7, 2018 · 3 comments
Milestone

Comments

@rohlem
Copy link
Contributor

rohlem commented Oct 7, 2018

(Depends on the answer to #1643, but I had it all typed out already so why not just post it.)
I believe that @fieldParentPtr , which has been more actively discussed recently on the topic of interface design, violates the basic assumptions of type based (non-)aliasing guarantees ("strict aliasing") (which I believe are still planned, but maybe not? see #1643 ).

Minimal example code:

const Connection = struct {a: u8, b: u16}; //any "multiplicative" type composed of other types

fn assumes_connection(pa: u8*) void //the signature shows how we can modify variables of type u8
 {@fieldParentPtr(Connection, "a", pa).b += 1;} //the signature hid the fact field b of parent struct Connection can be modified.

test "usage" {
 c: Connection = .{.a = 8, .b = 8}; //c is stack-allocated and only "known"/visible within this scope
 assumes_connection(&c.a); //only pointer to a (*u8) passed
 c.b += 1; // "sufficiently smart" compiler/optimizer should assume c.b was not modified
}

From how I understand it, passing a value t of type *T may modify any value s of distinct type S, as long as the compiler cannot prove that t and s are not related via struct composition. This would have to be proven transitively across structs and functions, thereby also ".o"/"language" boundaries. (I think that would only make it reasonable for non-public/-exported types, although in that scope I would expect inlining and local dependency analysis to do a better job regardless.)


Now that I look at it again, even dependencies between structs with pointer fields become kind of hairy. And any opaque type could potentially hide any number of types as fields as well... right? Maybe I just overestimated the applicability of strict aliasing (or underestimated its complexity).
Regardless, without @fieldParentPtr (aka "in the C world"), at least "primitive types" (non-composites) were relatively "safe" to optimize based on this. Now I'm having trouble coming up with any example where strict aliasing would be safe plainly based on function signature (without scope / lifetime information beyond that).

@andrewrk
Copy link
Member

andrewrk commented Oct 8, 2018

Thanks - I'll keep this issue in mind when experimenting with introducing aliasing rules to Zig.

Currently Zig does not have TBAA and it's unclear what aliasing rules Zig will have in the future.

@andrewrk
Copy link
Member

related #1108 and #476

@andrewrk andrewrk modified the milestones: 0.4.0, 0.5.0 Feb 15, 2019
@andrewrk
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants