Skip to content

@fieldParentPtr violates type based aliasing guarantees #1644

Closed
@rohlem

Description

@rohlem

(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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions