Skip to content

Pointer (even if it's const) can be reassigned to non-pointer #3649

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
ghost opened this issue Nov 10, 2019 · 2 comments
Closed

Pointer (even if it's const) can be reassigned to non-pointer #3649

ghost opened this issue Nov 10, 2019 · 2 comments
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Milestone

Comments

@ghost
Copy link

ghost commented Nov 10, 2019

This nonsense code successfully compiles:

const Struct = struct { field: u32 };
pub fn main() void {
    var val = Struct { .field = 1 };
    const ptr = &val;
    ptr = Struct { .field = 2 };

    @import("std").debug.assert(ptr == &val);
}

It will correctly fail if you change the struct to a plain u32, or if you try to reassign ptr to a pre-existing variable instead of a literal.

A variation - this segfaults the compiler:

const Struct = struct { field: u32 };
pub fn main() void {
    // val is now const, ptr is now var
    const val = Struct { .field = 1 };
    var ptr = &val;
    ptr = Struct { .field = 2 };
}   
@andrewrk andrewrk added this to the 0.6.0 milestone Nov 10, 2019
@andrewrk andrewrk added the bug Observed behavior contradicts documented or intended behavior label Nov 10, 2019
@momumi
Copy link
Contributor

momumi commented Jan 20, 2020

Another variant using slices:

const warn = @import("std").debug.warn;

pub fn main() anyerror!void {
    var odd_nums = [3]u8 {1,3,5};
    var even_nums = [3]u8 {2,4,6};
    const slice: []u8 = even_nums[0..];
    slice[0] = 0;
    slice = odd_nums[0..]; // should be invalid, slice is const
    slice[0] = 0;

    warn("odds : {x}\n", .{ odd_nums }); // prints  000305
    warn("evens: {x}\n", .{ even_nums }); // prints 000406
}

Edit:

I tried reproducing the versions with struct above, but it seems to be fixed now in master. However, the bug still seems to effect slices.

Edit2:

Another example with structs that shouldn't work:

const Struct = struct { field: u32 };
pub fn main() void {
    const val = Struct { .field = 1 };
    const ptr: *const Struct = &val;
    ptr.* = Struct { .field = 2 }; // should be invalid, since ptr points to const data
    // ptr.field = 2; // this fails to compile (correct behavior)

    warn("{}\n", .{ val.field }); // prints 2
}

Edit3:

This code also ignores const without using pointers:

const U = union {
    A: u32,
    B: u32,
};

pub fn main() void {
    const a: U = U{ .A = 0 };

    a = U{ .B = 1 }; // invalid, a is const

    warn("warn: {}\n", .{a.B});
}

The root cause of this bug might be related to copy elision bugs: #4021

Some other bugs where const gets ignored: (#4015, #3800)

@andrewrk andrewrk added the stage1 The process of building from source via WebAssembly and the C backend. label Apr 5, 2020
@andrewrk andrewrk modified the milestones: 0.6.0, 0.7.0 Apr 5, 2020
@Vexu
Copy link
Member

Vexu commented Apr 9, 2020

Fixed by #4975.

./build/a.zig:266:18: error: cannot assign to constant
    ptr = Struct { .field = 2 };
                 ^
./build/a.zig:267:18: error: type '*const Struct' does not support struct initialization syntax
    ptr = Struct { .field = 2 };
                 ^
./build/a.zig:267:21: error: cannot assign to constant
    slice = odd_nums[0..]; // should be invalid, slice is const
                    ^
./build/a.zig:297:20: error: cannot assign to constant
    ptr.* = Struct { .field = 2 }; // should be invalid, since ptr points to const data
                   ^
./build/a.zig:270:10: error: cannot assign to constant
    a = U{ .B = 1 }; // invalid, a is const
         ^

@Vexu Vexu closed this as completed Apr 9, 2020
@Vexu Vexu modified the milestones: 0.7.0, 0.6.0 Apr 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Projects
None yet
Development

No branches or pull requests

3 participants