Skip to content

Commit

Permalink
fix #30741, fix #31082, stack overflow in type intersection
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Feb 25, 2019
1 parent 31234a5 commit 045e233
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 11 deletions.
40 changes: 29 additions & 11 deletions src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -1382,6 +1382,20 @@ static int try_subtype_in_env(jl_value_t *a, jl_value_t *b, jl_stenv_t *e)
return ret;
}

static void set_bound(jl_value_t **bound, jl_value_t *val, jl_tvar_t *v, jl_stenv_t *e)
{
if (in_union(val, (jl_value_t*)v))
return;
jl_varbinding_t *btemp = e->vars;
while (btemp != NULL) {
if (btemp->lb == (jl_value_t*)v && btemp->ub == (jl_value_t*)v &&
in_union(val, (jl_value_t*)btemp->var))
return;
btemp = btemp->prev;
}
*bound = val;
}

static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int8_t R, int param)
{
jl_varbinding_t *bb = lookup(e, b);
Expand Down Expand Up @@ -1445,8 +1459,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
JL_GC_POP();
return jl_bottom_type;
}
if (ub != (jl_value_t*)b)
bb->ub = ub;
set_bound(&bb->ub, ub, b, e);
JL_GC_POP();
return (jl_value_t*)b;
}
Expand All @@ -1456,8 +1469,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
if (!subtype_in_env(a, bb->ub, e))
return jl_bottom_type;
jl_value_t *lb = simple_join(bb->lb, a);
if (lb != (jl_value_t*)b)
bb->lb = lb;
set_bound(&bb->lb, lb, b, e);
return a;
}
assert(bb->constraintkind == 3);
Expand All @@ -1471,7 +1483,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
// if the var has an equality constraint then make sure bounds stay consistent.
// TODO: try to use this check in more cases
bb->ub != bb->lb || try_subtype_in_env(bb->lb, ub, e)) {
bb->ub = ub;
set_bound(&bb->ub, ub, b, e);
return (jl_value_t*)b;
}
return ub;
Expand All @@ -1486,8 +1498,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
if (ii == jl_bottom_type) {
restore_env(e, root, &se);
ii = (jl_value_t*)b;
if (ub != (jl_value_t*)b)
bb->ub = ub;
set_bound(&bb->ub, ub, b, e);
}
free(se.buf);
JL_GC_POP();
Expand Down Expand Up @@ -1694,12 +1705,14 @@ static jl_value_t *intersect_unionall_(jl_value_t *t, jl_unionall_t *u, jl_stenv
e->vars = vb->prev;

if (res != jl_bottom_type) {
// fail on circular constraints
if (jl_has_typevar(vb->lb, u->var) || jl_has_typevar(vb->ub, u->var))
if (vb->ub == jl_bottom_type && vb->occurs_cov) {
// T=Bottom in covariant position
res = jl_bottom_type;
// T=Bottom in covariant position
if (vb->ub == jl_bottom_type && vb->occurs_cov)
}
else if (jl_has_typevar(vb->lb, u->var) || jl_has_typevar(vb->ub, u->var)) {
// fail on circular constraints
res = jl_bottom_type;
}
}
if (res != jl_bottom_type)
// res is rooted by callee
Expand Down Expand Up @@ -2040,6 +2053,11 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa
if (R) flip_vars(e);
if (!ccheck)
return jl_bottom_type;
if (var_occurs_inside(xub, (jl_tvar_t*)y, 0, 0) && var_occurs_inside(yub, (jl_tvar_t*)x, 0, 0)) {
// circular constraint. the result will be Bottom, but in the meantime
// we need to avoid computing intersect(xub, yub) since it won't terminate.
return y;
}
jl_value_t *ub=NULL, *lb=NULL;
JL_GC_PUSH2(&lb, &ub);
ub = intersect_aside(xub, yub, e, xx ? xx->depth0 : 0);
Expand Down
8 changes: 8 additions & 0 deletions test/subtype.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1420,3 +1420,11 @@ let U = Tuple{Union{LT, LT1},Union{R, R1},Int} where LT1<:R1 where R1<:Tuple{Int
@test U2 == V
@test_broken U2 == V2
end

# issue #31082 and #30741
@testintersect(Tuple{T, Ref{T}, T} where T,
Tuple{Ref{S}, S, S} where S,
Union{})
@testintersect(Tuple{Pair{B,C},Union{C,Pair{B,C}},Union{B,Real}} where {B,C},
Tuple{Pair{B,C},C,C} where {B,C},
Tuple{Pair{B,C},C,C} where C<:Union{Real, B} where B)

0 comments on commit 045e233

Please sign in to comment.