File 0513-Correct-an-unsafe-optimization-of-nested-map-matchin.patch of Package erlang

From af34a3d0caf70c8404aaead6474964cf69a72ecd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Mon, 31 Aug 2020 08:18:32 +0200
Subject: [PATCH] Correct an unsafe optimization of nested map matching

Because of an unsafe optimization, the following expression would
fail to match:

    #{ <<"result">> := #{<<"foo">> := <<"6">> } } =
        #{ <<"result">> => #{<<"foo">> => <<"6">> } }
---
 lib/compiler/src/beam_peep.erl  |  6 +++++-
 lib/compiler/test/map_SUITE.erl | 13 +++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/lib/compiler/src/beam_peep.erl b/lib/compiler/src/beam_peep.erl
index eed0b19037..da59aea2bd 100644
--- a/lib/compiler/src/beam_peep.erl
+++ b/lib/compiler/src/beam_peep.erl
@@ -184,7 +184,8 @@ prune_redundant_values([], _) -> [].
 
 simplify_get_map_elements(Fail, Src, {list,[Key,Dst]},
                           [{get_map_elements,Fail,Src,{list,List1}}|Acc]) ->
-    case are_keys_literals([Key]) andalso are_keys_literals(List1) of
+    case are_keys_literals([Key]) andalso are_keys_literals(List1) andalso
+        not is_source_overwritten(Src, List1) of
         true ->
             case member(Key, List1) of
                 true ->
@@ -217,3 +218,6 @@ simplify_has_map_fields(_, _, _) -> error.
 are_keys_literals([{x,_}|_]) -> false;
 are_keys_literals([{y,_}|_]) -> false;
 are_keys_literals([_|_]) -> true.
+
+is_source_overwritten(Src, [_Key,Src]) -> true;
+is_source_overwritten(_, _) -> false.
diff --git a/lib/compiler/test/map_SUITE.erl b/lib/compiler/test/map_SUITE.erl
index 3c5c6214bc..36eb9755d2 100644
--- a/lib/compiler/test/map_SUITE.erl
+++ b/lib/compiler/test/map_SUITE.erl
@@ -1995,6 +1995,15 @@ t_nested_pattern_expressions(Config) when is_list(Config) ->
     F1 = F0(wat),
     F2 = F1(watzor),
     {yep,ok} = F2(M0),
+
+    %% Test matching of nested maps. There used to be an unsafe optimization in beam_peep.
+    #{ <<"result">> := #{<<"foo">> := <<"6">> } } =
+        nested_map(),
+
+    InnerMap = #{a => id({a,value})},
+    OuterMap = #{inner_map => InnerMap},
+    #{inner_map := #{a := {a,value}}} = OuterMap,
+
     ok.
 
 map_nested_pattern_funs(M) ->
@@ -2014,6 +2023,10 @@ map_nested_pattern_funs(M) ->
 	    end
     end.
 
+nested_map() ->
+    #{ <<"result">> := #{<<"foo">> := <<"6">> } } =
+        #{ <<"result">> => #{<<"foo">> => <<"6">> } }.
+
 t_guard_update_variables(Config) when is_list(Config) ->
     error  = map_guard_update_variables(n,#{},#{}),
     first  = map_guard_update_variables(x,#{}, #{x=>first}),
-- 
2.26.2

openSUSE Build Service is sponsored by