Skip to content

Something is wrong with arrays of weird-length primitives #26026

@chethega

Description

@chethega

Discussion on https://discourse.julialang.org/t/odd-byte-length-primitive-types-and-reinterpret/9025/3.

Reproduce:

primitive type Int24 24 end
Int24(x::Int) = Core.Intrinsics.trunc_int(Int24, x)
Base.zero(::Type{Int24})=Int24(0)

V=Vector{Int24}(1000);
p=reinterpret(Ptr{UInt8}, pointer(V));
for i=1:sizeof(V) unsafe_store!(p+i, UInt8(i)) end

@show V[1:4];
#V[1:4] = Int24[Int24(0x020100), Int24(0x060504), Int24(0x0a0908), Int24(0x007f37)]

So we see that the arrayref behaves like Int24 had size 4 (tree bytes plus one padding). The same happens for pointerref:

@show unsafe_load(pointer(V,2));
@show unsafe_load(pointer(V)+3);
@show unsafe_load(pointer(V),2);
#unsafe_load(pointer(V, 2)) = Int24(0x050403)
#unsafe_load(pointer(V) + 3) = Int24(0x050403)
#unsafe_load(pointer(V), 2) = Int24(0x060504)

Of course that means that we see oob memory and corrupt on writes:

@show V[length(V)];
# V[length(V)] = Int24(0x007f37)
V=zeros(Int24, 1000)
#signal (11): Segmentation fault

Tested both on 0.62 and current master 0.7.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIndicates an unexpected problem or unintended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions