diff options
author | Hans Bolinder <[email protected]> | 2016-09-16 11:54:57 +0200 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2016-10-06 16:37:59 +0200 |
commit | 87a13c257bfd5a53b6803bc2d714afb13106c243 (patch) | |
tree | ce5b5882e1889649c57ed3466d26c03ec3cfd92d /lib/hipe | |
parent | 5acfcf3758f89ba32d44807cd8cb406a55d39836 (diff) | |
download | otp-87a13c257bfd5a53b6803bc2d714afb13106c243.tar.gz otp-87a13c257bfd5a53b6803bc2d714afb13106c243.tar.bz2 otp-87a13c257bfd5a53b6803bc2d714afb13106c243.zip |
dialyzer: Fix opaque bugs
t_from_form() sometimes returned a more general type than it should
have done due to a bug in from_form_loop(): it stopped when the limit
was exceeded, which could mean a collapsed type. Returning a type with
smaller depth should fix this.
is_specialization() now handles opaque types before unions, which
should fix another problem.
The bugs reported by Kostis.
Diffstat (limited to 'lib/hipe')
-rw-r--r-- | lib/hipe/cerl/erl_types.erl | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl index 15f7b793a1..a6a7efb1de 100644 --- a/lib/hipe/cerl/erl_types.erl +++ b/lib/hipe/cerl/erl_types.erl @@ -3109,6 +3109,10 @@ is_specialization(?tuple_set(List1), ?tuple_set(List2)) -> [sup_tuple_elements(T) || {_Arity, T} <- List2]) catch _:_ -> false end; +is_specialization(?opaque(_) = T1, T2) -> + is_specialization(t_opaque_structure(T1), T2); +is_specialization(T1, ?opaque(_) = T2) -> + is_specialization(T1, t_opaque_structure(T2)); is_specialization(?union(List1)=T1, ?union(List2)=T2) -> case specialization_union2(T1, T2) of {yes, Type1, Type2} -> is_specialization(Type1, Type2); @@ -3124,10 +3128,6 @@ is_specialization(T1, ?union(List)) -> {yes, Type} -> is_specialization(T1, Type); no -> false end; -is_specialization(?opaque(_) = T1, T2) -> - is_specialization(t_opaque_structure(T1), T2); -is_specialization(T1, ?opaque(_) = T2) -> - is_specialization(T1, t_opaque_structure(T2)); is_specialization(?var(_), _) -> exit(error); is_specialization(_, ?var(_)) -> exit(error); is_specialization(?none, _) -> false; @@ -4482,28 +4482,31 @@ t_from_form1(Form, ET, Site, MR, V, C) -> vtab = V, tnames = TypeNames}, L = ?EXPAND_LIMIT, - {T1, L1, C1} = from_form(Form, State, ?EXPAND_DEPTH, L, C), + {T0, L0, C0} = from_form(Form, State, ?EXPAND_DEPTH, L, C), if - L1 =< 0 -> - from_form_loop(Form, State, 1, L, C1); + L0 =< 0 -> + {T1, _, C1} = from_form(Form, State, 1, L, C0), + from_form_loop(Form, State, 2, L, C1, T1); true -> - {T1, C1} + {T0, C0} end. initial_typenames({type, _MTA}=Site) -> [Site]; initial_typenames({spec, _MFA}) -> []; initial_typenames({record, _MRA}) -> []. -from_form_loop(Form, State, D, Limit, C) -> +from_form_loop(Form, State, D, Limit, C, T0) -> {T1, L1, C1} = from_form(Form, State, D, Limit, C), Delta = Limit - L1, if - %% Save some time by assuming next depth will exceed the limit. + L1 =< 0 -> + {T0, C1}; Delta * 8 > Limit -> + %% Save some time by assuming next depth will exceed the limit. {T1, C1}; true -> D1 = D + 1, - from_form_loop(Form, State, D1, Limit, C1) + from_form_loop(Form, State, D1, Limit, C1, T1) end. -spec from_form(parse_form(), |