Skip to content

Commit

Permalink
Guard a call to jl_types_equal in inst_datatype_inner
Browse files Browse the repository at this point in the history
For recursive data types, this call could lead to infinite recursion, so
guard it with a special condition to re-fix #22624.
  • Loading branch information
martinholters committed Apr 23, 2019
1 parent 0fa10cf commit b430127
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
24 changes: 23 additions & 1 deletion src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,28 @@ static jl_value_t *normalize_vararg(jl_value_t *va)
return va;
}

static int guard_against_22624(jl_value_t *a, jl_value_t *b)
{
if (a == b) return 0;
if ((jl_is_concrete_type(a) && jl_is_typevar(b)) ||
(jl_is_concrete_type(b) && jl_is_typevar(a)))
return 1;
if (jl_is_unionall(a)) a = jl_unwrap_unionall(a);
if (jl_is_unionall(b)) b = jl_unwrap_unionall(b);
if (jl_is_datatype(a) && jl_is_datatype(b)) {
jl_datatype_t *ad = (jl_datatype_t*)a, *bd = (jl_datatype_t*)b;
if (ad->name != bd->name)
return 1;
size_t np = jl_nparams(ad);
if (np != jl_nparams(bd)) return 1;
for (size_t i = 0; i < np; i++) {
if (guard_against_22624(jl_tparam(ad,i), jl_tparam(bd,i)))
return 1;
}
}
return 0;
}

static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **iparams, size_t ntp,
int cacheable, jl_typestack_t *stack, jl_typeenv_t *env)
{
Expand All @@ -1101,7 +1123,7 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
// normalize types equal to wrappers (prepare for wrapper_id)
jl_value_t *tw = extract_wrapper(pi);
if (tw && tw != pi && (tn != jl_type_typename || jl_typeof(pi) == jl_typeof(tw)) &&
jl_types_equal(pi, tw)) {
(!guard_against_22624(pi, tw) && jl_types_equal(pi, tw))) {
iparams[i] = tw;
if (p) jl_gc_wb(p, tw);
}
Expand Down
2 changes: 0 additions & 2 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@ struct D21923{T,N}; v::D21923{T}; end
@test fieldtype(D21923, 1) == D21923

# issue #22624, more circular definitions
#= broken again :-(
struct T22624{A,B,C}; v::Vector{T22624{Int64,A}}; end
let elT = T22624.body.body.body.types[1].parameters[1]
@test elT == T22624{Int64, T22624.var, C} where C
Expand All @@ -227,7 +226,6 @@ let elT = T22624.body.body.body.types[1].parameters[1]
@test elT2.body.types[1].parameters[1] === elT2
@test Base.isconcretetype(elT2.body.types[1])
end
=#

# issue #3890
mutable struct A3890{T1}
Expand Down

0 comments on commit b430127

Please sign in to comment.