From 44d609df5fc694ed1030cf7d56c492fc7e222590 Mon Sep 17 00:00:00 2001
From: Hans Bolinder <hasse@erlang.org>
Date: Fri, 9 Jun 2017 14:34:39 +0200
Subject: stdlib: Evaluate expressions in fun2ms bodies

The ms_transform module, used by ets:fun2ms/1 and dbg:fun2ms,
evaluates constant arithmetic expressions. This is necessary since the
Erlang compiler, which normally evaluates constant expressions, does
not recognize the format generated by ms_transform.
---
 lib/stdlib/src/ms_transform.erl        | 18 ++++++++++++++----
 lib/stdlib/test/ms_transform_SUITE.erl | 15 +++++++++++++--
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/lib/stdlib/src/ms_transform.erl b/lib/stdlib/src/ms_transform.erl
index c1c09f091c..6616e957c0 100644
--- a/lib/stdlib/src/ms_transform.erl
+++ b/lib/stdlib/src/ms_transform.erl
@@ -501,10 +501,20 @@ tg0(Line,[H|T],B) ->
 
 tg({match,Line,_,_},B) -> 
     throw({error,Line,?ERR_GENMATCH+B#tgd.eb});
-tg({op, Line, Operator, O1, O2}, B) ->
-    {tuple, Line, [{atom, Line, Operator}, tg(O1,B), tg(O2,B)]};
-tg({op, Line, Operator, O1}, B) ->
-    {tuple, Line, [{atom, Line, Operator}, tg(O1,B)]};
+tg({op, Line, Operator, O1, O2}=Expr, B) ->
+    case erl_eval:partial_eval(Expr) of
+        Expr ->
+            {tuple, Line, [{atom, Line, Operator}, tg(O1, B), tg(O2, B)]};
+        Value ->
+            Value
+    end;
+tg({op, Line, Operator, O1}=Expr, B) ->
+    case erl_eval:partial_eval(Expr) of
+        Expr ->
+            {tuple, Line, [{atom, Line, Operator}, tg(O1, B)]};
+        Value ->
+            Value
+    end;
 tg({call, _Line, {atom, Line2, bindings},[]},_B) ->
     	    {atom, Line2, '$*'};
 tg({call, _Line, {atom, Line2, object},[]},_B) ->
diff --git a/lib/stdlib/test/ms_transform_SUITE.erl b/lib/stdlib/test/ms_transform_SUITE.erl
index f35013b1b2..d1e6faf863 100644
--- a/lib/stdlib/test/ms_transform_SUITE.erl
+++ b/lib/stdlib/test/ms_transform_SUITE.erl
@@ -1,7 +1,7 @@
 %%
 %% %CopyrightBegin%
 %%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. 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.
@@ -43,6 +43,7 @@
 -export([warnings/1]).
 -export([no_warnings/1]).
 -export([eep37/1]).
+-export([otp_14454/1]).
 
 init_per_testcase(_Func, Config) ->
     Config.
@@ -59,7 +60,7 @@ all() ->
      record_index, multipass, bitsyntax, record_defaults,
      andalso_orelse, float_1_function, action_function,
      warnings, no_warnings, top_match, old_guards, autoimported,
-     semicolon, eep37].
+     semicolon, eep37, otp_14454].
 
 groups() -> 
     [].
@@ -771,6 +772,16 @@ eep37(Config) when is_list(Config) ->
                           "F()">>).
 
 
+otp_14454(Config) when is_list(Config) ->
+    setup(Config),
+    [{'$1',[],[{'band','$1',136}]}] =
+        compile_and_run(
+          <<"ets:fun2ms(fun(A) -> A band ( -(-17) bsl 3) end)">>),
+    [{'$1',[],[{'band','$1',136}]}] =
+        compile_and_run(
+          <<"ets:fun2ms(fun(A) -> A band ( erlang:'bsl'(-(-17), 3)) end)">>),
+    ok.
+
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% Helpers
-- 
cgit v1.2.3