File 2751-yecc-Avoid-compilation-errors-if-atoms-become-reserv.patch of Package erlang

From 8025a032193bbf0f58b70d04c6c4617012d00f86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Wed, 10 Nov 2021 10:17:20 +0100
Subject: [PATCH] yecc: Avoid compilation errors if atoms become reserved words

In code generated by `yecc`, only atoms known to be reserved words
would be quoted. If a generated module is later compiled with a
version of the compiler that has made one of the used atoms a
reserved word, compilation would fail.

Avoid the problem by having `yecc` code quote all atoms in the
generated code.
---
 lib/parsetools/src/yecc.erl | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl
index 98b7102293..93a512fceb 100644
--- a/lib/parsetools/src/yecc.erl
+++ b/lib/parsetools/src/yecc.erl
@@ -2130,7 +2130,7 @@ output_goto_fini(F, NT, #yecc{includefile_version = {1,1}}=St0) ->
                 [F]),
     fwrite(St, 
            ?YECC_BUG(<<"{~ts, State, missing_in_goto_table}">>,
-                     [quoted_atom(St0, NT)]),
+                     [quoted_atom(NT)]),
            []);
 output_goto_fini(_F, _NT, St) ->
     fwrite(St, <<".\n\n">>, []).
@@ -2255,13 +2255,13 @@ output_action(St, State, Terminal, #reduce{}=Action, IsFirst, SI) ->
 output_action(St0, State, Terminal, #shift{state = NewState}, IsFirst, _SI) ->
     St10 = delim(St0, IsFirst),
     St = fwrite(St10, <<"yeccpars2_~w(S, ~ts, Ss, Stack, T, Ts, Tzr) ->\n">>,
-                [State, quoted_atom(St10, Terminal)]),
+                [State, quoted_atom(Terminal)]),
     output_call_to_includefile(NewState, St);
 output_action(St0, State, Terminal, accept, IsFirst, _SI) ->
     St10 = delim(St0, IsFirst),
     St = fwrite(St10, 
                 <<"yeccpars2_~w(_S, ~ts, _Ss, Stack, _T, _Ts, _Tzr) ->\n">>,
-                [State, quoted_atom(St10, Terminal)]),
+                [State, quoted_atom(Terminal)]),
     fwrite(St, <<" {ok, hd(Stack)}">>, []);
 output_action(St, _State, _Terminal, nonassoc, _IsFirst, _SI) ->
     St.
@@ -2287,7 +2287,7 @@ output_reduce(St0, State, Terminal,
               IsFirst, StateInfo) ->
     St10 = delim(St0, IsFirst),
     QuotedTerminal = if 
-                         is_atom(Terminal) -> quoted_atom(St10, Terminal);
+                         is_atom(Terminal) -> quoted_atom(Terminal);
                          true -> Terminal
                      end,
     St20 = fwrite(St10,
@@ -2341,11 +2341,13 @@ delim(St, true) ->
 delim(St, false) ->
     fwrite(St, <<";\n">>, []).
 
-quoted_atom(#yecc{encoding = latin1}, Atom) when is_atom(Atom) ->
-    io_lib:write_atom_as_latin1(Atom);
-quoted_atom(_St, Atomic) ->
-    io_lib:write(Atomic).
-    
+%% Always quote atoms to ensure compatibility with future reserved words.
+quoted_atom(Atom) when is_atom(Atom) ->
+    case lists:flatten(io_lib:write_atom_as_latin1(Atom)) of
+        "'" ++ _ = Quoted -> Quoted;
+        NotQuoted -> ["'", NotQuoted, "'"]
+    end.
+
 output_inlined(St, UserCodeActions, Infile) ->
     foldl(fun(#user_code{funname = InlinedFunctionName, 
                          action = Action}, St_0) ->
@@ -2407,13 +2409,23 @@ output_nowarn(St, Function, Suffix, Arity) ->
 inlined_function_name(St, State, Terminal) ->
     End = case Terminal of
               "Cat" -> [];
-              _ -> [quoted_atom(St, Terminal)]
+              _ -> [safe_atom_chars(St, Terminal)]
           end,
     list_to_atom(concat([yeccpars2_, State, '_'] ++ End)).
 
 -compile({nowarn_unused_function,function_name/3}).
 function_name(St, Name, Suf) ->
-    list_to_atom(concat([Name, '_'] ++ [quoted_atom(St, Suf)])).
+    list_to_atom(concat([Name, '_', safe_atom_chars(St, Suf)])).
+
+safe_atom_chars(St, Atom) when is_atom(Atom) ->
+    case St of
+        #yecc{encoding = latin1} ->
+            io_lib:write_atom_as_latin1(Atom);
+        #yecc{} ->
+            atom_to_list(Atom)
+    end;
+safe_atom_chars(_St, Atomic) ->
+    io_lib:write(Atomic).
 
 rule(RulePointer, St) ->
     #rule{n = N, location = Location, symbols = Symbols} =
-- 
2.31.1

openSUSE Build Service is sponsored by