Skip to content

Commit

Permalink
jltypes: ensure revising structs is safe (#51303)
Browse files Browse the repository at this point in the history
(cherry picked from commit 1142759)
  • Loading branch information
vtjnash authored and KristofferC committed Sep 15, 2023
1 parent ea93115 commit 0eff9d8
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2491,6 +2491,8 @@ void jl_reinstantiate_inner_types(jl_datatype_t *t) // can throw!

for (j = 0; j < jl_array_len(partial); j++) {
jl_datatype_t *ndt = (jl_datatype_t*)jl_array_ptr_ref(partial, j);
if (ndt == NULL)
continue;
assert(jl_unwrap_unionall(ndt->name->wrapper) == (jl_value_t*)t);
for (i = 0; i < n; i++)
env[i].val = jl_svecref(ndt->parameters, i);
Expand All @@ -2502,6 +2504,8 @@ void jl_reinstantiate_inner_types(jl_datatype_t *t) // can throw!
if (t->types != jl_emptysvec) {
for (j = 0; j < jl_array_len(partial); j++) {
jl_datatype_t *ndt = (jl_datatype_t*)jl_array_ptr_ref(partial, j);
if (ndt == NULL)
continue;
for (i = 0; i < n; i++)
env[i].val = jl_svecref(ndt->parameters, i);
assert(ndt->types == NULL);
Expand All @@ -2510,7 +2514,9 @@ void jl_reinstantiate_inner_types(jl_datatype_t *t) // can throw!
if (ndt->isconcretetype) { // cacheable
jl_compute_field_offsets(ndt);
}
jl_array_ptr_set(partial, j, NULL);
}
t->name->partial = NULL;
}
else {
assert(jl_field_names(t) == jl_emptysvec);
Expand Down
13 changes: 13 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7544,6 +7544,19 @@ end
struct T36104 # check that redefining it works, issue #21816
v::Vector{T36104}
end
struct S36104{K,V}
v::S36104{K,V}
S36104{K,V}() where {K,V} = new()
S36104{K,V}(x::S36104) where {K,V} = new(x)
end
@test !isdefined(Base.unwrap_unionall(Base.ImmutableDict).name, :partial)
@test !isdefined(S36104.body.body.name, :partial)
@test hasfield(typeof(S36104.body.body.name), :partial)
struct S36104{K,V} # check that redefining it works
v::S36104{K,V}
S36104{K,V}() where {K,V} = new()
S36104{K,V}(x::S36104) where {K,V} = new(x)
end
# with a gensymmed unionall
struct Symmetric{T,S<:AbstractMatrix{<:T}} <: AbstractMatrix{T}
data::S
Expand Down

0 comments on commit 0eff9d8

Please sign in to comment.