Skip to content

Commit fe2287f

Browse files
JeffBezansonElOceanografo
authored andcommitted
fix JuliaLang#39804, ABI handling of structs with String references (JuliaLang#39821)
1 parent abc1f1d commit fe2287f

5 files changed

Lines changed: 12 additions & 6 deletions

File tree

src/abi_aarch64.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Type *get_llvm_vectype(jl_datatype_t *dt) const
1717
{
1818
// Assume jl_is_datatype(dt) && !jl_is_abstracttype(dt)
1919
// `!dt->mutabl && dt->pointerfree && !dt->haspadding && dt->nfields > 0`
20-
if (dt->layout == NULL)
20+
if (dt->layout == NULL || jl_is_layout_opaque(dt->layout))
2121
return nullptr;
2222
size_t nfields = dt->layout->nfields;
2323
assert(nfields > 0);

src/abi_ppc64le.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ unsigned isHFA(jl_datatype_t *ty, jl_datatype_t **ty0, bool *hva) const
8383
int n = 0;
8484
for (i = 0; i < l; i++) {
8585
jl_datatype_t *fld = (jl_datatype_t*)jl_field_type(ty, i);
86-
if (!jl_is_datatype(fld) || ((jl_datatype_t*)fld)->layout == NULL)
86+
if (!jl_is_datatype(fld) || ((jl_datatype_t*)fld)->layout == NULL || jl_is_layout_opaque(((jl_datatype_t*)fld)->layout))
8787
return 9;
8888
n += isHFA((jl_datatype_t*)fld, ty0, hva);
8989
if (n > 8)

src/abi_x86_64.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ void classifyType(Classification& accum, jl_datatype_t *dt, uint64_t offset) con
147147
accum.addField(offset, Sse);
148148
}
149149
// Other struct types
150-
else if (jl_datatype_size(dt) <= 16) {
150+
else if (jl_datatype_size(dt) <= 16 && dt->layout) {
151151
size_t i;
152152
for (i = 0; i < jl_datatype_nfields(dt); ++i) {
153153
jl_value_t *ty = jl_field_type(dt, i);
154-
if (!jl_is_datatype(ty) || ((jl_datatype_t*)ty)->layout == NULL || jl_is_array_type(ty))
154+
if (jl_field_isptr(dt, i))
155155
ty = (jl_value_t*)jl_voidpointer_type;
156156
classifyType(accum, (jl_datatype_t*)ty, offset + jl_field_offset(dt, i));
157157
}

src/ccall.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,7 +1011,7 @@ std::string generate_func_sig(const char *fname)
10111011
abi->use_sret(jl_nothing_type);
10121012
}
10131013
else {
1014-
if (!jl_is_datatype(rt) || ((jl_datatype_t*)rt)->layout == NULL || jl_is_cpointer_type(rt) || jl_is_array_type(rt) || retboxed) {
1014+
if (!jl_is_datatype(rt) || ((jl_datatype_t*)rt)->layout == NULL || jl_is_layout_opaque(((jl_datatype_t*)rt)->layout) || jl_is_cpointer_type(rt) || retboxed) {
10151015
prt = lrt; // passed as pointer
10161016
abi->use_sret(jl_voidpointer_type);
10171017
}
@@ -1072,7 +1072,7 @@ std::string generate_func_sig(const char *fname)
10721072
}
10731073

10741074
Type *pat;
1075-
if (!jl_is_datatype(tti) || ((jl_datatype_t*)tti)->layout == NULL || jl_is_array_type(tti)) {
1075+
if (!jl_is_datatype(tti) || ((jl_datatype_t*)tti)->layout == NULL || jl_is_layout_opaque(((jl_datatype_t*)tti)->layout)) {
10761076
tti = (jl_value_t*)jl_voidpointer_type; // passed as pointer
10771077
}
10781078

test/ccall.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,12 @@ unstable26078(x) = x > 0 ? x : "foo"
10031003
handle26078 = @cfunction(unstable26078, Int32, (Int32,))
10041004
@test ccall(handle26078, Int32, (Int32,), 1) == 1
10051005

1006+
# issue #39804
1007+
let f = @cfunction(Base.last, String, (Tuple{Int,String},))
1008+
# String inside a struct is a pointer even though String.size == 0
1009+
@test ccall(f, Ref{String}, (Tuple{Int,String},), (1, "a string?")) === "a string?"
1010+
end
1011+
10061012
# issue 17219
10071013
function ccall_reassigned_ptr(ptr::Ptr{Cvoid})
10081014
ptr = Libdl.dlsym(Libdl.dlopen(libccalltest), "test_echo_p")

0 commit comments

Comments
 (0)