Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:25
erlang
3501-beam_validator-Fix-inference-on-singleton-...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 3501-beam_validator-Fix-inference-on-singleton-types-in-r.patch of Package erlang
From ebc461e1827a3597268dda8188bee6e777f5e400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org> Date: Thu, 2 Mar 2023 17:44:42 +0100 Subject: [PATCH] beam_validator: Fix inference on singleton types in registers Type inference with singleton types in registers was weaker than inference on their corresponding literals. --- lib/compiler/src/beam_validator.erl | 31 +++++++++++++------ lib/compiler/test/beam_validator_SUITE.erl | 18 +++++++++-- .../singleton_inference.erl | 7 +++++ 3 files changed, 44 insertions(+), 12 deletions(-) create mode 100644 lib/compiler/test/beam_validator_SUITE_data/singleton_inference.erl diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 0378a225b7..ee5f49d03a 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -2282,12 +2282,14 @@ infer_types(CompareOp, LHS, {Kind,_}=RHS, Vst) when Kind =:= x; Kind =:= y -> infer_types(CompareOp, LHS, RHS, #vst{current=#st{vs=Vs}}=Vst0) -> case Vs of #{ LHS := LEntry, RHS := REntry } -> - Vst = infer_types_1(LEntry, RHS, CompareOp, Vst0), - infer_types_1(REntry, LHS, CompareOp, Vst); + Vst = infer_types_1(LEntry, canonical_value(RHS, Vst0), + CompareOp, Vst0), + infer_types_1(REntry, canonical_value(LHS, Vst), + CompareOp, Vst); #{ LHS := LEntry } -> - infer_types_1(LEntry, RHS, CompareOp, Vst0); + infer_types_1(LEntry, canonical_value(RHS, Vst0), CompareOp, Vst0); #{ RHS := REntry } -> - infer_types_1(REntry, LHS, CompareOp, Vst0); + infer_types_1(REntry, canonical_value(LHS, Vst0), CompareOp, Vst0); #{} -> Vst0 end. @@ -2626,12 +2628,9 @@ update_ne_types_1(LHS, RHS, Vst0) -> %% If LHS has a specific value after subtraction we can infer types %% as if we've made an exact match, which is much stronger than %% ne_exact. - LType = get_term_type(LHS, Vst), - case beam_types:get_singleton_value(LType) of - {ok, Value} -> - infer_types(eq_exact, LHS, value_to_literal(Value), Vst); - error -> - Vst + case canonical_value(LHS, Vst) of + LHS -> Vst; + Value -> infer_types(eq_exact, LHS, Value, Vst) end; false -> Vst0 @@ -2761,6 +2760,18 @@ value_to_literal(F) when is_float(F) -> {float,F}; value_to_literal(I) when is_integer(I) -> {integer,I}; value_to_literal(Other) -> {literal,Other}. +canonical_value(Val, Vst) -> + Type = get_term_type(Val, Vst), + case beam_types:is_singleton_type(Type) of + true -> + case beam_types:get_singleton_value(Type) of + {ok, Res} -> value_to_literal(Res); + error -> Val + end; + false -> + Val + end. + %% These are just wrappers around their equivalents in beam_types, which %% handle the validator-specific #t_abstract{} type. %% diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index 8cbce95567..624870659d 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -42,7 +42,7 @@ missing_return_type/1,will_succeed/1, bs_saved_position_units/1,parent_container/1, container_performance/1, - not_equal_inference/1, + not_equal_inference/1,singleton_inference/1, inert_update_type/1]). -include_lib("common_test/include/ct.hrl"). @@ -78,7 +78,7 @@ groups() -> missing_return_type,will_succeed, bs_saved_position_units,parent_container, container_performance, - not_equal_inference, + not_equal_inference,singleton_inference, inert_update_type]}]. init_per_suite(Config) -> @@ -1100,6 +1100,20 @@ not_equal_inference(_Config) -> not_equal_inference_1(X) when (X /= []) /= is_port(0 div 0) -> [X || _ <- []]. +%% GH-6962: Type inference with singleton types in registers was weaker than +%% inference on their corresponding literals. +singleton_inference(Config) -> + Mod = ?FUNCTION_NAME, + + Data = proplists:get_value(data_dir, Config), + File = filename:join(Data, "singleton_inference.erl"), + + {ok, Mod} = compile:file(File, [no_copt, no_bool_opt, no_ssa_opt]), + + ok = Mod:test(), + + ok. + %% GH-6969: A type was made concrete even though that added no additional %% information. inert_update_type(_Config) -> diff --git a/lib/compiler/test/beam_validator_SUITE_data/singleton_inference.erl b/lib/compiler/test/beam_validator_SUITE_data/singleton_inference.erl new file mode 100644 index 0000000000..66f0bb312a --- /dev/null +++ b/lib/compiler/test/beam_validator_SUITE_data/singleton_inference.erl @@ -0,0 +1,7 @@ +-module(singleton_inference). +-export([test/0]). + +test() -> + {'EXIT',{{badmatch,true}, _}} = + catch [0 || (X = (true or (X = is_port(node()))))], + ok. -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor