[erl-frontend] Translate expression Match

Summary: Translates "PATTERN = EXPRESSION".

Differential Revision: D29540785

fbshipit-source-id: f17f0938b
master
Radu Grigore 3 years ago committed by Facebook GitHub Bot
parent 2ecfa422ac
commit 6788fdef7e

@ -422,6 +422,13 @@ let rec translate_expression env {Ast.line; simple_expression} =
| Literal (String s) ->
let e = Exp.Const (Cstr s) in
Block.make_load env ret_var e any
| Match {pattern; body} ->
let body_block = translate_expression {env with result= Present (Exp.Var ret_var)} body in
let pattern_block = translate_pattern env ret_var pattern in
let crash_node = Node.make_pattern_fail env in
pattern_block.exit_failure |~~> [crash_node] ;
let pattern_block = {pattern_block with exit_failure= crash_node} in
Block.all env [body_block; pattern_block]
| Nil ->
let fun_exp = Exp.Const (Cfun BuiltinDecl.__erlang_make_nil) in
let instruction = Sil.Call ((ret_var, any), fun_exp, [], env.location, CallFlags.default) in

@ -1,6 +1,13 @@
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, assert_empty/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, assert_second_is_nil/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, fp_match_test_c_Ok/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, fp_match_test_d_Ok/0, -31, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `tail/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, list_match_test_a/0, -4, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `tail/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, list_match_test_b/0, -8, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `assert_empty/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, list_match_test_c/0, -12, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `assert_second_is_nil/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, match_test_b_Bad/0, 1, CONSTANT_ADDRESS_DEREFERENCE, no_bucket, WARNING, [in call to `two/0`,is the constant 2,assigned,returned,return from call to `two/0`,invalid access occurs here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, match_test_b_Bad/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, match_test_e_Bad/0, -35, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `tail/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, match_test_g_Bad/0, 7, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `only_accepts_one/1`,no pattern match here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, only_accepts_one/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]
codetoanalyze/erlang/nonmatch/src/nonmatch.erl, tail/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here]

@ -5,7 +5,18 @@
-module(nonmatch).
-export([list_match_test_a/0, list_match_test_b/0, list_match_test_c/0]).
-export([
list_match_test_a/0,
list_match_test_b/0,
list_match_test_c/0,
match_test_a_Ok/0,
match_test_b_Bad/0,
fp_match_test_c_Ok/0,
fp_match_test_d_Ok/0,
match_test_e_Bad/0,
match_test_f_Ok/0,
match_test_g_Bad/0
]).
tail([_ | Xs]) -> Xs.
assert_empty([]) -> ok.
@ -26,3 +37,37 @@ list_match_test_c() ->
assert_second_is_nil([1, [], 2]),
assert_second_is_nil([1, []]),
assert_second_is_nil([1, [2], 3]).
match_test_a_Ok() ->
_X = two().
match_test_b_Bad() ->
[_ | _] = two().
% FP (T94492137)
fp_match_test_c_Ok() ->
[_X, _Y] = [1, 2].
% FP (T94492137)
fp_match_test_d_Ok() ->
[_ | Xs] = [1, 2],
tail(Xs).
match_test_e_Bad() ->
[_ | Xs] = [1],
tail(Xs).
match_test_f_Ok() ->
X = (Y = 1),
only_accepts_one(X),
only_accepts_one(Y).
match_test_g_Bad() ->
X = 2,
only_accepts_one(X).
%% internal
%% These functions are used to fool the compiler, which would warn if these were inlined.
only_accepts_one(1) -> ok.
two() -> 2.

@ -1,6 +1,7 @@
codetoanalyze/erlang/topl/src/topl_taint.erl, fp_test_f_Bad/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]
codetoanalyze/erlang/topl/src/topl_taint.erl, fp_test_g_Ok/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]
codetoanalyze/erlang/topl/src/topl_taint.erl, test_a_Bad/0, 0, TOPL_ERROR, no_bucket, ERROR, [call to source/0,call to sink/1]
codetoanalyze/erlang/topl/src/topl_taint.erl, test_c_Bad/0, 0, TOPL_ERROR, no_bucket, ERROR, [call to source/0,call to sink/1]
codetoanalyze/erlang/topl/src/topl_taint.erl, test_d_Bad/0, 0, TOPL_ERROR, no_bucket, ERROR, [call to source/0,call to call_sink_indirectly/1,call to call_sink/1,call to sink/1]
codetoanalyze/erlang/topl/src/topl_taint.erl, test_h_Bad/0, 0, TOPL_ERROR, no_bucket, ERROR, [call to dirty_if_argument_nil/1,call to source/0,call to sink/1]
codetoanalyze/erlang/topl/src/topl_taint.erl, test_j_Bad/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]

@ -8,7 +8,7 @@
-export([
test_a_Bad/0,
test_b_Ok/0,
fn_test_c_Bad/0,
test_c_Bad/0,
test_d_Bad/0,
test_e_Ok/0,
fp_test_f_Bad/0,
@ -24,8 +24,7 @@ test_a_Bad() ->
test_b_Ok() ->
sink(1).
% FN because match not yet translated
fn_test_c_Bad() ->
test_c_Bad() ->
X = source(),
sink(X).

Loading…
Cancel
Save