From 2fbcd3b38d0dd6224fd3e0017245bb5d47cdfe66 Mon Sep 17 00:00:00 2001 From: Akos Hajdu Date: Fri, 30 Jul 2021 06:08:19 -0700 Subject: [PATCH] [erl-frontend] Support bitwise binary operators Summary: Add support for binary bitwise operators (and, or, xor, shift left, shift right). Reviewed By: mmarescotti Differential Revision: D29967773 fbshipit-source-id: 60dd8c337 --- infer/src/erlang/ErlangTranslator.ml | 10 ++ .../codetoanalyze/erlang/features/issues.exp | 10 ++ .../erlang/features/src/bitwise.erl | 156 ++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 infer/tests/codetoanalyze/erlang/features/src/bitwise.erl diff --git a/infer/src/erlang/ErlangTranslator.ml b/infer/src/erlang/ErlangTranslator.ml index 00f44b28e..4edefab7a 100644 --- a/infer/src/erlang/ErlangTranslator.ml +++ b/infer/src/erlang/ErlangTranslator.ml @@ -419,6 +419,16 @@ and translate_expression env {Ast.line; simple_expression} = make_simple_eager Ge | AtMost -> make_simple_eager Le + | BAnd -> + make_simple_eager BAnd + | BOr -> + make_simple_eager BOr + | Bsl -> + make_simple_eager Shiftlt + | Bsr -> + make_simple_eager Shiftrt + | BXor -> + make_simple_eager BXor (* TODO: proper modeling of equal vs exactly equal T95767672 *) | Equal | ExactlyEqual -> make_simple_eager Eq diff --git a/infer/tests/codetoanalyze/erlang/features/issues.exp b/infer/tests/codetoanalyze/erlang/features/issues.exp index c2af04349..4caf0040b 100644 --- a/infer/tests/codetoanalyze/erlang/features/issues.exp +++ b/infer/tests/codetoanalyze/erlang/features/issues.exp @@ -11,6 +11,16 @@ codetoanalyze/erlang/features/src/arithmetic.erl, test_sub2_Bad/0, -54, NO_MATCH codetoanalyze/erlang/features/src/arithmetic.erl, test_uminus1_Bad/0, -170, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] codetoanalyze/erlang/features/src/arithmetic.erl, test_uminus2_Bad/0, -183, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] codetoanalyze/erlang/features/src/arithmetic.erl, warn/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here] +codetoanalyze/erlang/features/src/bitwise.erl, test_band1_Bad/0, -9, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] +codetoanalyze/erlang/features/src/bitwise.erl, test_band2_Bad/0, -23, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] +codetoanalyze/erlang/features/src/bitwise.erl, test_bor1_Bad/0, -37, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] +codetoanalyze/erlang/features/src/bitwise.erl, test_bor2_Bad/0, -51, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] +codetoanalyze/erlang/features/src/bitwise.erl, test_bsl_Bad/0, -93, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] +codetoanalyze/erlang/features/src/bitwise.erl, test_bsr1_Bad/0, -107, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] +codetoanalyze/erlang/features/src/bitwise.erl, test_bsr2_Bad/0, -121, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] +codetoanalyze/erlang/features/src/bitwise.erl, test_bxor1_Bad/0, -65, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] +codetoanalyze/erlang/features/src/bitwise.erl, test_bxor2_Bad/0, -79, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] +codetoanalyze/erlang/features/src/bitwise.erl, warn/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here] codetoanalyze/erlang/features/src/block.erl, test_block_Bad/0, -15, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [calling context starts here,in call to `warn/1`,no matching function clause here] codetoanalyze/erlang/features/src/block.erl, warn/1, 0, NO_MATCHING_FUNCTION_CLAUSE, no_bucket, ERROR, [*** LATENT ***,no matching function clause here] codetoanalyze/erlang/features/src/comparison.erl, fp_test_equal_Ok2/0, 3, NO_TRUE_BRANCH_IN_IF, no_bucket, ERROR, [no true branch in if expression here] diff --git a/infer/tests/codetoanalyze/erlang/features/src/bitwise.erl b/infer/tests/codetoanalyze/erlang/features/src/bitwise.erl new file mode 100644 index 000000000..ab3b95aa5 --- /dev/null +++ b/infer/tests/codetoanalyze/erlang/features/src/bitwise.erl @@ -0,0 +1,156 @@ +% 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(bitwise). + +-export([ + test_band1_Ok/0, + test_band1_Bad/0, + test_band2_Ok/0, + test_band2_Bad/0, + test_bor1_Ok/0, + test_bor1_Bad/0, + test_bor2_Ok/0, + test_bor2_Bad/0, + test_bxor1_Ok/0, + test_bxor1_Bad/0, + test_bxor2_Ok/0, + test_bxor2_Bad/0, + test_bsl_Ok/0, + test_bsl_Bad/0, + test_bsr1_Ok/0, + test_bsr1_Bad/0, + test_bsr2_Ok/0, + test_bsr2_Bad/0 +]). + +% Call this method with warn(1) to trigger a warning to expect +warn(0) -> ok. + +test_band1_Ok() -> + X = 6, + Y = 3, + case X band Y of + 2 -> ok + end. + +test_band1_Bad() -> + X = 6, + Y = 3, + case X band Y of + 2 -> warn(1) + end. + +test_band2_Ok() -> + X = 2347, + Y = 8465, + case X band Y of + 257 -> ok + end. + +test_band2_Bad() -> + X = 2347, + Y = 8465, + case X band Y of + 257 -> warn(1) + end. + +test_bor1_Ok() -> + X = 6, + Y = 3, + case X bor Y of + 7 -> ok + end. + +test_bor1_Bad() -> + X = 6, + Y = 3, + case X bor Y of + 7 -> warn(1) + end. + +test_bor2_Ok() -> + X = 2347, + Y = 8465, + case X bor Y of + 10555 -> ok + end. + +test_bor2_Bad() -> + X = 2347, + Y = 8465, + case X bor Y of + 10555 -> warn(1) + end. + +test_bxor1_Ok() -> + X = 6, + Y = 3, + case X bxor Y of + 5 -> ok + end. + +test_bxor1_Bad() -> + X = 6, + Y = 3, + case X bxor Y of + 5 -> warn(1) + end. + +test_bxor2_Ok() -> + X = 2347, + Y = 8465, + case X bxor Y of + 10298 -> ok + end. + +test_bxor2_Bad() -> + X = 2347, + Y = 8465, + case X bxor Y of + 10298 -> warn(1) + end. + +test_bsl_Ok() -> + X = 1234, + Y = 3, + case X bsl Y of + 9872 -> ok + end. + +test_bsl_Bad() -> + X = 1234, + Y = 3, + case X bsl Y of + 9872 -> warn(1) + end. + +test_bsr1_Ok() -> + X = 9872, + Y = 3, + case X bsr Y of + 1234 -> ok + end. + +test_bsr1_Bad() -> + X = 9872, + Y = 3, + case X bsr Y of + 1234 -> warn(1) + end. + +test_bsr2_Ok() -> + X = 127, + Y = 7, + case X bsr Y of + 0 -> ok + end. + +test_bsr2_Bad() -> + X = 127, + Y = 7, + case X bsr Y of + 0 -> warn(1) + end.