Skip to content

Commit 7407595

Browse files
committed
Ensure sizeof returns correctly for isbits Union arrays. Fixes #23321
1 parent 88a553a commit 7407595

File tree

3 files changed

+20
-7
lines changed

3 files changed

+20
-7
lines changed

src/builtins.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,15 @@ JL_CALLABLE(jl_f_sizeof)
270270
jl_error("type does not have a fixed size");
271271
return jl_box_long(jl_datatype_size(x));
272272
}
273-
if (jl_is_array(x))
274-
return jl_box_long(jl_array_len(x) * ((jl_array_t*)x)->elsize);
273+
if (jl_is_array(x)) {
274+
jl_value_t *ety = jl_tparam0(jl_typeof(x));
275+
size_t elsize = 0, al = 0;
276+
int isboxed = !jl_islayout_inline(ety, &elsize, &al);
277+
if (isboxed)
278+
elsize = sizeof(void*);
279+
size_t len = jl_array_len(x);
280+
return jl_box_long((!isboxed && jl_is_uniontype(ety)) ? len * elsize + len : len * elsize);
281+
}
275282
if (jl_is_string(x))
276283
return jl_box_long(jl_string_len(x));
277284
if (jl_is_symbol(x))

src/codegen.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2718,18 +2718,24 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
27182718
auto len = emit_arraylen(ctx, obj, ary_ex);
27192719
jl_value_t *ety = jl_tparam0(sty);
27202720
Value *elsize;
2721+
size_t elsz = 0, al = 0;
2722+
bool isboxed = !jl_islayout_inline(ety, &elsz, &al);
27212723
if (!jl_has_free_typevars(ety)) {
2722-
if (!jl_array_store_unboxed(ety)) {
2724+
if (isboxed) {
27232725
elsize = ConstantInt::get(T_size, sizeof(void*));
27242726
}
27252727
else {
2726-
elsize = ConstantInt::get(T_size, jl_datatype_size(ety));
2728+
elsize = ConstantInt::get(T_size, elsz);
27272729
}
27282730
}
27292731
else {
27302732
elsize = ctx.builder.CreateZExt(emit_arrayelsize(ctx, obj), T_size);
27312733
}
2732-
*ret = mark_julia_type(ctx, ctx.builder.CreateMul(len, elsize), false, jl_long_type);
2734+
Value *sz = ctx.builder.CreateMul(len, elsize);
2735+
if (!isboxed && jl_is_uniontype(ety)) {
2736+
sz = ctx.builder.CreateAdd(sz, len);
2737+
}
2738+
*ret = mark_julia_type(ctx, sz, false, jl_long_type);
27332739
return true;
27342740
}
27352741
if (jl_is_type_type((jl_value_t*)sty) && !jl_is_typevar(jl_tparam0(sty))) {

test/core.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5284,7 +5284,7 @@ for U in unboxedunions
52845284
mxsz = maximum(sizeof, Base.uniontypes(U))
52855285
A = Array{U}(len)
52865286
@test length(A) == prod(len)
5287-
@test Core.sizeof(A) == prod(len) * mxsz
5287+
@test Core.sizeof(A) == prod(len) * mxsz + prod(len)
52885288
@test isassigned(A, 1)
52895289
@test isassigned(A, length(A))
52905290

@@ -5312,7 +5312,7 @@ for U in unboxedunions
53125312

53135313
# reshape
53145314
A3 = reshape(A, (div(prod(len), 2), 2))
5315-
@test Core.sizeof(A) == prod(len) * mxsz
5315+
@test Core.sizeof(A) == prod(len) * mxsz + prod(len)
53165316
@test isassigned(A, 1)
53175317
@test A[1] === initvalue2(F)
53185318

0 commit comments

Comments
 (0)