Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
2712-compiler-Run-erl_pp-legalize_vars-1-when-d...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 2712-compiler-Run-erl_pp-legalize_vars-1-when-dumping-cod.patch of Package erlang
From bc315e52b7238b9fa175614a215805686cfff214 Mon Sep 17 00:00:00 2001 From: Frej Drejhammar <frej.drejhammar@gmail.com> Date: Tue, 9 Nov 2021 15:43:59 +0100 Subject: [PATCH 2/2] compiler: Run erl_pp:legalize_vars/1 when dumping code using `-E` When running the compiler using `-E` to produce a listing of the code, after all source code transformations had been performed, could produce a module, which when parsed again, was not semantically equivalent to the input. This patch adds a new pass which is enabled when `-E` is used and runs erl_pp:legalize_vars/1 on all functions before producing a listing. erl_pp:legalize_vars/1 will ensure that the ouput will be semantically equivalent to the input. --- lib/compiler/src/compile.erl | 9 +++++ lib/compiler/test/compile_SUITE.erl | 36 +++++++++++++++++-- lib/compiler/test/compile_SUITE_data/bigE.erl | 22 ++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 lib/compiler/test/compile_SUITE_data/bigE.erl diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index f5f61cbd96..ef46c990a7 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -806,6 +806,7 @@ abstr_passes(AbstrStatus) -> ?pass(expand_records), {iff,'dexp',{listing,"expand"}}, + {iff,'E',?pass(legalize_vars)}, {iff,'E',{src_listing,"E"}}, {iff,'to_exp',{done,"E"}}, @@ -1422,6 +1423,14 @@ expand_records(Code0, #compile{options=Opts}=St) -> Code = erl_expand_records:module(Code0, Opts), {ok,Code,St}. +legalize_vars(Code0, St) -> + Code = map(fun(F={function,_,_,_,_}) -> + erl_pp:legalize_vars(F); + (F) -> + F + end, Code0), + {ok,Code,St}. + compile_directives(Forms, #compile{options=Opts0}=St) -> Opts = expand_opts(flatten([C || {attribute,_,compile,C} <- Forms])), {ok, Forms, St#compile{options=Opts ++ Opts0}}. diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index efee6b9674..abc570984d 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -26,7 +26,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, - app_test/1,appup_test/1, + app_test/1,appup_test/1,bigE_roundtrip/1, debug_info/4, custom_debug_info/1, custom_compile_info/1, file_1/1, forms_2/1, module_mismatch/1, outdir/1, binary/1, makedep/1, cond_and_ifdef/1, listings/1, listings_big/1, @@ -48,7 +48,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. -spec all() -> all_return_type(). all() -> - [app_test, appup_test, file_1, forms_2, module_mismatch, outdir, + [app_test, appup_test, bigE_roundtrip, file_1, + forms_2, module_mismatch, outdir, binary, makedep, cond_and_ifdef, listings, listings_big, other_output, kernel_listing, encrypted_abstr, tuple_calls, strict_record, utf8_atoms, utf8_functions, extra_chunks, @@ -85,6 +86,37 @@ app_test(Config) when is_list(Config) -> appup_test(Config) when is_list(Config) -> ok = test_server:appup_test(compiler). +%% Check that a file compiled to the abstract form and dumped with -E +%% can be compiled. We use a file constructed to produce errors if the +%% dumping fails to legalize compiler generated variable names. +bigE_roundtrip(Config) when is_list(Config) -> + DataDir = proplists:get_value(data_dir, Config), + PrivDir = proplists:get_value(priv_dir, Config), + Source = filename:join(DataDir, "bigE.erl"), + TargetDir = filename:join(PrivDir, "bigE"), + Target = filename:join(TargetDir, "bigE.E"), + TargetSource = filename:join(TargetDir, "bigE.erl"), + ok = file:make_dir(TargetDir), + io:format("Source: ~p~nTargetDir: ~p~nTarget: ~p\n", + [Source, TargetDir, Target]), + case compile:file(Source, + ['E', warnings_as_errors, {outdir, TargetDir}]) of + {ok, _} -> ok; + Other -> ct:fail({unexpected_result, Other}) + end, + %% Rename the output to .erl so that the compiler accepts it and + %% we won't get a warning due to the filename not matching the + %% module name. + ok = file:rename(Target, TargetSource), + case compile:file(TargetSource, + [warnings_as_errors, {outdir, TargetDir}]) of + {ok, _} -> ok; + Other1 -> ct:fail({unexpected_result, Other1}) + end, + file:delete(TargetSource), + file:del_dir(TargetDir), + ok. + %% Tests that we can compile and run a simple Erlang program, %% using compile:file/1. diff --git a/lib/compiler/test/compile_SUITE_data/bigE.erl b/lib/compiler/test/compile_SUITE_data/bigE.erl new file mode 100644 index 0000000000..598b8fc965 --- /dev/null +++ b/lib/compiler/test/compile_SUITE_data/bigE.erl @@ -0,0 +1,22 @@ +-module(bigE). + +-export([f/1]). + +-record(r, {a, b}). + +f(#r{b = B} = C) -> + receive + B -> + X = C#r.a, + %% The compiler will do a case to extract the `a` field + %% using a pattern variable named `rec0`. Without + %% legalization the variable will be output as an atom and + %% the compiler will report an error as the following `X + + %% X` will always fail. + REC0 = X + X, + %% If the legalization fails to detect that the default + %% legalization of uppercasing the pattern variable would + %% collide with the `REC0` below, we will get a warning + %% for an unsafe use. + REC0 + end. -- 2.31.1
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