Skip to content

Surprising aliasing despite explicit copy #22906

@jamii

Description

@jamii

Zig Version

0.13.0 and 0.14.0-dev.3223+13ad984b1

Steps to Reproduce and Observed Behavior

Standard PRO/RLS surprise, except that this one occurs through an explicit copy, which means my workarounds can't be trusted. This segfaults only for Thing = [1]u32 and not Thing = u32, and only on llvm backends.

const std = @import("std");

const allocator = std.heap.page_allocator;

const Thing = [1]u32;

// This works fine
// const Thing = u32;

fn replace(box_b: *Thing, a: Thing) void {
    box_b.* = a;
}

fn destroy_and_replace(box_b: *Thing, a: Thing, box_a: *Thing) void {
    allocator.destroy(box_a);
    box_b.* = a;
}

pub fn main() !void {
    // This works fine.
    {
        const box_a = try allocator.create(Thing);
        const box_b = try allocator.create(Thing);

        const a = box_a.*; // explicit copy
        allocator.destroy(box_a);
        replace(box_b, a);
    }

    std.debug.print("ok\n", .{});

    // Moving the destroy into a function causes surprising aliasing, even with an explicit copy.
    {
        const box_a = try allocator.create(Thing);
        const box_b = try allocator.create(Thing);

        const a = box_a.*; // explicit copy
        destroy_and_replace(box_b, a, box_a);
    }
}
> zig run test.zig -O Debug
ok
Segmentation fault at address 0x7f03fc7b2000
/home/jamie/test.zig:16:5: 0x103a82a in destroy_and_replace (test)
    box_b.* = a;
    ^
/home/jamie/test.zig:38:28: 0x103a4a8 in main (test)
        destroy_and_replace(box_b, a, box_a);
                           ^
/nix/store/2dm1d3cxwr7sm3irvwi6k1dk6x9jl9jz-zig/lib/std/start.zig:656:37: 0x103a23a in posixCallMainAndExit (test)
            const result = root.main() catch |err| {
                                    ^
/nix/store/2dm1d3cxwr7sm3irvwi6k1dk6x9jl9jz-zig/lib/std/start.zig:271:5: 0x1039ded in _start (test)
    asm volatile (switch (native_arch) {
    ^
???:?:?: 0x0 in ??? (???)
fish: Job 1, 'zig run test.zig -O Debug' terminated by signal SIGABRT (Abort)

> zig run test.zig -O Debug -fno-llvm -fno-lld -fno-libllvm 
ok

Expected Behavior

> zig run test.zig -O Debug
ok

Metadata

Metadata

Assignees

No one assigned

    Labels

    backend-llvmThe LLVM backend outputs an LLVM IR Module.bugObserved behavior contradicts documented or intended behaviormiscompilationThe compiler reports success but produces semantically incorrect code.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions