diff --git a/infer/tests/codetoanalyze/erlang/nonmatch/issues.exp b/infer/tests/codetoanalyze/erlang/nonmatch/issues.exp index b44bc2b53..19e5ce315 100644 --- a/infer/tests/codetoanalyze/erlang/nonmatch/issues.exp +++ b/infer/tests/codetoanalyze/erlang/nonmatch/issues.exp @@ -1,20 +1,21 @@ -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, case_simple/1, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here] -codetoanalyze/erlang/nonmatch/src/nonmatch.erl, case_test_simple3_Bad/0, -14, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `case_simple/1`,no pattern match here] -codetoanalyze/erlang/nonmatch/src/nonmatch.erl, case_test_tail3_Bad/0, -15, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `tail_with_case/1`,no pattern match here] -codetoanalyze/erlang/nonmatch/src/nonmatch.erl, fp_list_match_test_secondnil1_Ok/0, -17, 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, fp_list_match_test_secondnil2_Ok/0, -20, 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, 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, -38, 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_empty2_Bad/0, -12, 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_empty3_Bad/0, -14, 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_secondnil3_Bad/0, -22, 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, list_match_test_tail3_Bad/0, -8, 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_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, -42, 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, 32, 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] -codetoanalyze/erlang/nonmatch/src/nonmatch.erl, tail_with_case/1, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here] +codetoanalyze/erlang/nonmatch/src/case_expression.erl, case_simple/1, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here] +codetoanalyze/erlang/nonmatch/src/case_expression.erl, case_test_simple3_Bad/0, -14, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `case_simple/1`,no pattern match here] +codetoanalyze/erlang/nonmatch/src/case_expression.erl, case_test_tail3_Bad/0, -15, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `tail_with_case/1`,no pattern match here] +codetoanalyze/erlang/nonmatch/src/case_expression.erl, tail_with_case/1, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here] +codetoanalyze/erlang/nonmatch/src/function.erl, assert_empty/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here] +codetoanalyze/erlang/nonmatch/src/function.erl, assert_second_is_nil/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here] +codetoanalyze/erlang/nonmatch/src/function.erl, fp_list_match_test_secondnil1_Ok/0, -17, 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/function.erl, fp_list_match_test_secondnil2_Ok/0, -20, 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/function.erl, list_match_test_empty2_Bad/0, -12, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `assert_empty/1`,no pattern match here] +codetoanalyze/erlang/nonmatch/src/function.erl, list_match_test_empty3_Bad/0, -14, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `assert_empty/1`,no pattern match here] +codetoanalyze/erlang/nonmatch/src/function.erl, list_match_test_secondnil3_Bad/0, -22, 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/function.erl, list_match_test_tail3_Bad/0, -8, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `tail/1`,no pattern match here] +codetoanalyze/erlang/nonmatch/src/function.erl, tail/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here] +codetoanalyze/erlang/nonmatch/src/match.erl, fp_match_test_c_Ok/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here] +codetoanalyze/erlang/nonmatch/src/match.erl, fp_match_test_d_Ok/0, -13, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `tail/1`,no pattern match here] +codetoanalyze/erlang/nonmatch/src/match.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/match.erl, match_test_b_Bad/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here] +codetoanalyze/erlang/nonmatch/src/match.erl, match_test_e_Bad/0, -17, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [calling context starts here,in call to `tail/1`,no pattern match here] +codetoanalyze/erlang/nonmatch/src/match.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/match.erl, only_accepts_one/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here] +codetoanalyze/erlang/nonmatch/src/match.erl, tail/1, 0, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [*** LATENT ***,no pattern match here] diff --git a/infer/tests/codetoanalyze/erlang/nonmatch/src/case_expression.erl b/infer/tests/codetoanalyze/erlang/nonmatch/src/case_expression.erl new file mode 100644 index 000000000..7dd54d782 --- /dev/null +++ b/infer/tests/codetoanalyze/erlang/nonmatch/src/case_expression.erl @@ -0,0 +1,40 @@ +% Copyright (c) Facebook, Inc. and its affiliates. +% +% This source code is licensed under the MIT license found in the +% LICENSE file in the root directory of this source tree. + +-module(case_expression). + +-export([ + case_test_simple1_Ok/0, + case_test_simple2_Ok/0, + case_test_simple3_Bad/0, + case_test_tail1_Ok/0, + case_test_tail2_Ok/0, + case_test_tail3_Bad/0 +]). + +case_simple(X) -> + case X of + 0 -> zero; + 1 -> one + end. + +tail_with_case(X) -> + case X of + [_|T] -> T + end. + +case_test_simple1_Ok() -> + case_simple(0). +case_test_simple2_Ok() -> + case_simple(1). +case_test_simple3_Bad() -> + case_simple(2). + +case_test_tail1_Ok() -> + tail_with_case([1, 2]). +case_test_tail2_Ok() -> + tail_with_case([1]). +case_test_tail3_Bad() -> + tail_with_case([]). diff --git a/infer/tests/codetoanalyze/erlang/nonmatch/src/function.erl b/infer/tests/codetoanalyze/erlang/nonmatch/src/function.erl new file mode 100644 index 000000000..515367cd0 --- /dev/null +++ b/infer/tests/codetoanalyze/erlang/nonmatch/src/function.erl @@ -0,0 +1,45 @@ +% Copyright (c) Facebook, Inc. and its affiliates. +% +% This source code is licensed under the MIT license found in the +% LICENSE file in the root directory of this source tree. + +-module(function). + +-export([ + list_match_test_tail1_Ok/0, + list_match_test_tail2_Ok/0, + list_match_test_tail3_Bad/0, + list_match_test_empty1_Ok/0, + list_match_test_empty2_Bad/0, + list_match_test_empty3_Bad/0, + fp_list_match_test_secondnil1_Ok/0, + fp_list_match_test_secondnil2_Ok/0, + list_match_test_secondnil3_Bad/0 +]). + +tail([_ | Xs]) -> Xs. +assert_empty([]) -> ok. +assert_second_is_nil([_, [] | _]) -> ok. + +list_match_test_tail1_Ok() -> + tail([1, 2]). +list_match_test_tail2_Ok() -> + tail([1]). +list_match_test_tail3_Bad() -> + tail([]). + +list_match_test_empty1_Ok() -> + assert_empty([]). +list_match_test_empty2_Bad() -> + assert_empty([1]). +list_match_test_empty3_Bad() -> + assert_empty([1, 2]). + +% FP (T94492137) +fp_list_match_test_secondnil1_Ok() -> + assert_second_is_nil([1, [], 2]). +% FP (T94492137) +fp_list_match_test_secondnil2_Ok() -> + assert_second_is_nil([1, []]). +list_match_test_secondnil3_Bad() -> + assert_second_is_nil([1, [2], 3]). diff --git a/infer/tests/codetoanalyze/erlang/nonmatch/src/match.erl b/infer/tests/codetoanalyze/erlang/nonmatch/src/match.erl new file mode 100644 index 000000000..05d6c40f2 --- /dev/null +++ b/infer/tests/codetoanalyze/erlang/nonmatch/src/match.erl @@ -0,0 +1,52 @@ +% Copyright (c) Facebook, Inc. and its affiliates. +% +% This source code is licensed under the MIT license found in the +% LICENSE file in the root directory of this source tree. + +-module(match). + +-export([ + 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. + +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. diff --git a/infer/tests/codetoanalyze/erlang/nonmatch/src/nonmatch.erl b/infer/tests/codetoanalyze/erlang/nonmatch/src/nonmatch.erl deleted file mode 100644 index 98f3b82c0..000000000 --- a/infer/tests/codetoanalyze/erlang/nonmatch/src/nonmatch.erl +++ /dev/null @@ -1,117 +0,0 @@ -% Copyright (c) Facebook, Inc. and its affiliates. -% -% This source code is licensed under the MIT license found in the -% LICENSE file in the root directory of this source tree. - --module(nonmatch). - --export([ - list_match_test_tail1_Ok/0, - list_match_test_tail2_Ok/0, - list_match_test_tail3_Bad/0, - list_match_test_empty1_Ok/0, - list_match_test_empty2_Bad/0, - list_match_test_empty3_Bad/0, - fp_list_match_test_secondnil1_Ok/0, - fp_list_match_test_secondnil2_Ok/0, - list_match_test_secondnil3_Bad/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, - case_test_simple1_Ok/0, - case_test_simple2_Ok/0, - case_test_simple3_Bad/0, - case_test_tail1_Ok/0, - case_test_tail2_Ok/0, - case_test_tail3_Bad/0 -]). - -tail([_ | Xs]) -> Xs. -assert_empty([]) -> ok. -assert_second_is_nil([_, [] | _]) -> ok. - -list_match_test_tail1_Ok() -> - tail([1, 2]). -list_match_test_tail2_Ok() -> - tail([1]). -list_match_test_tail3_Bad() -> - tail([]). - -list_match_test_empty1_Ok() -> - assert_empty([]). -list_match_test_empty2_Bad() -> - assert_empty([1]). -list_match_test_empty3_Bad() -> - assert_empty([1, 2]). - -% FP (T94492137) -fp_list_match_test_secondnil1_Ok() -> - assert_second_is_nil([1, [], 2]). -% FP (T94492137) -fp_list_match_test_secondnil2_Ok() -> - assert_second_is_nil([1, []]). -list_match_test_secondnil3_Bad() -> - 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). - -case_simple(X) -> - case X of - 0 -> zero; - 1 -> one - end. - -tail_with_case(X) -> - case X of - [_|T] -> T - end. - -case_test_simple1_Ok() -> - case_simple(0). -case_test_simple2_Ok() -> - case_simple(1). -case_test_simple3_Bad() -> - case_simple(2). - -case_test_tail1_Ok() -> - tail_with_case([1, 2]). -case_test_tail2_Ok() -> - tail_with_case([1]). -case_test_tail3_Bad() -> - tail_with_case([]). - -%% internal -%% These functions are used to fool the compiler, which would warn if these were inlined. - -only_accepts_one(1) -> ok. -two() -> 2.