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

support comptime @ptrCast #955

Open
walac opened this Issue Apr 25, 2018 · 6 comments

Comments

Projects
None yet
3 participants
@walac
Contributor

walac commented Apr 25, 2018

Code:

const std = @import("std");
const mem = std.mem;
const assert = std.debug.assert;
const warn = std.debug.warn;
const builtin = @import("builtin");
const is_test = builtin.is_test;


extern fn memcpy(dest: ?&c_void, src: ?&const c_void, count: usize) ?&c_void {
    const s = ((&[]const u8)??src)[0..usize];
    var d = ((&[]u8)??dest)[0..usize];
    mem.copy(u8, d, s);
    return dest;
}

test "memcpy" {
    const src = []const u8{0, 1, 2, 3, 5, 6, 7, 8, 9};
    var dst: [10]u8 = undefined;

    const c_src = @ptrCast(&const c_void, &src[0]);
    var c_dst = @ptrCast(&c_void, &dst[0]);

    const p = memcpy(c_dst, c_src, src.len);
    assert(@ptrCast(&u8, p) == @ptrCast(&u8, c_dst));
    assert(mem.eql(u8, src, dst));
}

comptime {
    if (is_test) {
        const linkage = builtin.GlobalLinkage.Internal;
        @export("_memcpy", memcpy, linkage);
    } else {
        const linkage = builtin.GlobalLinkage.Weak;
        @export("memcpy", memcpy, linkage);
    }
}

Running:

$ ~/work/zig/build/zig test string.zig
zig: /home/vagrant/work/zig/src/ir.cpp:16297: TypeTableEntry* ir_analyze_instruction_slice(IrAnalyze*, IrInstructionSlice*): Assertion `ptr_type->id == TypeTableEntryIdPointer' failed.
Aborted (core dumped)

@andrewrk andrewrk added this to the 0.3.0 milestone Apr 26, 2018

@andrewrk andrewrk added the bug label Apr 26, 2018

@tgschultz

This comment has been minimized.

Contributor

tgschultz commented May 7, 2018

Ran into what I think might be the same issue.

const warn = @import("std").debug.warn;
const S = packed struct
{
    f: u32,
};

const bytes = []u8{0} ** (@sizeOf(S) * 64);

//esses has to be const
const esses = @ptrCast(&const S, &bytes[0])[0..64];

pub fn main() void
{
    warn("{}\n", esses[10].f);
}

Not running a debug build, so I don't have an assertion message for you.

This variation only crashes in release modes:

const std = @import("std");
const warn = std.debug.warn;
var random = std.rand.DefaultPrng.init(0xDEADC0DEBEEFFACE).random;

const bytes = []u8{0} ** (@sizeOf(u32) * 64);

//esses has to be const
const esses = @ptrCast(&const u32, &bytes[0])[0..64];

pub fn main() void
{
    var start = random.range(usize, 0, 64);
    warn("{}\n", esses[start]);
}
@andrewrk

This comment has been minimized.

Member

andrewrk commented Sep 5, 2018

The original example when ported to the new syntax correctly reports a compile error:

const std = @import("std");
const mem = std.mem;
const assert = std.debug.assert;
const warn = std.debug.warn;
const builtin = @import("builtin");
const is_test = builtin.is_test;

extern fn memcpy(dest: ?*c_void, src: ?*const c_void, count: usize) ?*c_void {
    const s = ((*[]const u8) orelse src)[0..usize];
    var d = ((*[]u8) orelse dest)[0..usize];
    mem.copy(u8, d, s);
    return dest;
}

test "memcpy" {
    const src = []const u8{ 0, 1, 2, 3, 5, 6, 7, 8, 9 };
    var dst: [10]u8 = undefined;

    const c_src = @ptrCast(*const c_void, &src[0]);
    var c_dst = @ptrCast(*c_void, &dst[0]);

    const p = memcpy(c_dst, c_src, src.len);
    assert(@ptrCast(*u8, p) == @ptrCast(*u8, c_dst));
    assert(mem.eql(u8, src, dst));
}

comptime {
    if (is_test) {
        const linkage = builtin.GlobalLinkage.Internal;
        @export("_memcpy", memcpy, linkage);
    } else {
        const linkage = builtin.GlobalLinkage.Weak;
        @export("memcpy", memcpy, linkage);
    }
}
/home/andy/downloads/zig/build/test.zig:9:17: error: expected optional type, found 'type'
    const s = ((*[]const u8) orelse src)[0..usize];
                ^
/home/andy/downloads/zig/build/test.zig:10:15: error: expected optional type, found 'type'
    var d = ((*[]u8) orelse dest)[0..usize];
              ^

Side note, it looks like the code is attempting to pointer cast src and dest to slices, which is definitely wrong. @walac what were you trying to do? @memcpy is already a compiler builtin.

@andrewrk

This comment has been minimized.

Member

andrewrk commented Sep 5, 2018

@tgschultz your issue is totally different. Here's the updated test case:

const warn = @import("std").debug.warn;
const S = packed struct {
    f: u32,
};

const bytes = []u8{0} ** (@sizeOf(S) * 64);

//esses has to be const
const esses = @ptrCast([*]const S, &bytes[0])[0..64];

pub fn main() void {
    warn("{}\n", esses[10].f);
}

I'll just go ahead and hijack this issue for the above code snippet.

@andrewrk

This comment has been minimized.

Member

andrewrk commented Sep 5, 2018

Here's an even simpler example of the problem:

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

comptime {
    var bytes = []u8{0} ** 4;
    const ptr = @ptrCast(*u32, &bytes);
    ptr.* = 0x12121212;
    assert(bytes[0] == 0x12);
}

Essentially, @ptrCast at comptime is going to crash the compiler right now, and it's going to take a lot of effort to change that. However we can't just disallow it, because it does work for some things, and we want to make it work for more things.

@andrewrk andrewrk changed the title from Compiler assertion failure to comptime @ptrCast crashes the compiler Sep 5, 2018

andrewrk added a commit that referenced this issue Sep 5, 2018

@andrewrk

This comment has been minimized.

Member

andrewrk commented Sep 5, 2018

@tgschultz your example now does this instead of crashing:

/home/andy/downloads/zig/build/test.zig:12:27: error: TODO handle comptime reinterpreted pointer. See https://github.com/ziglang/zig/issues/955
    warn("{}\n", esses[10].f);
                          ^

I'll leave this issue open until all this compile error is gone and the example compiles and runs correctly.

@andrewrk andrewrk added enhancement and removed bug labels Sep 5, 2018

@andrewrk andrewrk modified the milestones: 0.3.0, 0.4.0 Sep 5, 2018

@andrewrk andrewrk changed the title from comptime @ptrCast crashes the compiler to support comptime @ptrCast Sep 5, 2018

@walac

This comment has been minimized.

Contributor

walac commented Sep 27, 2018

@andrewrk sorry, this was lost in my inbox. I was trying to write a glibc version of memcpy and memset.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment