File 0846-erl_lint-Fix-forbidden-segments-in-binary-generators.patch of Package erlang
From 5c220217cac088033af989bba102a0e6278d5a6a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Tue, 4 Feb 2020 06:53:25 +0100
Subject: [PATCH 05/13] erl_lint: Fix forbidden segments in binary generators
In the pattern for bit string generators, segments without size are
not allowed. Thus erl_lint correctly generates an error for the
following bit string generator:
foo(Bin) ->
[ [X] || <<X/bitstring>> <= Bin ].
However, if the pattern matched a literal erl_lint would not generate
an error:
bar(Bin) ->
[ 42 || <<42/bitstring>> <= Bin ].
For this particular example, the compiler would crash later. For
variations of this code, the compiler would not crash but would
generate nonsensical code.
---
lib/stdlib/src/erl_lint.erl | 2 +-
lib/stdlib/test/erl_lint_SUITE.erl | 22 +++++++++++++++++-----
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 4dd30019d9..8be07e6c45 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -3513,7 +3513,7 @@ handle_generator(P,E,Vt,Uvt,St0) ->
handle_bitstring_gen_pat({bin,_,Segments=[_|_]},St) ->
case lists:last(Segments) of
- {bin_element,Line,{var,_,_},default,Flags} when is_list(Flags) ->
+ {bin_element,Line,_,default,Flags} when is_list(Flags) ->
case member(binary, Flags) orelse member(bytes, Flags)
orelse member(bits, Flags) orelse member(bitstring, Flags) of
true ->
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index a5de033e89..0f27702f14 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -1298,6 +1298,10 @@ unsized_binary_in_bin_gen_pattern(Config) when is_list(Config) ->
<< <<X,Tail/bits>> || <<X,Tail/bits>> <= Bin >>;
t({bc,bitstring,Bin}) ->
<< <<X,Tail/bits>> || <<X,Tail/bitstring>> <= Bin >>;
+ t({bc,binary_lit,Bin}) ->
+ << <<X>> || <<X,1/binary>> <= Bin >>;
+ t({bc,bytes_lit,Bin}) ->
+ << <<X>> || <<X,a/bytes>> <= Bin >>;
t({lc,binary,Bin}) ->
[ {X,Tail} || <<X,Tail/binary>> <= Bin ];
t({lc,bytes,Bin}) ->
@@ -1305,17 +1309,25 @@ unsized_binary_in_bin_gen_pattern(Config) when is_list(Config) ->
t({lc,bits,Bin}) ->
[ {X,Tail} || <<X,Tail/bits>> <= Bin ];
t({lc,bitstring,Bin}) ->
- [ {X,Tail} || <<X,Tail/bitstring>> <= Bin ].">>,
+ [ {X,Tail} || <<X,Tail/bitstring>> <= Bin ];
+ t({lc,bits_lit,Bin}) ->
+ [ X || <<X,42/bits>> <= Bin ];
+ t({lc,bitstring_lit,Bin}) ->
+ [ X || <<X,b/bitstring>> <= Bin ].">>,
[],
{errors,
[{2,erl_lint,unsized_binary_in_bin_gen_pattern},
{4,erl_lint,unsized_binary_in_bin_gen_pattern},
{6,erl_lint,unsized_binary_in_bin_gen_pattern},
{8,erl_lint,unsized_binary_in_bin_gen_pattern},
- {10,erl_lint,unsized_binary_in_bin_gen_pattern},
- {12,erl_lint,unsized_binary_in_bin_gen_pattern},
- {14,erl_lint,unsized_binary_in_bin_gen_pattern},
- {16,erl_lint,unsized_binary_in_bin_gen_pattern}],
+ {10,erl_lint,unsized_binary_in_bin_gen_pattern},
+ {12,erl_lint,unsized_binary_in_bin_gen_pattern},
+ {14,erl_lint,unsized_binary_in_bin_gen_pattern},
+ {16,erl_lint,unsized_binary_in_bin_gen_pattern},
+ {18,erl_lint,unsized_binary_in_bin_gen_pattern},
+ {20,erl_lint,unsized_binary_in_bin_gen_pattern},
+ {22,erl_lint,unsized_binary_in_bin_gen_pattern},
+ {24,erl_lint,unsized_binary_in_bin_gen_pattern}],
[]}}],
[] = run(Config, Ts),
ok.
--
2.16.4