File 3521-compiler-Add-support-for-checking-annotations-in-SSA.patch of Package erlang

From da38a38bf41689e52a50868fc93ba2b065b8bc65 Mon Sep 17 00:00:00 2001
From: Frej Drejhammar <frej.drejhammar@gmail.com>
Date: Thu, 1 Dec 2022 11:29:49 +0100
Subject: [PATCH 11/13] compiler: Add support for checking annotations in SSA
 code

Implement support for checking annotations present in SSA code.
---
 lib/compiler/src/beam_ssa_check.erl           | 43 +++++++++++++------
 lib/compiler/test/beam_ssa_check_SUITE.erl    |  6 ++-
 .../beam_ssa_check_SUITE_data/annotations.erl | 40 +++++++++++++++++
 3 files changed, 75 insertions(+), 14 deletions(-)
 create mode 100644 lib/compiler/test/beam_ssa_check_SUITE_data/annotations.erl

diff --git a/lib/compiler/src/beam_ssa_check.erl b/lib/compiler/src/beam_ssa_check.erl
index 53cec045f4..05384fc5f0 100644
--- a/lib/compiler/src/beam_ssa_check.erl
+++ b/lib/compiler/src/beam_ssa_check.erl
@@ -117,11 +117,11 @@ check_exprs(Exprs, Env, #b_function{bs=Blocks}=F) ->
     {File,_} = beam_ssa:get_anno(location, F),
     check_expr_seq(Exprs, Code, Env, never, File).
 
-check_expr_seq([{check_expr,Loc,Args,_}|Rest]=Checks,
+check_expr_seq([{check_expr,Loc,Args,Anno}|Rest]=Checks,
                [First|Code], Env0, LastMatchedLoc, File) ->
     Env = try
               ?DP("trying:~n  pat: ~p~n  i: ~p~n", [Args, First]),
-              op_check(Args, First, Env0)
+              op_check(Args, Anno, First, Env0)
           catch
               throw:no_match ->
                   ?DP("op_check did not match~n"),
@@ -146,32 +146,38 @@ check_expr_seq([{check_expr,Loc,Args,_}|_], [], Env, LastMatchedLoc, File) ->
     [{File,[{Loc,?MODULE,{no_match,Args,LastMatchedLoc,Env}}]}].
 
 
-op_check([set,Result,{atom,_,Op}|PArgs],
-         #b_set{dst=Dst,args=AArgs,op=Op}=_I, Env) ->
+op_check([set,Result,{atom,_,Op}|PArgs], PAnno,
+         #b_set{dst=Dst,args=AArgs,op=Op,anno=AAnno}=_I, Env0) ->
     ?DP("trying set ~p:~n  res: ~p <-> ~p~n  args: ~p <-> ~p~n  i: ~p~n",
         [Op, Result, Dst, PArgs, AArgs, _I]),
+    Env = check_annos(PAnno, AAnno, Env0),
     op_check_call(Op, Result, Dst, PArgs, AArgs, Env);
-op_check([set,Result,{{atom,_,bif},{atom,_,Op}}|PArgs],
-         #b_set{dst=Dst,args=AArgs,op={bif,Op}}=_I, Env) ->
+op_check([set,Result,{{atom,_,bif},{atom,_,Op}}|PArgs], PAnno,
+         #b_set{dst=Dst,args=AArgs,op={bif,Op},anno=AAnno}=_I, Env0) ->
     ?DP("trying bif ~p:~n  res: ~p <-> ~p~n  args: ~p <-> ~p~n  i: ~p~n",
         [Op, Result, Dst, PArgs, AArgs, _I]),
+    Env = check_annos(PAnno, AAnno, Env0),
     op_check_call(Op, Result, Dst, PArgs, AArgs, Env);
-op_check([none,{atom,_,ret}|PArgs], #b_ret{arg=AArg}=_I, Env) ->
+op_check([none,{atom,_,ret}|PArgs], PAnno,
+         #b_ret{arg=AArg,anno=AAnno}=_I, Env0) ->
     ?DP("trying return:, arg: ~p <-> ~p~n  i: ~p~n",
         [PArgs, [AArg], _I]),
+    Env = check_annos(PAnno, AAnno, Env0),
     post_args(PArgs, [AArg], Env);
-op_check([none,{atom,_,br}|PArgs],
-         #b_br{bool=ABool,succ=ASucc,fail=AFail}=_I, Env) ->
+op_check([none,{atom,_,br}|PArgs], PAnno,
+         #b_br{bool=ABool,succ=ASucc,fail=AFail,anno=AAnno}=_I, Env0) ->
     ?DP("trying br: arg: ~p <-> ~p~n  i: ~p~n",
         [PArgs, [ABool,ASucc,AFail], _I]),
+    Env = check_annos(PAnno, AAnno, Env0),
     post_args(PArgs, [ABool,#b_literal{val=ASucc},#b_literal{val=AFail}], Env);
-op_check([none,{atom,_,switch},PArg,PFail,{list,_,PArgs}],
-         #b_switch{arg=AArg,fail=AFail,list=AList}=_I, Env0) ->
+op_check([none,{atom,_,switch},PArg,PFail,{list,_,PArgs}], PAnno,
+         #b_switch{arg=AArg,fail=AFail,list=AList,anno=AAnno}=_I, Env0) ->
     ?DP("trying switch: arg: ~p <-> ~p~n  i: ~p~n",
         [PArgs, [AArg,AFail,AList], _I]),
-    Env = env_post(PArg, AArg, env_post(PFail, #b_literal{val=AFail}, Env0)),
+    Env1 = env_post(PArg, AArg, env_post(PFail, #b_literal{val=AFail}, Env0)),
+    Env = check_annos(PAnno, AAnno, Env1),
     post_switch_args(PArgs, AList, Env);
-op_check([label,PLbl], {label,ALbl}, Env) when is_integer(ALbl) ->
+op_check([label,PLbl], _Anno, {label,ALbl}, Env) when is_integer(ALbl) ->
     env_post(PLbl, #b_literal{val=ALbl}, Env).
 
 op_check_call(Op, PResult, AResult, PArgs, AArgs, Env0) ->
@@ -345,6 +351,17 @@ build_map_key_list([]) ->
 build_map_key_list(E) ->
     build_map_key(E).
 
+check_annos([{term,{atom,_,Key},PTerm}|Patterns], Actual, Env0) ->
+    ?DP("Checking term anno ~p: ~p~nkeys: ~p~n",
+        [Key, PTerm, maps:keys(Actual)]),
+    #{ Key := ATerm } = Actual,
+    ?DP("~p <-> ~p~n", [PTerm, ATerm]),
+    Env = env_post(PTerm, #b_literal{val=ATerm}, Env0),
+    ?DP("ok~n"),
+    check_annos(Patterns, Actual, Env);
+check_annos([], _, Env) ->
+    Env.
+
 -spec format_error(term()) -> nonempty_string().
 
 format_error(xfail_passed) ->
diff --git a/lib/compiler/test/beam_ssa_check_SUITE.erl b/lib/compiler/test/beam_ssa_check_SUITE.erl
index 07b429a202..c5bcb78076 100644
--- a/lib/compiler/test/beam_ssa_check_SUITE.erl
+++ b/lib/compiler/test/beam_ssa_check_SUITE.erl
@@ -28,6 +28,7 @@
          init_per_suite/1, end_per_suite/1,
 	 init_per_group/2,end_per_group/2,
 
+         annotation_checks/1,
          sanity_checks/1]).
 
 suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -36,7 +37,7 @@ all() ->
     [{group,post_ssa_opt_static}].
 
 groups() ->
-    [{post_ssa_opt_static,test_lib:parallel(),[sanity_checks]}].
+    [{post_ssa_opt_static,test_lib:parallel(),[annotation_checks, sanity_checks]}].
 
 init_per_suite(Config) ->
     test_lib:recompile(?MODULE),
@@ -51,6 +52,9 @@ init_per_group(_GroupName, Config) ->
 end_per_group(_GroupName, Config) ->
     Config.
 
+annotation_checks(Config) when is_list(Config) ->
+    run_post_ssa_opt(annotations, Config).
+
 sanity_checks(Config) when is_list(Config) ->
     run_post_ssa_opt(sanity_checks, Config).
 
diff --git a/lib/compiler/test/beam_ssa_check_SUITE_data/annotations.erl b/lib/compiler/test/beam_ssa_check_SUITE_data/annotations.erl
new file mode 100644
index 0000000000..5e938c2588
--- /dev/null
+++ b/lib/compiler/test/beam_ssa_check_SUITE_data/annotations.erl
@@ -0,0 +1,40 @@
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2022. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%%     http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+-module(annotations).
+
+-export([t0/0]).
+
+%% Check annotations, do not add lines before this function without
+%% changing the location annotation.
+t0() ->
+%ssa% () when post_ssa_opt ->
+%ssa% _ = call(fun return_int/0) { result_type => {t_integer,{17,17}},
+%ssa%                              location => {_,32} },
+%ssa% _ = call(fun return_tuple/0) {
+%ssa%    result_type => {t_tuple,2,true,#{1 => {t_integer,{1,1}},
+%ssa%                                     2 => {t_integer,{2,2}}}}
+%ssa% }.
+    X = return_int(),
+    Y = return_tuple(),
+    {X, Y}.
+
+return_int() ->
+    17.
+
+return_tuple() ->
+    {1,2}.
-- 
2.35.3

openSUSE Build Service is sponsored by